C++ 模拟封装Win API

本文使用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;
}

取自《老马识途》

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值