ross_nolan
asked on
CreateWindow function problem
I have the following code in a program, where I want to create an invisible window and HOOKWINDOWCLASS & HOOKWINDOWNAME are predefined constants:
ghwndSpyHook = CreateWindow(HOOKWINDOWCLA SS, HOOKWINDOWNAME,
WS_OVERLAPPEDWINDOW,
0, 0, 0, 0,
(HWND) NULL, /* no parent */
(HMENU) NULL, /* use class menu */
(HINSTANCE) ghInst, /* handle to window instance */
(LPSTR) NULL /* no params to pass on */
);
This code causes the following run time error:
Unhanded Exception in Messages.exe (MFC42D.DLL):0xC00000005:a ccess violation
-------------------------- ---------- ---------- -------
I should also mention that the function that this is in is part of an MFC application.
Thank you very much
ghwndSpyHook = CreateWindow(HOOKWINDOWCLA
WS_OVERLAPPEDWINDOW,
0, 0, 0, 0,
(HWND) NULL, /* no parent */
(HMENU) NULL, /* use class menu */
(HINSTANCE) ghInst, /* handle to window instance */
(LPSTR) NULL /* no params to pass on */
);
This code causes the following run time error:
Unhanded Exception in Messages.exe (MFC42D.DLL):0xC00000005:a
--------------------------
I should also mention that the function that this is in is part of an MFC application.
Thank you very much
It is likely that the error is caused by somewhere else such as the WM_CREATE message handler.
ASKER
HOOKWINDOWCLASS is something that I have registered myself.
THe idea behind my project is to watch the Message Queue. I have a DLL already which does this but I need a hidden window for it to communicate with. It is this window that I am trying to create.
ghInst is declared as a HANDLE, that is why I cast it to (HINSTANCE)
THe idea behind my project is to watch the Message Queue. I have a DLL already which does this but I need a hidden window for it to communicate with. It is this window that I am trying to create.
ghInst is declared as a HANDLE, that is why I cast it to (HINSTANCE)
is ghinst a handle to your application? It must be. And if so, then why isn't an HINSTANCE?
Is your window procedure being called?
Is your window procedure being called?
ASKER
ghInst is a handle to my application!!!
I am not used to programming in Win32, so what is my window procedure again???
thanks
I am not used to programming in Win32, so what is my window procedure again???
thanks
When you register the window, you had to specify a procedure that would handle all the messages for that window. This is the procedure where you will do all the "custom" processing for that window. (This is very important.) You must have this procedure. If not add it, If so, check to see that it is being called. You should be getting at least the WM_CREATE and WM_NCCREATE messages.
ASKER
Yes I know the procedure that you are talking about.
It is properly specified along with the ClassName in the registry.
THe procedure also has the WM_CREATE message, but I am not sure that it is being called.
Any ideas??
Thanks
It is properly specified along with the ClassName in the registry.
THe procedure also has the WM_CREATE message, but I am not sure that it is being called.
Any ideas??
Thanks
Find out it if it is being called. That cuts the search for problems in half.
Place a breakpoint at the start of the procedure.
Place a breakpoint at the start of the procedure.
ASKER
I did and it did not break at that point.
any ideas???
chears
any ideas???
chears
ASKER
Here is a copy of my registry entry:
WNDCLASS wc;
//
// Register a class for the hook stuff to forward its messages to.
//
wc.hCursor = NULL; // this window never shown, so no
wc.hIcon = NULL; // cursor or icon are necessary
wc.lpszMenuName = NULL;
wc.lpszClassName = HOOKWINDOWCLASS;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.hInstance = (HINSTANCE)ghInst;
wc.style = 0;
wc.lpfnWndProc = HookWndProc;
wc.cbWndExtra = sizeof(HWND) + sizeof(HWND);
wc.cbClsExtra = 0;
WNDCLASS wc;
//
// Register a class for the hook stuff to forward its messages to.
//
wc.hCursor = NULL; // this window never shown, so no
wc.hIcon = NULL; // cursor or icon are necessary
wc.lpszMenuName = NULL;
wc.lpszClassName = HOOKWINDOWCLASS;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.hInstance = (HINSTANCE)ghInst;
wc.style = 0;
wc.lpfnWndProc = HookWndProc;
wc.cbWndExtra = sizeof(HWND) + sizeof(HWND);
wc.cbClsExtra = 0;
Post the code used to register the window class.
Also post the code that sets HOOKWINDOWCLASS and HOOKWINDOWNAME.
Also post the code that sets HOOKWINDOWCLASS and HOOKWINDOWNAME.
ASKER
This is the code that sets HOOKWINDOWCLASS and HOOKWINDOWNAME:
#define HOOKWINDOWNAME "SpyHookWindow"
#define HOOKWINDOWCLASS "SpyHookClass"
THe code used to register the window class is above
cheers
#define HOOKWINDOWNAME "SpyHookWindow"
#define HOOKWINDOWCLASS "SpyHookClass"
THe code used to register the window class is above
cheers
You must be psychic. Are you using that in the RegisterClass Function? Does that work correctly (return a non-zero value)?
How are those constants defined?
How is ghinst being set?
can you post the window procedure?
How are those constants defined?
How is ghinst being set?
can you post the window procedure?
Are HOOKWINDOWNAME and HOOKWINDOWCLASS being passed by reference? I'm not a C programmer, but I thought C passed everything by value unless otherwise specified.
ASKER
HOOKWINDOWNAME and HOOKWINDOWCLASS are globally defined constants so they don't need to be passed by value or reference
#define HOOKWINDOWNAME "SpyHookWindow"
#define HOOKWINDOWCLASS "SpyHookClass"
#define HOOKWINDOWNAME "SpyHookWindow"
#define HOOKWINDOWCLASS "SpyHookClass"
What about ghinst, and the window procedure?
To put an end to all this guessing, why don't you post a symbolic stack trace showing exactly what happened before the crash? That way, we can see some of the flow of control just before you crashed, exactly where you did crash, and therefore have a more direct route towards understanding your problem.
Remember to tell us which version of MFC you're using; otherwise, the stack trace isn't quite so useful.
B ekiM
Remember to tell us which version of MFC you're using; otherwise, the stack trace isn't quite so useful.
B ekiM
ASKER
I am using Visual C++ version 6.
OK here is the 3 main functions to do with this invisible window:
THese are the global variables that I am using:
// Spy memebers
HWND ghwndSpyApp;
HANDLE ghHookThread;
HWND ghwndSpyHook;
HWND ghwndSpyingOn;
BOOL gfSpyOn;
BOOL gfSpyAll;
HANDLE ghInst;
The first procedure is called when the main application is started.
It creates a thread of the second function -
bool CreateHookThread(VOID)
{
WNDCLASS wc;
DWORD Id;
//
// Register a class for the hook stuff to forward its messages to.
//
wc.hCursor = NULL; // this window never shown, so no
wc.hIcon = NULL; // cursor or icon are necessary
wc.lpszMenuName = NULL;
wc.lpszClassName = HOOKWINDOWCLASS;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.hInstance = (HINSTANCE)ghInst;
wc.style = 0;
wc.lpfnWndProc = HookWndProc;
wc.cbWndExtra = sizeof(HWND) + sizeof(HWND);
wc.cbClsExtra = 0;
if (!RegisterClass(&wc))
return FALSE;
//
// Now create another thread to handle the new queue
//
if (!(ghHookThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Ho okMain,
0L, STANDARD_RIGHTS_REQUIRED, &Id)))
return FALSE;
return TRUE;
}
This second function is where the hidden window is set up:
DWORD HookMain(LPVOID lpv)
{
MSG msg;
//
// Create a hidden window for all to find, but not to see
//
ghwndSpyHook = CreateWindow(HOOKWINDOWCLA SS, HOOKWINDOWNAME,
WS_OVERLAPPEDWINDOW,
0, 0, 0, 0,
(HWND) NULL, /* no parent */
(HMENU) NULL, /* use class menu */
(HINSTANCE) ghInst, /* handle to window instance */
(LPSTR) NULL /* no params to pass on */
);
if (!ghwndSpyHook)
{
ExitThread(0);
}
SetWindowToSpyOn(HWND_ALL) ;
//
// Polling forwarded messages from hook's event queue
//
while (IsWindow(ghwndSpyHook) && GetMessage(&msg, ghwndSpyHook, 0, 0))
{
if (gfProcessHooks)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
ghwndSpyHook = NULL;
return 0;
}
THis function is to handle any messages from the DLL or the hidden application:
LRESULT CALLBACK HookWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
CWnd* wnd = CWnd::FindWindow(HOOKWINDO WCLASS,HOO KWINDOWNAM E);
CWnd* c = wnd->GetParent();
CListBox* lb = (CListBox*)c->GetDlgItem(I DC_LIST_MS G);
switch (msg)
{
//
// New message for Win32 - allows the application to pass data to another application.
//
case WM_COPYDATA:
{
MSG msgT;
msgT.hwnd = (HWND)wParam;
msgT.message = ((PCOPYDATASTRUCT)lParam)- >dwData;
msgT.wParam = ((PSPYMSGDATA)((PCOPYDATAS TRUCT)lPar am)->lpDat a)->wParam ;
msgT.lParam = ((PSPYMSGDATA)((PCOPYDATAS TRUCT)lPar am)->lpDat a)->lParam ;
//DbgPrintf("S Received Message hwnd:%8.8x msg:%d", msgT.hwnd, msgT.message);
//PrintMsg(&msgT);
//DbgPrintf("S Printed Message hwnd:%8.8x msg:%d", msgT.hwnd, msgT.message);
CString str((char*)msgT.message);
lb->AddString(str);
}
return TRUE;
case WM_CREATE:
//
// Initialize the second HWND in the window words to be the
// window handle of the spy app. This will be queried by
// the hook DLL.
//
SetWindowLong(hwnd, sizeof(HWND), (LONG)ghwndSpyApp);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_NCDESTROY:
gfProcessHooks = FALSE;
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
OK here is the 3 main functions to do with this invisible window:
THese are the global variables that I am using:
// Spy memebers
HWND ghwndSpyApp;
HANDLE ghHookThread;
HWND ghwndSpyHook;
HWND ghwndSpyingOn;
BOOL gfSpyOn;
BOOL gfSpyAll;
HANDLE ghInst;
The first procedure is called when the main application is started.
It creates a thread of the second function -
bool CreateHookThread(VOID)
{
WNDCLASS wc;
DWORD Id;
//
// Register a class for the hook stuff to forward its messages to.
//
wc.hCursor = NULL; // this window never shown, so no
wc.hIcon = NULL; // cursor or icon are necessary
wc.lpszMenuName = NULL;
wc.lpszClassName = HOOKWINDOWCLASS;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.hInstance = (HINSTANCE)ghInst;
wc.style = 0;
wc.lpfnWndProc = HookWndProc;
wc.cbWndExtra = sizeof(HWND) + sizeof(HWND);
wc.cbClsExtra = 0;
if (!RegisterClass(&wc))
return FALSE;
//
// Now create another thread to handle the new queue
//
if (!(ghHookThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Ho
0L, STANDARD_RIGHTS_REQUIRED, &Id)))
return FALSE;
return TRUE;
}
This second function is where the hidden window is set up:
DWORD HookMain(LPVOID lpv)
{
MSG msg;
//
// Create a hidden window for all to find, but not to see
//
ghwndSpyHook = CreateWindow(HOOKWINDOWCLA
WS_OVERLAPPEDWINDOW,
0, 0, 0, 0,
(HWND) NULL, /* no parent */
(HMENU) NULL, /* use class menu */
(HINSTANCE) ghInst, /* handle to window instance */
(LPSTR) NULL /* no params to pass on */
);
if (!ghwndSpyHook)
{
ExitThread(0);
}
SetWindowToSpyOn(HWND_ALL)
//
// Polling forwarded messages from hook's event queue
//
while (IsWindow(ghwndSpyHook) && GetMessage(&msg, ghwndSpyHook, 0, 0))
{
if (gfProcessHooks)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
ghwndSpyHook = NULL;
return 0;
}
THis function is to handle any messages from the DLL or the hidden application:
LRESULT CALLBACK HookWndProc(HWND hwnd, unsigned int msg, WPARAM wParam, LPARAM lParam)
{
CWnd* wnd = CWnd::FindWindow(HOOKWINDO
CWnd* c = wnd->GetParent();
CListBox* lb = (CListBox*)c->GetDlgItem(I
switch (msg)
{
//
// New message for Win32 - allows the application to pass data to another application.
//
case WM_COPYDATA:
{
MSG msgT;
msgT.hwnd = (HWND)wParam;
msgT.message = ((PCOPYDATASTRUCT)lParam)-
msgT.wParam = ((PSPYMSGDATA)((PCOPYDATAS
msgT.lParam = ((PSPYMSGDATA)((PCOPYDATAS
//DbgPrintf("S Received Message hwnd:%8.8x msg:%d", msgT.hwnd, msgT.message);
//PrintMsg(&msgT);
//DbgPrintf("S Printed Message hwnd:%8.8x msg:%d", msgT.hwnd, msgT.message);
CString str((char*)msgT.message);
lb->AddString(str);
}
return TRUE;
case WM_CREATE:
//
// Initialize the second HWND in the window words to be the
// window handle of the spy app. This will be queried by
// the hook DLL.
//
SetWindowLong(hwnd, sizeof(HWND), (LONG)ghwndSpyApp);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_NCDESTROY:
gfProcessHooks = FALSE;
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
To put an end to all this guessing, why don't you post a symbolic stack trace showing exactly what happened before the crash? That way, we can see some of the flow of control just before you crashed, exactly where you did crash, and therefore have a more direct route towards understanding your problem.
Remember to tell us which version of MFC you're using; otherwise, the stack trace isn't quite so useful.
B ekiM
Remember to tell us which version of MFC you're using; otherwise, the stack trace isn't quite so useful.
B ekiM
ASKER
Steping through the program the 'CreateHookThread' function is entered. Next the hookWindow is registered and then a thread is called for the 'HookMain' function. The 'CreateHookThread' function then exits successfully.
When the 'HookMain' function is entered it tries to create a window. It is when I am trying to step through this procedure that I get the following run time error:
Unhanded Exception in Messages.exe (MFC42D.DLL):0xC00000005:a ccess violation
I hope this helps!!!
When the 'HookMain' function is entered it tries to create a window. It is when I am trying to step through this procedure that I get the following run time error:
Unhanded Exception in Messages.exe (MFC42D.DLL):0xC00000005:a
I hope this helps!!!
What mike is saying is look at the stack trace at the time of the exception and list the functions at the top of the stack. That will give us an idea of the "area" in MFC in which it is dying which may provide a clue as to what you are doing that is killing it.
ASKER
I this what you are looking for:
CWnd::GetParent() line 265 + 13 bytes
HookWndProc(HWND__ * 0x00000db4, unsigned int 36, unsigned int 0, long 9960792) line 211 + 8 bytes
KERNEL32! bff73663()
KERNEL32! bff92894()
CWnd::GetParent() line 265 + 13 bytes
HookWndProc(HWND__ * 0x00000db4, unsigned int 36, unsigned int 0, long 9960792) line 211 + 8 bytes
KERNEL32! bff73663()
KERNEL32! bff92894()
Its dying in the code
CWnd* wnd = CWnd::FindWindow(HOOKWINDO WCLASS,HOO KWINDOWNAM E);
CWnd* c = wnd->GetParent();
CListBox* lb = (CListBox*)c->GetDlgItem(I DC_LIST_MS G);
in the middle line. I'm not sure how MFC's FindWindow functions, but I suspect the problem is that it isn't finding the window it is looking for. (What is weird is that you probably don't need that because I assume that is the window the function is called for, right?)
A temporary fix would be to move this code into the WM_COPYDATA code as that is the only place it is needed. However, I think you probably need to rethink this code. You ceartainly should consider error checking. You might also consider if it is the right approach.
CWnd* wnd = CWnd::FindWindow(HOOKWINDO
CWnd* c = wnd->GetParent();
CListBox* lb = (CListBox*)c->GetDlgItem(I
in the middle line. I'm not sure how MFC's FindWindow functions, but I suspect the problem is that it isn't finding the window it is looking for. (What is weird is that you probably don't need that because I assume that is the window the function is called for, right?)
A temporary fix would be to move this code into the WM_COPYDATA code as that is the only place it is needed. However, I think you probably need to rethink this code. You ceartainly should consider error checking. You might also consider if it is the right approach.
ASKER
YOU THE MAN (or woman if this is the case)
YOU THE MAN (or woman if this is the case)
YOU THE MAN (or woman if this is the case)
YOU THE MAN (or woman if this is the case)
THank you very much
I can now get on with my project.
Cheers
YOU THE MAN (or woman if this is the case)
YOU THE MAN (or woman if this is the case)
YOU THE MAN (or woman if this is the case)
THank you very much
I can now get on with my project.
Cheers
ASKER
Hi there
another question to be posed:
After loading the DLL which is used in conjunction with the above (large) code segment,
the following code freezes my computer:
if (!hhkGetMessage)
{
HOOKPROC hp = (HOOKPROC)GetProcAddress(( HINSTANCE) hmodHook, "SpyGetMsgProc");
if (!(hhkGetMessage = SetWindowsHookEx(WH_GETMES SAGE,
hp, (HINSTANCE)hmodHook, 0)))
{
DWORD err = GetLastError();
return FALSE;
}
}
THe only way to free up my computer is to CTL+ALT+DEL and kill the application and Visual C++.
At first I thought that it was not finding the function inside the DLL but it gets a valid address not far off the library address.
Any ideas???
Cheers
another question to be posed:
After loading the DLL which is used in conjunction with the above (large) code segment,
the following code freezes my computer:
if (!hhkGetMessage)
{
HOOKPROC hp = (HOOKPROC)GetProcAddress((
if (!(hhkGetMessage = SetWindowsHookEx(WH_GETMES
hp, (HINSTANCE)hmodHook, 0)))
{
DWORD err = GetLastError();
return FALSE;
}
}
THe only way to free up my computer is to CTL+ALT+DEL and kill the application and Visual C++.
At first I thought that it was not finding the function inside the DLL but it gets a valid address not far off the library address.
Any ideas???
Cheers
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
You took your time in claiming the points
Thanks
Thanks
Sorry, I was quit sure that my initial contribution was worth it.
Is HOOKWINDOWCLASS the name of a registered window class? One that you registered or a predefined One? (which one?)
Is ghInst the instance handle to your application? it should be, but if it is why do you need to cast it to (HINSTANCE)? That seems suspicious.
Do you have a window procedure for this class? Is it getting called?