首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我的TB_INSERTBUTTON消息导致comctl32抛出?

为什么我的TB_INSERTBUTTON消息导致comctl32抛出?
EN

Stack Overflow用户
提问于 2014-01-31 15:05:29
回答 1查看 570关注 0票数 10

我在试着add an additional button into a toolbar in Internet Explorer

我假设实现是直接的,目前正在使用以下代码:

代码语言:javascript
复制
TBBUTTON buttonToAdd;
ZeroMemory( &buttonToAdd, sizeof( TBBUTTON ) );
buttonToAdd.iBitmap = 1;
buttonToAdd.idCommand = 1;
buttonToAdd.fsState = TBSTATE_ENABLED;
buttonToAdd.fsStyle = BTNS_BUTTON|BTNS_AUTOSIZE;

LRESULT insertButtonResult = SendMessage( hWndToolbar, TB_INSERTBUTTON, 0, (LPARAM)&buttonToAdd );

当消息被发送时,Internet将崩溃90%的时间(10%的时间,我在工具栏上得到一个有点坏的按钮),但有以下例外:

Unhandled exception at 0x000007FEFB97DDFA (comctl32.dll) in iexplore.exe: 0xC000041D: An unhandled exception was encountered during a user callback.

考虑到结果不一致,我假设了某种内存布局问题。因此,我尝试发送TB_INSERTBUTTONA (我的应用程序默认为TB_INSERTBUTTONW),但这对问题没有影响。

我还尝试了我的应用程序的32和64构建,两者都有相同的结果。

我查看了iexplore.exe的调用堆栈,它如下所示:

代码语言:javascript
复制
comctl32.dll!CToolbar::TBInputStruct(struct _TBBUTTONDATA *,struct _TBBUTTON const *)   Unknown
comctl32.dll!CToolbar::TBInsertButtons(unsigned int,unsigned int,struct _TBBUTTON *,int)    Unknown
comctl32.dll!CToolbar::ToolbarWndProc(struct HWND__ *,unsigned int,unsigned __int64,__int64)    Unknown
comctl32.dll!CToolbar::s_ToolbarWndProc(struct HWND__ *,unsigned int,unsigned __int64,__int64)  Unknown
user32.dll!UserCallWinProcCheckWow()   Unknown
user32.dll!DispatchClientMessage() Unknown
user32.dll!__fnDWORD() Unknown
ntdll.dll!KiUserCallbackDispatcherContinue()   Unknown
user32.dll!NtUserPeekMessage() Unknown
user32.dll!PeekMessageW()  Unknown
...

我发现这有点有趣,因为我假设顶部的方法将数据从我的输入结构复制到内部结构中,有些地方出错了。但是我的输入数据结构有什么问题呢?

源代码本身可在GitHub at:https://github.com/oliversalzburg/ie-button上使用。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-31 15:09:30

它失败了,因为您正在发送一条跨越进程边界的包含指针的消息。请注意,您传递了一个地址:

代码语言:javascript
复制
LRESULT insertButtonResult = SendMessage(hWndToolbar, TB_INSERTBUTTON, 0, 
    (LPARAM)&buttonToAdd);

最后一个参数是进程地址空间中的地址。但是收件人是一个不同的进程,您传递的地址在其他进程的地址空间中没有任何意义。

一些消息,例如WM_SETTEXT,将由系统将其有效负载编组到另一个进程。但TB_INSERTBUTTON不属于这一类。TB_INSERTBUTTON的规则之一是,您传递的指针在拥有收件人窗口的进程中具有意义。

您可以通过使用VirtualAllocWriteProcessMemory等在另一个进程中分配和写入内存来解决这个问题。

请注意,这是一个有点困难的任务,以使正确。特别是,这两个过程是否具有相同的比特性非常重要。结构的布局在32位和64位之间不同。要确保发送正确的布局,最简单的方法是使用与目标进程相同的位数编译流程。

到目前为止,这样做的最简单的方法是在目标进程中。如果您要编写一个插件,那么您将不必处理任何这些问题,也可以使用官方支持的API进行扩展。

正如雷蒙德所说,你所尝试的是相当危险的,你最好听从他的建议。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21483214

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档