Win32 API wrapper classes

Hi,

I'm creating a few classes to use as Win32 API wrappers.

They are not intended to become a general library. I'm just doing this to get familiarized with the Win32 API and to integrate it with C++ coding.

The classes I created so far are Window, StatusBar, Button and ListView.

These are draft versions, so I know they can be improved. All this classes are not related to each other (there's no common base class for the controls), since so far I'm trying to determine if my approach is gonna work.

What I'd like to ask to this forum is:

- What do you think of the approach ?
- Why isn't my WM_CREATE message handled ? (The MessageBox in the on_create() function never shows up)

I'll post the main file first, so you can see how I intend to use this classes.

Thanks in advance, and let me know if you need to see the rest of the classes.

Cheers!

[code]
void on_resize(WPARAM wParam, LPARAM lparam); //this are procedures that will get called
void on_click(WPARAM wParam, LPARAM lParam); //when events occur
void on_exit(WPARAM wParam, LPARAM lParam); //
void on_create(WPARAM wParam, LPARAM lParam); //

Window *fm; //the main Window
Button *b; //a Button
StatusBar *sb; //the StatusBar
ListView *lv; //a ListView

int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
{
fm = new Window(hInst, "Test..."); //create the main Window
fm->Show(nCmdShow); //and display it
fm->Update(); //
//b = new Button(fm, "Boton", 100, 250, 100, 30); //add a button to the window
sb = new StatusBar(fm, "", 0, 0, 0, 0, 2); //add a status bar
sb->setPart(0, 100, 0, "Disconnected"); //create the status bar parts
sb->setPart(1, fm->getWidth() - 100, SBT_NOBORDERS, "");//
lv = new ListView(fm, "", 0, 0, 200, 200); //create a list view
lv->addColumn(70, "column0"); //and add two columns
lv->addColumn(70, "column1"); //to it
int it = lv->addItem(); //add some items to the list
lv->setItemText(it, 0, "item0-0"); //
lv->setItemText(it, 1, "item0-1"); //
it = lv->addItem(); //
lv->setItemText(it, 0, "item1-0"); //
lv->setItemText(it, 1, "item1-1"); //

fm->registerProcedure(WM_DESTROY, on_exit);
fm->registerProcedure(WM_COMMAND, on_click);
fm->registerProcedure(WM_SIZE, on_resize);
fm->registerProcedure(WM_CREATE, on_create);
return fm->MessageLoop();
}

void on_resize(WPARAM wParam, LPARAM lParam) {
//sb->move(0, HIWORD(lParam), LOWORD(lParam), HIWORD(lParam), FALSE);
sb->move(0, 0, 0, 0, FALSE);
sb->setPart(0, 100, 0, "Disconnected");
sb->setPart(1, LOWORD(lParam) - 100, SBT_NOBORDERS, "");
}

void on_click(WPARAM wParam, LPARAM lParam) {
if(LOWORD(wParam) == bt.getId())
MessageBox(NULL, "Button bt on_click", "Note", MB_OK);
}

void on_exit(WPARAM wParam, LPARAM lParam) {
PostQuitMessage(0);
}

void on_create(WPARAM wParam, LPARAM lParam) {
MessageBox(NULL, "wm_create", "", MB_OK);
}
[/code]

The Window class is defined in a file "windowclass.h"

[code]
typedef void(*PROCPTR)(WPARAM, LPARAM);

class Window {
public:
Window(HINSTANCE hInst, LPCSTR caption);
void Show(int nCmdShow);
void Update(void);
static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam,LPARAM lParam);
WPARAM MessageLoop(void);
HWND getHandle(void);
INT registerProcedure(WPARAM event, PROCPTR procedure);
HINSTANCE getInstance(void);
INT getFreeID(void);
LONG getWidth(void);
LONG getHeight(void);
private:
WNDCLASS wc;
HWND hWnd;
HINSTANCE hInst;
LPSTR Caption;
INT nextID; //value of the next ID to be returned by getFreeID()
};
[/code]

And the implementation in "windowclass.cpp":

[code]
static map procs;

Window::Window(HINSTANCE hInst, LPCSTR caption) {

Caption = (LPSTR)malloc(strlen(caption) + 1);
strcpy(Caption, caption);
Window::hInst = hInst;
Window::nextID = 101; //initial free ID

wc.lpszClassName = Caption;
wc.lpfnWndProc = WndProc;
wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
wc.hInstance = hInst;
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
wc.lpszMenuName = NULL;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;

if(!RegisterClass(&wc)) throw WindowException();
hWnd = CreateWindow(Caption,
Caption,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
500, 350, NULL, NULL,
hInst,NULL);
if(hWnd == NULL) throw WindowException();
}

LRESULT CALLBACK Window::WndProc(HWND hWnd, UINT msg, WPARAM wParam,LPARAM lParam) {

if(procs.find(msg) != procs.end()) {
procs[msg](wParam, lParam);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}

void Window::Show(int nCmdShow) {
ShowWindow(hWnd, nCmdShow);
}

void Window::Update(void) {
UpdateWindow(hWnd);
}

WPARAM Window::MessageLoop(void) {
MSG msg;
while(GetMessage(&msg,NULL,0,0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}

HWND Window::getHandle(void) {
return hWnd;
}

HINSTANCE Window::getInstance(void) {
return hInst;
}

INT Window::registerProcedure(UINT msg, PROCPTR procedure) {
procs[msg] = procedure;
return 0;
}

INT Window::getFreeID() {
return nextID ++;
}

LONG Window::getWidth(void) {
RECT rect;
GetClientRect(hWnd, &rect);
return rect.right;
}

LONG Window::getHeight(void) {
RECT rect;
GetClientRect(hWnd, &rect);
return rect.bottom;
}
[/code]

Comments

  • [blue]Not all messages from WndProc return zero. Some required to return different values. Otherwise, not bad, but a little inflexible... what if you need a child window? Do you need to create a C++ class for that too - how to derive it and perform appropriate creation?[/blue]
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

In this Discussion