Link to home
Start Free TrialLog in
Avatar of ross_nolan
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(HOOKWINDOWCLASS, 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:access violation

-----------------------------------------------------
I should also mention that the function that this is in is part of an MFC application.

Thank you very much
Avatar of nietod
nietod

Why are you trying to create a window in this way in MFC?  That may not be the problem but it doesn't seem like a good idea.

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?
It is likely that the error is caused by somewhere else such as the WM_CREATE message handler.
Avatar of ross_nolan

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)

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?
ghInst is a handle to my application!!!

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.
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
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.
I did and it did not break at that point.

any ideas???

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


Post the code used to register the window class.
Also post the code that sets HOOKWINDOWCLASS and HOOKWINDOWNAME.
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
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?
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.
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"
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


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)HookMain,
        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(HOOKWINDOWCLASS, 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(HOOKWINDOWCLASS,HOOKWINDOWNAME);
      CWnd* c  = wnd->GetParent();
      CListBox* lb = (CListBox*)c->GetDlgItem(IDC_LIST_MSG);

    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)((PCOPYDATASTRUCT)lParam)->lpData)->wParam;
                msgT.lParam = ((PSPYMSGDATA)((PCOPYDATASTRUCT)lParam)->lpData)->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);
}


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


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:access violation

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

Its dying in the code

CWnd* wnd = CWnd::FindWindow(HOOKWINDOWCLASS,HOOKWINDOWNAME);
     CWnd* c  = wnd->GetParent();
     CListBox* lb = (CListBox*)c->GetDlgItem(IDC_LIST_MSG);

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.


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
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_GETMESSAGE,
                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
Avatar of nietod
nietod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
You took your time in claiming the points

Thanks
Sorry,  I was quit sure that my initial contribution was worth it.