c++ - Why is my TB_INSERTBUTTON message causing comctl32 to throw? -


i'm trying add additional button toolbar in internet explorer.

i assumed implementation straight forward, , using code:

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 ); 

when message sent, internet explorer crash 90% of time (10% of time, broken button on toolbar) following exception:

unhandled exception @ 0x000007fefb97ddfa (comctl32.dll) in iexplore.exe: 0xc000041d: unhandled exception encountered during user callback.

given results aren't consistent, assumed sort of memory layout issue. tried send tb_insertbuttona instead (my application defaults tb_insertbuttonw), has no effect on issue.

i tried both 32 , 64 builds of application, both have same result.

i took @ callstack of iexplore.exe, looks this:

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 ... 

i found interesting, because i'm assuming method @ top copies data input structure internal structure , goes wrong. what's wrong input data structure?

the source code available on github at: https://github.com/oliversalzburg/ie-button

it failing because sending message contains pointer across process boundary. note fact pass address:

lresult insertbuttonresult = sendmessage(hwndtoolbar, tb_insertbutton, 0,      (lparam)&buttontoadd); 

that final parameter address in processes address space. recipient different process , address pass has no meaning in address space of other process.

some messages, instance wm_settext, have payloads marshalled other process system. tb_insertbutton not fall category. 1 of rules of tb_insertbutton pointer pass has meaning in process owns recipient window.

you can resolve using virtualalloc, writeprocessmemory, etc. allocate , write memory in other process.

be warned difficult task right. in particular matters whether or not 2 processes have same bitness. layout of struct differs between 32 , 64 bit. easiest way make sure send right layout compile process same bitness target process.

by far easiest way inside target process. if write plugin not have deal of these issues , able use officially supported apis extension.

as raymond says, attempting rather dangerous , heed advice.


Comments

Popular posts from this blog

html - Sizing a high-res image (~8MB) to display entirely in a small div (circular, diameter 100px) -

java - IntelliJ - No such instance method -

identifier - Is it possible for an html5 document to have two ids? -