Thread: What's wrong with my Win32 Wrapper code?

  1. #1
    Registered User
    Join Date
    Feb 2005
    Posts
    4

    What's wrong with my Win32 Wrapper code?

    Please help me check my Win32 Wrapper code, it compiled right, and run with no error, but it exit immediately after running, I have look at my code many times but still don't know what's wrong with it. Here's my code:

    main.cpp
    Code:
    #include <windows.h>
    
    #include "Window.h"
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                        PSTR szCmdLine, int iCmdShow)
    {
        CWindow test(hInstance);
        test.RegisterWindow();
        test.Create();
    
        MSG msg;
    
        while(GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        return msg.wParam;
    }
    Window.cpp
    Code:
    #include "Window.h"
    
    LRESULT CALLBACK CWindow::staticWinMsgHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        CWindow* pWnd;
    
        if(uMsg == WM_NCCREATE)
        {
            SetWindowLong(hwnd, GWL_USERDATA, (long)((LPCREATESTRUCT(lParam))->lpCreateParams));
        }
    
        pWnd = (CWindow *)GetWindowLong(hwnd, GWL_USERDATA);
    
        if(pWnd)
            return pWnd->WinMsgHandler(hwnd, uMsg, wParam, lParam);
        else
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    
    LRESULT CALLBACK CWindow::WinMsgHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        switch(uMsg)
        {
            case WM_CREATE:
                MessageBox(NULL, "Create", "test", MB_OK);
                break;
            case WM_CLOSE:
                PostQuitMessage(0);
                break;
            default:
                return CWindow::WinMsgHandler(hwnd, uMsg, wParam, lParam);
        }
        return 0;
    }
    
    BOOL CWindow::RegisterWindow()
    {
        WNDCLASS wcx;
    
        wcx.style         = CS_HREDRAW | CS_VREDRAW;
        wcx.lpfnWndProc   = CWindow::staticWinMsgHandler;
        wcx.cbClsExtra    = 0;
        wcx.cbWndExtra    = 0;
        wcx.hInstance     = m_hInstance;
        wcx.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
        wcx.hCursor       = LoadCursor(NULL, IDC_ARROW);
        wcx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        wcx.lpszMenuName  = NULL;
        wcx.lpszClassName = "Window";
    
        return (RegisterClass(&wcx) != 0);
    }
    
    BOOL CWindow::Create()
    {
        m_hwnd = CreateWindow("Window", "Hello",
            WS_OVERLAPPEDWINDOW | WS_VISIBLE,
            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
            NULL, NULL, m_hInstance, (void *)this);
    
        return (m_hwnd != NULL);
    }
    Window.h
    Code:
    #ifndef Window_H_
    #define Window_H_
    
    #include <windows.h>
    
    // The class is based on the example taken from Code Project article:
    // "A Simple Win32 Window Wrapper Class" By Jason Henderson 
    
    class CWindow
    {
    protected:
        HINSTANCE m_hInstance;
        HWND m_hwnd;
        char szClassName[256];
        char szWindowTitle[256];
    
        virtual LRESULT CALLBACK WinMsgHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    
    public:
        CWindow(HINSTANCE hInst)
            : m_hInstance(hInst){};
        virtual BOOL RegisterWindow();
        virtual BOOL Create();
        static LRESULT CALLBACK staticWinMsgHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    };
    
    #endif
    I think that the

    Code:
        CWindow test(hInstance);
        test.RegisterWindow();
        test.Create();
    runs ok, the problem is in CWindow::staticWinMsgHandler, I think.

  2. #2
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Recursively calling your class member function window procedure (WinMsgHandler) by default is not a good idea; replace the default of the switch statment with a call to DefWindowProc instead:
    Code:
    LRESULT CALLBACK CWindow::WinMsgHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        switch(uMsg)
        {
            case WM_CREATE:
                MessageBox(NULL, "Create", "test", MB_OK);
                break;
            case WM_CLOSE:
                /*default system processing of WM_CLOSE involves a call to DestroyWindow
                  so if you intercept this message, do the same*/
                DestroyWindow(hwnd);
                PostQuitMessage(0);
                break;
            default:
                //return CWindow::WinMsgHandler(hwnd, uMsg, wParam, lParam);
                DefWindowProc(hwnd,uMsg,wParam,lParam);
        }
        return 0;
    }
    You might want to read up on GetMessage, too; there's a possibility of that function returning -1, a result which will break your code.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  3. #3
    Registered User
    Join Date
    Feb 2005
    Posts
    4
    Ken Fitlike, thanks for the tips.

    I haven't change the GetMessage() while loop, I find that CreateWindow() is the one that fails, m_hwnd returns 0! I replace "(void *)this" with "NULL", CreateWindow() works! why!? what's wrong?

    I checked my CWindow::RegisterWindow(), no problems there.

  4. #4
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Does the WM_CREATE message box ever come up?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  5. #5
    Registered User Dante Shamest's Avatar
    Join Date
    Apr 2003
    Posts
    970
    I find that CreateWindow() is the one that fails, m_hwnd returns 0! I replace "(void *)this" with "NULL", CreateWindow() works! why!? what's wrong?
    miica, did you do as Ken said?

    Did you replace the default of the switch statement with a call to DefWindowProc instead?

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Wouldn't that produce a stack overflow if he hadn't?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  7. #7
    Registered User Dante Shamest's Avatar
    Join Date
    Apr 2003
    Posts
    970
    I couldn't think of anything else.

    After modifying his code using Ken's suggestions, my version of his program runs properly.

  8. #8
    Registered User
    Join Date
    Feb 2005
    Posts
    4
    sorry, I spent a whole day cleaning up my disk so I can install a new big MSVC .Net, I thought the code does not compile because I am using MSVC 6.0, so I tried to compile it with .Net, unfortunately, the problems still isn't solved, CreateWindow() still fails and returns 0. I then tried in a yet another different compiler, Dev-C++ 4.9.8.0, the result still is the same.

    "Does the WM_CREATE message box ever come up?"
    no. I changed my code as Ken Fitlike suggested, this time the program run but it does no show, I can only see it in Windows Task Manager, the Processes tab, it is not in the Applications tab.

    "Did you replace the default of the switch statement with a call to DefWindowProc instead?"
    Is this just what I need to do? I did it, but the test.Create() still returns 0.

    "After modifying his code using Ken's suggestions, my version of his program runs properly."
    Dante Shamest, what compiler are you using? I wonder why mine doesn't works properly.

    This is my revised code:

    main.cpp
    Code:
    #include <windows.h>
    
    #include "Window.h"
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                        PSTR szCmdLine, int iCmdShow)
    {
        int returnvalue;
        CWindow test(hInstance);
        returnvalue = test.RegisterWindow();
        returnvalue = test.Create();
    
        // I checked the return value in debugging, found that
        // test.RegisterWindow() returns 1 while
        // test.Create() returns 0.
    
        MSG msg;
    
        while((returnvalue = GetMessage(&msg, NULL, 0, 0)) > 0)
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        return 0;
    }
    [edit]
    sorry, forget this:

    Window.cpp
    Code:
    #include "Window.h"
    
    LRESULT CALLBACK CWindow::staticWinMsgHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        CWindow* pWnd;
    
        if(uMsg == WM_NCCREATE)
        {
            SetWindowLong(hwnd, GWL_USERDATA, (long)((LPCREATESTRUCT(lParam))->lpCreateParams));
        }
    
        pWnd = (CWindow *)GetWindowLong(hwnd, GWL_USERDATA);
    
        if(pWnd)
            return pWnd->WinMsgHandler(hwnd, uMsg, wParam, lParam);
        else
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    
    LRESULT CALLBACK CWindow::WinMsgHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        switch(uMsg)
        {
            case WM_CREATE:
                MessageBox(NULL, "Create", "test", MB_OK);
                break;
            case WM_CLOSE:
                DestroyWindow(hwnd);
                PostQuitMessage(0);
                break;
            default:
                DefWindowProc(hwnd,uMsg,wParam,lParam);
        }
        return 0;
    }
    
    BOOL CWindow::RegisterWindow()
    {
        WNDCLASS wcx;
    
        wcx.style         = CS_HREDRAW | CS_VREDRAW;
        wcx.lpfnWndProc   = CWindow::staticWinMsgHandler;
        wcx.cbClsExtra    = 0;
        wcx.cbWndExtra    = 0;
        wcx.hInstance     = m_hInstance;
        wcx.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
        wcx.hCursor       = LoadCursor(NULL, IDC_ARROW);
        wcx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        wcx.lpszMenuName  = NULL;
        wcx.lpszClassName = "Window";
    
        return (RegisterClass(&wcx) != 0);
    }
    
    BOOL CWindow::Create()
    {
        m_hwnd = CreateWindow("Window", "Hello",
            WS_OVERLAPPEDWINDOW | WS_VISIBLE,
            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
            NULL, NULL, m_hInstance, (void *)this);
    
        return (m_hwnd != NULL);
    }
    Window.h hasn't changed.
    Last edited by miica; 02-22-2005 at 01:08 PM.

  9. #9
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Code:
    LRESULT CALLBACK CWindow::WinMsgHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        switch(uMsg)
        {
            case WM_CREATE:
                MessageBox(NULL, "Create", "test", MB_OK);
                break;
            case WM_CLOSE:
                DestroyWindow(hwnd);
                PostQuitMessage(0);
                break;
            default:
                return DefWindowProc(hwnd,uMsg,wParam,lParam);
        }
        return 0;
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  10. #10
    Registered User
    Join Date
    Feb 2005
    Posts
    4
    [edit to my last post]
    "I thought the code does not compile"
    actually it did compiled under MSVC but the program doesn't work.

    Ah, that return, sorry, if only I could understand more about the code myself, then I would be able to solve it. It works now, I am very happy thank you Ken Fitlike and others who has helped.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. What's wrong with this code?
    By Luciferek in forum C++ Programming
    Replies: 4
    Last Post: 06-21-2008, 12:02 PM
  2. need example code for a win32 window
    By deian in forum Windows Programming
    Replies: 18
    Last Post: 09-29-2007, 06:33 AM
  3. What is wrong with my code? My first program......
    By coreyt1111 in forum C++ Programming
    Replies: 11
    Last Post: 11-14-2006, 02:03 PM
  4. what is wrong with this code please
    By korbitz in forum Windows Programming
    Replies: 3
    Last Post: 03-05-2004, 10:11 AM
  5. I cant find what is wrong with this code
    By senegene in forum C Programming
    Replies: 1
    Last Post: 11-12-2002, 06:32 PM