SetwindowsHookEx, GetItem, Crash in ComCtl32.DLL
First off, I would like to thank ChainsaW, Steve, and Damit for their help
with this particular situation. However, I am still having problems...
For those who dont know, let me reiterate my problem:
I am writing an application that gets a CTabCtrl item. The CTabCtrl item
(TCITEM) resides in a different process different than my application. I
am using the CTabCtrl in Wordpad to test my application.
The code looks something like this:
void MyFunc(HWND hWnd, int id)
{
CTabCtrl* Tab = new CTabCtrl;
Tab->Attach(hWnd);
Tab->GetItem(id, NULL);
// The TCITEM normally passed is handled in the following
// DLL function (via the Hook processing), so I use NULL just
// to send the message so it will get intercepted
Tab->Detach();
delete Tab;
}
In my application, a hook is set using SetWindowsHookEx (as sugggested by
ChainsaW and in Jeffrey Richter's book 'Advanced Windows Programming').
This hooks a DLL I created that looks for the TCM_GETITEM message. The hook
is set in all threads (using a thread id of 0), and seems to set fine, as
my DLL function is called when a SendMessage occurs.
My DLL function looks like this
HWND hApp; // Set in a DLL SetHandle function
BOOL bBranch = FALSE; // Needed for branch to next hook
TCITEM gItem;
char gstr[255];
LRESULT WINAPI CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
{
CWPSTRUCT* Msg;
Msg = (CWPSTRUCT*)lParam;
if((nCode < 0) || bBranch)
{
return CallNextWindowsHookEx(nCode, wParam, lParam);
}
if(Msg->message == TCM_GETITEM)
{
gItem.mask = TCIF_TEXT;
gItem.pszText = gstr;
gItem.cchTextMax = 255;
int id = Msg->wParam;
bBranch = TRUE; // required so does CallWndProc does not process following
SendMessage)
if(SendMessage(gApp, TCM_GETITEM, id, &gItem);
{
// gItem.pszText still = "", should equal the name of the Tab.
printf("%s", gItem.pszText);
}
bBranch = FALSE;
return CallNextWindowsHook(nCode, wParam, lParam);
}
return CallNextWindowsHookEx(nCode, wParam, lParam);
}
Apologies for the long posting, but there is a lot of information here...
While I am in DEBUG step-through, Wordpad does not crash when I SendMessage
in CallWndProc. However, it does not return the name of the Tab Item as
expected, but only "" for the pszText member. In DEBUG execute, Wordpad
causes a page fault in ComCtl32.dll.
Now for the questions:
1. Thanks to the help of Steve, Damit, and ChainsaW, I now understand that
Windows32 processes do not share memory. My understanding is in order to
access another processes memory, you can inject a DLL into the other (remote)
process by using SetWindowsHookEx. Now the DLL can 'see' the memory in the
remote process. So, if you create a pointer or structure in the DLL, the
remote process can use information in that pointer or structure. Therefore,
if I create the TCITEM structure and char[255] in my DLL, those should be
available to the remote process, so it can put data in them and my DLL can
see that data. Am I correct in believing this?? Because I still get the
page fault when I do this.
2. As stated in number 1, a process cannot 'see' a data in another process.
However, when I SendMessage WM_GETTEXT with a pointer to a char[255], it
works just fine. In this case, there is a pointer in my process that the
other process can 'see' and use. This does not work with CTreeView messages
or CTabCtrl messages. However, both &TCITEM and &char[255] are just references
to memory locations. How come one works and the other doesn't??
3. And finally (thanks for your patience) is there another way to send a
message other than SendMessage or PostMessage, so I dont have to set the
bBranch flag in my code. The method must wait for the message to be processed.
ANY help or insight you can give is VERY MUCH appreciated. I have done a
lot of research on this problem, but to no avail, and this part is CRITICAL
to my application. I have seen other applications do it, but I can't get
mine to do it.
If you have any questions, let me know!!
-Johnny

