pouët.net

Go to bottom

Win32 API coding: A Wrapper class for Window Creation

category: general [glöplog]
Is there any experienced win32 api coders that can give me some usefull information about win32 wrapper classes?.. I guess this may not be the best place to ask, but i'll do it anyway.. Also I've read several tutorials about wrapper classes but noone seems to inherit the design i want. i want it to be easy, like when making new controllers, I want as little code as possible.

some cues:
- message crackers
- non-static wndProc

i think i may have it working very soon, i just thought i would ask someone here if they've been working on this before and what difficulties they may have had and what they're solutions they found etc.. - thanks
added on the 2009-01-03 01:13:29 by rudi rudi
Please ask a specific question.
added on the 2009-01-03 01:21:28 by hfr hfr
If you want as little code as possible winapi is definitely not the way you want to go. Use a widget toolkit such as QT,GTK+ or wxWidgets. Or If you don't mind managed code Windows Forms.
added on the 2009-01-03 01:29:13 by masterm masterm
What lazy-san said.

Although, might I ask, why reinvent the wheel?
added on the 2009-01-03 01:30:29 by doomdoom doomdoom
Quote:
I guess this may not be the best place to ask

good observation, now go ask google.
added on the 2009-01-03 01:32:40 by decipher decipher
Hm. Object Windows Library is a wrapper for WinAPI:

http://en.wikipedia.org/wiki/Object_Windows_Library
added on the 2009-01-03 01:50:56 by Salinga Salinga
Quote:

Quote:
I guess this may not be the best place to ask

good observation, now go ask google.


Hahaha! Definitively!
added on the 2009-01-03 02:49:25 by rudi rudi
well.. i was very specific on this topic right before i pressed submit and got a error message saying something like that i was not logged in anymore.
anyway.. im not gonna use wxWidgets or any libraries like that. it was meant to be a Win32 API coding question only, it seems like there arent that many people who are very fond of this kind of stuff. :P
added on the 2009-01-03 02:54:11 by rudi rudi
I never really got comfortable with wrapping the shit up, so I've just written my windows in pure win32. I'm doing the "non-static wndprocs" (or usually in my case "non-global wndprocs") only when I need to be able to create more than one window per wndproc (through GWLP_USERDATA or some shit). I usually don't bother with those fancy message cracker thingies.

See Raymond Chen's skeleton code if you need something simple:
http://blogs.msdn.com/oldnewthing/archive/2005/04/22/410773.aspx
added on the 2009-01-03 03:07:54 by kusma kusma
ok and thanks kusma. ill check the code tomorrow since im too tired for reading ... i was working on a "non-static" method but got some problems, i cant remember what problems it was, i dont think i really knew what happened because some windows didnt behave the way they should have behaved. i had to rewrite the whole thing again. bah time to sleep. ill probably be writing something in here again tomorrow.
added on the 2009-01-03 03:59:34 by rudi rudi
Ok. If you really want to use winapi here's my non-static approach to WNDPROC:
Code:LRESULT CALLBACK Win32_Application::staticWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { Win32_Application *thisApp; if(uMsg == WM_CREATE) { thisApp = (Win32_Application*)((LPCREATESTRUCT)lParam)->lpCreateParams; SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG_PTR)thisApp); } else thisApp = (Win32_Application*)GetWindowLongPtr(hWnd, GWL_USERDATA); if(thisApp == NULL) return DefWindowProc(hWnd, uMsg, wParam, lParam); return thisApp->windowProc(hWnd, uMsg, wParam, lParam); } LRESULT CALLBACK Win32_Application::windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_CREATE: break; case WM_CLOSE: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, uMsg, wParam, lParam); } return 0; }

Of course in your WNDCLASSEX you specify staticWindowProc and then remember to pass Win32_Application/your_class_name pointer (usually 'this') as the last parameter of CreateWindowEx().
added on the 2009-01-03 13:56:04 by masterm masterm
im doing the same thing masterm.



added on the 2009-01-03 16:55:59 by rudi rudi
im not sure what the fuck is going on here.
the main window draws over the child.

BB Image
added on the 2009-01-03 16:57:12 by rudi rudi
You might also want to consider using WM_NCCREATE and WM_NCDESTROY instead of WM_CREATE and WM_DESTROY as NCCREATE is issued before CREATE and NCDESTROY is issued after DESTROY. Let's you catch some more messages during creation and destruction.
added on the 2009-01-03 21:49:34 by kusma kusma
I'd give you some of my old code if I had it on the laptop. I'm with Kusma on this one though, go see if you can put the problem in a less 'specific' corner and if need really be, learn how the different window types differ from eachother by experience and lift the common part to a wrapper base once you feel confident.
added on the 2009-01-03 21:56:08 by superplek superplek
i started this project from scratch again.
this is how my cpp file looks like:

