本文使用C++ 简单封装Win API,封装一个Form和Button。
#include <windows.h>
#include <map>
HINSTANCE applicationHandle;
CRITICAL_SECTION handlesLock;
std::map<HANDLE, void *> windowHandles;
void InitApp(HINSTANCE instance) {
applicationHandle = instance;
InitializeCriticalSection(&handlesLock);
}
void AddWindowHandle(HWND hwnd, void * objPtr) {
EnterCriticalSection(&handlesLock);
windowHandles[hwnd] = objPtr;
LeaveCriticalSection(&handlesLock);
}
void DeleteWindowHandle(HWND hwd) {
EnterCriticalSection(&handlesLock);
windowHandles.erase(hwd);
LeaveCriticalSection(&handlesLock);
}
void* GetWindowObject(HWND hwnd) {
EnterCriticalSection(&handlesLock);
void *objPtr = windowHandles[hwnd];
LeaveCriticalSection(&handlesLock);
return objPtr;
}
class Button;
class ButtonListener {
public:
virtual void OnLeftButtonUp(Button *btn) = 0;
};
class ButtonAction : public ButtonListener {
virtual void OnLeftButtonUp(Button *btn) {
// MessageBox(NULL, "Button up test .. ", NULL, NULL);
}
};
class Button {
public:
Button(int x, int y, int width, int height, char *caption, HWND parentWnd);
virtual ~Button();
void SetListener(ButtonListener *listener) {
listener_ = listener;
}
private:
HWND handle_;
WNDPROC oldWinProc_;
ButtonListener *listener_;
static LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);
};
Button::Button(int x, int y, int width, int height, char *caption, HWND parentWnd) {
handle_ = CreateWindow("BUTTON", caption, WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, x, y,
width, height, parentWnd, 0, applicationHandle, NULL);
oldWinProc_ = (WNDPROC)SetWindowLong(handle_, GWL_WNDPROC, (LONG)this->WndProc);
AddWindowHandle(handle_, this);
listener_ = NULL;
}
Button::~Button() {
DeleteWindowHandle(handle_);
if (listener_ != NULL) delete listener_;
DestroyWindow(handle_);
}
LRESULT CALLBACK Button::WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
Button *self = (Button *)GetWindowObject(hwnd);
if (self == NULL) return 0;
//MessageBox(NULL, "button proc", NULL, NULL);
LRESULT result = CallWindowProc(self->oldWinProc_, hwnd, Message, wParam, lParam);
if (self->listener_ != NULL) {
if (Message == WM_LBUTTONUP) {
self->listener_->OnLeftButtonUp(self);
MessageBox(NULL, "button proc", NULL, NULL);
}
}
return result;
}
//HWND hBtn1;
//WNDPROC oldBtnProc;
class Form {
public:
Form(char *caption) {
memset(&wc_,0,sizeof(wc_));
wc_.cbSize = sizeof(WNDCLASSEX);
wc_.lpfnWndProc = WndProc; /* This is where we will send messages to */
wc_.hInstance = applicationHandle;
wc_.hCursor = LoadCursor(NULL, IDC_ARROW);
wc_.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc_.lpszClassName = "WindowClass";
wc_.hIcon = LoadIcon(NULL, IDI_APPLICATION); /* Load a standard icon */
wc_.hIconSm = LoadIcon(NULL, IDI_APPLICATION); /* use the name "A" to use the project icon */
if(!RegisterClassEx(&wc_)) {
MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
//return 0;
}
handle_ = CreateWindowEx(WS_EX_CLIENTEDGE,"WindowClass",caption, WS_VISIBLE|WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, /* x */
CW_USEDEFAULT, /* y */
640, /* width */
480, /* height */
NULL,NULL,applicationHandle,NULL);
oldWinProc_ = (WNDPROC)SetWindowLong(handle_, GWL_WNDPROC, (LONG)this->WndProc);
AddWindowHandle(handle_, this);
//listener_ = NULL;
}
virtual ~Form();
HWND GetHandle() {
return handle_;
}
private:
WNDCLASSEX wc_;
HWND handle_;
WNDPROC oldWinProc_;
ButtonListener *listener_;
BOOL isMainWnd_;
static LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);
};
Form::~Form() {
DeleteWindowHandle(handle_);
DestroyWindow(handle_);
if (isMainWnd_) {
PostQuitMessage(0);
}
}
LRESULT CALLBACK Form::WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
Form *self = (Form *)GetWindowObject(hwnd);
//MessageBox(NULL, "button proc", NULL, NULL);
//if (self == NULL) return 0;
//LRESULT result = CallWindowProc(self->oldWinProc_, hwnd, Message, wParam, lParam);
switch (Message)
{
case WM_DESTROY:
delete self;
return 0;
default:
break;
}
return DefWindowProc(hwnd, Message, wParam, lParam);
}
class MyButton : public Button, ButtonAction {
public:
MyButton(int x, int y, int width, int height, char *caption, HWND parentWnd)
: Button(x, y, width, height, caption, parentWnd) {
this->SetListener(this);
}
virtual void OnLeftButtonUp(Button *btn) {
MessageBox(NULL, "my button", NULL, NULL);
}
};
class MyForm : public Form {
public:
MyForm(char *caption)
: Form(caption)
{
btn1_ = new Button(10, 10, 100, 50, "TestButton", this->GetHandle());
btn1_->SetListener(new ButtonAction());
myBtn = new MyButton(50, 100, 100, 50, "MyButton", this->GetHandle());
}
virtual ~MyForm() {
delete btn1_;
delete myBtn;
}
private:
Button *btn1_;
MyButton *myBtn;
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
MSG msg;
InitApp(hInstance);
MyForm frm("lanzhuo");
while(GetMessage(&msg, NULL, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
取自《老马识途》