我在试着add an additional button into a toolbar in Internet Explorer。
我假设实现是直接的,目前正在使用以下代码:
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的调用堆栈,它如下所示:
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上使用。
发布于 2014-01-31 15:09:30
它失败了,因为您正在发送一条跨越进程边界的包含指针的消息。请注意,您传递了一个地址:
LRESULT insertButtonResult = SendMessage(hWndToolbar, TB_INSERTBUTTON, 0,
(LPARAM)&buttonToAdd);最后一个参数是进程地址空间中的地址。但是收件人是一个不同的进程,您传递的地址在其他进程的地址空间中没有任何意义。
一些消息,例如WM_SETTEXT,将由系统将其有效负载编组到另一个进程。但TB_INSERTBUTTON不属于这一类。TB_INSERTBUTTON的规则之一是,您传递的指针在拥有收件人窗口的进程中具有意义。
您可以通过使用VirtualAlloc、WriteProcessMemory等在另一个进程中分配和写入内存来解决这个问题。
请注意,这是一个有点困难的任务,以使正确。特别是,这两个过程是否具有相同的比特性非常重要。结构的布局在32位和64位之间不同。要确保发送正确的布局,最简单的方法是使用与目标进程相同的位数编译流程。
到目前为止,这样做的最简单的方法是在目标进程中。如果您要编写一个插件,那么您将不必处理任何这些问题,也可以使用官方支持的API进行扩展。
正如雷蒙德所说,你所尝试的是相当危险的,你最好听从他的建议。
https://stackoverflow.com/questions/21483214
复制相似问题