|
-
June 2nd, 2006, 04:37 AM
#1
Encapsulation of the Window
Here's my window creation code.
Code:
#include <windows.h>
// Declare WndProcedure
LRESULT CALLBACK WndProcedure(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam);
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG Msg;
HWND hWnd;
HRESULT hRet;
WNDCLASSEX WndClsEx;
// Populate the WNDCLASSEX structure
WndClsEx.cbSize = sizeof(WNDCLASSEX);
WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
WndClsEx.lpfnWndProc = WndProcedure;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClsEx.hbrBackground = (HBRUSH)(COLOR_HIGHLIGHT+1);//(HBRUSH)GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = "MyWindow";
WndClsEx.hInstance = hInstance;
WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
/* COLOURS :)
COLOR_ACTIVEBORDER
COLOR_ACTIVECAPTION
COLOR_APPWORKSPACE
COLOR_BACKGROUND
COLOR_BTNFACE
COLOR_BTNSHADOW
COLOR_BTNTEXT
COLOR_CAPTIONTEXT
COLOR_GRAYTEXT
COLOR_HIGHLIGHT
COLOR_HIGHLIGHTTEXT
COLOR_INACTIVEBORDER
COLOR_INACTIVECAPTION
COLOR_MENU
COLOR_MENUTEXT
COLOR_SCROLLBAR
COLOR_WINDOW
COLOR_WINDOWFRAME
COLOR_WINDOWTEXT
*/
// Register the class
RegisterClassEx(&WndClsEx);
// Create the window object
hWnd = CreateWindow("MyWindow",
"Rich's Window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
// Verify window creation
if( !hWnd ) // If the window was not created,
return 0; // stop the application
// Show the window
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
// message pump
while( (hRet = GetMessage( &Msg, NULL, 0, 0 )) != 0)
{
if (hRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
return 0;
}
LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg,
WPARAM wParam, LPARAM lParam)
{
switch(Msg)
{
case WM_DESTROY:
// user wants to exit
PostQuitMessage(WM_QUIT);
break;
default:
// Hand off unprocessed messages to DefWindowProc
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
return 0;
}
I am unsure of how to put it in a class so I can create as many windows as i want in an application.
-What do i do with the message handler? Do i declare it static
-Once classed to i added member functions like set window caption, using sendmessage.
A description of how to do it would be fantastic , i want to try and do as much myself, its the only way i learn.
Rich
Visual Studio 2010 Professional | Windows 7 (x64)
Ubuntu
-
June 2nd, 2006, 07:45 PM
#2
Re: Encapsulation of the Window
If you add a class , then the minimum data you keep there would be the HWND. Now, once you have that and have a static wndproc, you have to find a way to get to the C++ object for a particular window and there are many ways to do it.
One way is to make a framework where the framework maintains a mapping of HWNDs to the C++ objects. ( MFC style )
Another way could be to , in case they are your own registered classes, to store the C++ object pointer as data for the window using SetWindowLong ( beware that if you overwrite this area ), it will be messy.
You can come up with any other way..
-
June 3rd, 2006, 08:20 AM
#3
Re: Encapsulation of the Window
Below is a simple implementation of a C++ encapsulation of the window process.
It uses a window property (SetPropA, GetPropA) to store the window objects pointer. (Create all windows on the heap to be sure it's valid. Also, in WM_NCDESTROY, you can 'delete this' so when a window is destroyed the destructor gets called.
Code:
class Window
{
public:
// Normal
protected:
HWND Handle;
virtual INT_PTR WindowProcess(UINT message,WPARAM wParam,LPARAM lParam) throw();
private:
static INT_PTR __stdcall HandleWindowProcess(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) throw();
};
/////////////////////////////////////////////////////////////
//// HandleWindowProcess
INT_PTR __stdcall Window::HandleWindowProcess(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) throw()
{
// pass your this pointer as the last parameter to CreateWindowEx
if (message == WM_NCCREATE)
{
LPCREATESTRUCT lpCreate = reinterpret_cast<LPCREATESTRUCT>(lParam);
Window * pWindow = reinterpret_cast<Window *>(lpCreate->lpCreateParams);
/* Comment out above line and uncomment the below for an MDI Child Window
LPMDICREATESTRUCT lpMdiCreate = reinterpret_cast<LPMDICREATESTRUCT>(lpCreate->lpCreateParams);
Window * pWindow = reinterpret_cast<Window *>(lpMdiCreate->lParam);
*/
pWindow->Handle = hWnd;
// Set a window property to store the window object pointer
::SetPropA(hWnd,"WindowObject",reinterpret_cast<HANDLE>(pWindow));
return pWindow->WindowProcess(message,wParam,lParam);
}
else
{
// try to obtain a pointer to the window object
Window * pWindow = reinterpret_cast<Window *>(::GetPropA(hWnd,"WindowObject"));
if (pWindow != NULL)
{
return pWindow->WindowProcess(message,wParam,lParam);
}
else
{
// not a window object
return ::DefWindowProc(hWnd,message,wParam,lParam);
}
}
}
-
June 5th, 2006, 05:26 AM
#4
Re: Encapsulation of the Window
Thanks, I'll book mark this thread and give it a shot sometime soon.
Hmm looking at james example maybe I should finish learning OPP for C++ first, I see type casting and throws, haven't looked at them yet.
Rich
Visual Studio 2010 Professional | Windows 7 (x64)
Ubuntu
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|