Code: #include "Window.h" WndBase::WndBase(HINSTANCE hInst) { hInstance = hInst; style = WS_OVERLAPPEDWINDOW | WS_VISIBLE; exStyle = 0; } int WndBase::Register() { wc.cbSize = sizeof(WNDCLASSEX); wc.style = NULL; wc.lpfnWndProc = msgRouter; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName = NULL; wc.lpszClassName = className; if(!RegisterClassEx(&wc)) { MessageBox(0, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL); return 0; } } void WndBase::Create(HWND hwndparent, int _x, int _y, int _width, int _height) { exStyle = WS_EX_CLIENTEDGE; x = _x; y = _y; width = _width; height = _height; hWndParent = hwndparent; hMenu = 0; hWnd = CreateWindowEx(exStyle, className, windowName, style, x, y, width, height, hWndParent, hMenu, hInstance, (void *)this); } void WndBase::SetHwnd(HWND hwnd) { hWnd = hwnd; } HWND WndBase::GetHwnd() { return hWnd; } void WndBase::ShowWindow(int cmd) { ::ShowWindow(hWnd, cmd); UpdateWindow(hWnd); } LRESULT CALLBACK WndBase::msgRouter(HWND hwnd, UINT msg, WPARAM w, LPARAM l) { WndBase *wnd = 0; if (msg == WM_NCCREATE) { wnd = reinterpret_cast <WndBase *> ((long)((LPCREATESTRUCT)l)->lpCreateParams); SetWindowLongPtr(hwnd, GWL_USERDATA, (LONG_PTR)wnd); wnd->SetHwnd(hwnd); } else wnd = reinterpret_cast <WndBase *> (GetWindowLong(hwnd, GWL_USERDATA)); if (wnd == NULL) return DefWindowProc(hwnd, msg, w, l); return wnd->wndProc(hwnd, msg, w, l); } WndMain::WndMain(HINSTANCE hInst) : WndBase(hInst) { className = TEXT("WndMainClass"); windowName = TEXT("WndMain"); wc.style |= CS_HREDRAW | CS_VREDRAW; } LRESULT CALLBACK WndMain::wndProc(HWND hwnd, UINT msg, WPARAM w, LPARAM l) { switch(msg) { case WM_CREATE: break; case WM_PAINT: OnPaint(); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, w, l); } return 0; } void WndMain::OnPaint() { RECT rect; HDC hDC = GetDC(hWnd); PAINTSTRUCT PaintStruct; BeginPaint(hWnd, &PaintStruct); GetClientRect(hWnd, &rect); DrawText(hDC, "Hello Parent!", 13, &rect, DT_VCENTER | DT_CENTER | DT_SINGLELINE); EndPaint(hWnd, &PaintStruct); ReleaseDC(hWnd, hDC); } WndChild::WndChild(HINSTANCE hInst) : WndBase(hInst) { className = TEXT("WndChildClass"); windowName = TEXT("WndChild"); style |= WS_CHILD; wc.style |= CS_HREDRAW | CS_VREDRAW; } LRESULT CALLBACK WndChild::wndProc(HWND hwnd, UINT msg, WPARAM w, LPARAM l) { switch(msg) { case WM_CREATE: break; case WM_PAINT: OnPaint(); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, w, l); } return 0; } void WndChild::OnPaint() { RECT rect; HDC hDC = GetDC(hWnd); PAINTSTRUCT PaintStruct; BeginPaint(hWnd, &PaintStruct); GetClientRect(hWnd, &rect); DrawText(hDC, "Hello Child!", 12, &rect, DT_VCENTER | DT_CENTER | DT_SINGLELINE); EndPaint(hWnd, &PaintStruct); ReleaseDC(hWnd, hDC); }


and the declarations looks like this:

Code: #include <windows.h> class WndBase { public: WndBase(HINSTANCE); int Register(); void Create(HWND hwndparent, int _x, int _y, int _width, int _height); protected: static LRESULT CALLBACK msgRouter(HWND, UINT, WPARAM, LPARAM); virtual LRESULT CALLBACK wndProc(HWND, UINT, WPARAM, LPARAM) = 0; public: void SetHwnd(HWND); HWND GetHwnd(); void ShowWindow(int); protected: HWND hWnd; HINSTANCE hInstance; WNDCLASSEX wc; HWND hWndParent; HMENU hMenu; LPCSTR className; LPCSTR windowName; int style; int exStyle; int x, y; int width, height; }; class WndMain : public WndBase { public: WndMain(HINSTANCE hInst); void OnPaint(); protected: LRESULT CALLBACK wndProc(HWND, UINT, WPARAM, LPARAM); }; class WndChild : public WndBase { public: WndChild(HINSTANCE hInst); void OnPaint(); protected: LRESULT CALLBACK wndProc(HWND, UINT, WPARAM, LPARAM); };


so the problem i have right now is that the parent window is drawing over the child window. like the screenshot i pasted yesterday. im not sure what is wrong, the rest of the code is working okay.
added on the 2009-01-04 17:12:48 by rudi rudi
what i mean by that is that something is happening either in the DrawText function in the MainWindow or somewhere else, it seems like the child window's client is overdrawn when moving the child-window over the mainwindow's text.
added on the 2009-01-04 17:15:44 by rudi rudi
Maybe something with the WM_BACKGROUND messages?! Otherwise maybe some drawing function gets a wrong window handle...
added on the 2009-01-04 17:26:26 by raer raer
yeh, it may be that. the message-routing may not be working properly i think.
added on the 2009-01-04 17:49:24 by rudi rudi
hmm. the problem does not occur when i remove the WS_CHILD style in the WNDCLASSEX structure. so, obviously doesnt it have anything to do with the messagehandler or something..
added on the 2009-01-04 22:16:44 by rudi rudi
i found it! there was just a flag i needed to have for the parent window. its called WM_CLIPCHILDREN and it prevents areas occupied by child windows from being drawn on.
added on the 2009-01-04 22:25:47 by rudi rudi
WM_CLIPCHILDREN? I knew microsoft is evil, but thats just.. i mean, cmon THINK ABOUT THE CHILDREN!
OO pervs
added on the 2009-01-05 11:01:37 by DragonL DragonL
Seems to be pure joy opening a simple crappy window with WinAPI. And no, I wouldn't claim it's any cleaner with X11 for that matter. I guess you have your reasons for doing this but overall wouldn't it be sensible to use some lib for doing this - someone else has already taken the trouble of debugging on several machines?
added on the 2009-01-05 11:34:31 by Marq Marq
sorry but,

what a load of rubbish.. All this crap to open a window... :-( Surely wouldn't you rather use something else instead ?
added on the 2009-01-05 11:47:35 by Navis Navis

login

Go to top