Advertisement

Help with Window Class...

Started by February 10, 2003 10:02 PM
3 comments, last by NoMonkey 21 years, 9 months ago
I have done some digging online and asking some other people in the community but I can''t figure out why my program won''t close it''s instance. When I close the program, it calls the PostQuitMessage function when WM_DESTROY is called but PeekMessage doesn''t seem to see the WM_CLOSE message and leaves the program running in the background. All of this is in a class, so I am not sure if there is an extra step I need to take to correctly use PeekMessage in a member function or not. Here is the Code: /* pfWindow.h (created 2/10/03)*/ #pragma once #include <windows.h> class pfWindow { protected: HWND m_hWindow; MSG m_kMessage; WNDCLASSEX m_kWndClass; public: /* Constuctor and Destructor */ pfWindow (void) {}; ~pfWindow (void) {}; /* Functions */ /* Create a Window and Display it */ bool Create(HINSTANCE hInstance, LPSTR lpClassName, LPSTR lpWindowName, DWORD dwStyle = WS_OVERLAPPEDWINDOW | WS_VISIBLE, int x = CW_USEDEFAULT, int y = CW_USEDEFAULT, int nWidth = CW_USEDEFAULT, int nHeight = CW_USEDEFAULT); /* Windows Message Handler */ static LRESULT CALLBACK WndProc (HWND hWindow, UINT msg, WPARAM wParam, LPARAM lParam); /* Custom Message Loop */ void Run(void); }; bool pfWindow::Create(HINSTANCE hInstance, LPSTR lpClassName, LPSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight) { m_kWndClass.cbSize = sizeof(m_kWndClass); m_kWndClass.style = CS_HREDRAW | CS_VREDRAW; m_kWndClass.lpfnWndProc = WndProc; m_kWndClass.cbClsExtra = 0; m_kWndClass.cbWndExtra = 0; m_kWndClass.hInstance = hInstance; m_kWndClass.hIcon = LoadIcon(hInstance, IDI_APPLICATION); m_kWndClass.hIconSm = LoadIcon(hInstance, IDI_APPLICATION); m_kWndClass.hCursor = LoadCursor(NULL, IDC_ARROW); m_kWndClass.hbrBackground = (HBRUSH) GetStockObject(GRAY_BRUSH); m_kWndClass.lpszMenuName = NULL; m_kWndClass.lpszClassName = lpClassName; if (!RegisterClassEx(&m_kWndClass)) return 0; m_hWindow = CreateWindow(lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, NULL, NULL, hInstance, (void *)this); if (m_hWindow == NULL) return 0; SetWindowText(m_hWindow, lpWindowName); UpdateWindow(m_hWindow); return 1; } LRESULT CALLBACK pfWindow::WndProc(HWND hWindow, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hWindow, msg, wParam, lParam); } void pfWindow::Run(void) { while(1) { if (PeekMessage(&m_kMessage, m_hWindow, 0, 0, PM_REMOVE)) { if (WM_QUIT == m_kMessage.message) { /* Test for conditional statement being true */ MessageBox(m_hWindow, "Hello", "Testing", NULL); break; } else { TranslateMessage(&m_kMessage); DispatchMessage(&m_kMessage); } } } } /* pfWindow.cpp (created 2/10/03)*/ #include "pfWindow.h" int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { //custom window pfWindow NewWindow; //define window class and create window NewWindow.Create(hInstance, "ClsTest", "Testing"); //enter message loop NewWindow.Run(); return 1; }
Try passing NULL as the second parameter to PeekMessage(). That should take care of it.
Advertisement
That worked! Thank you very much!
Glad to help!
In case you''re curious, it''s because once the WM_DESTROY message has been passed to the window, the window is indeed destroyed. So when you try fetching messages for that window, you don''t get any. WM_QUIT is a thread-wide message, rather than a window-wide.

A couple of notes:


  • I don''t think you need that SetWindowText call. CreateWindow should do it for you perfectly.

  • From a conceptual point of view, ''Run'' isn''t really an action your window should be performing - it''s an action your application should be performing. You could move it to a CApplication class, or just make it a global function.

  • This might be overkill for your project, but there''s a really neat way of using a member function as a WndProc (and hence, having access to all member variables, etc - very useful if you have more than one window, and very useful when writing a re-usable window wrapper, because you can make the function virtual).


    Simply, there''s a block of 4 bytes for every window, designated as ''USERDATA'' - you can store anything you want in it. And so, you can store a pointer to your pfWindow in it. You pass a static function as the WndProc, but all that function does is retrieve the USERDATA, convert it back to a pointer, and call its NormalWndProc function.




Superpig
- saving pigs from untimely fates, and when he''s not doing that, runs The Binary Refinery.

Richard "Superpig" Fine - saving pigs from untimely fates - Microsoft DirectX MVP 2006/2007/2008/2009
"Shaders are not meant to do everything. Of course you can try to use it for everything, but it's like playing football using cabbage." - MickeyMouse

This topic is closed to new replies.

Advertisement