一个窗口应用程序的基类实现代码

我们知道,开发一个窗口应用程序,可以使用MFC,里面有一个类CWinApp,但MFC的实现原理不那么容易弄懂。下面这个WinApp的类,可以说揭示了一个窗口应用程序的全貌,使用者只需要继承这个类,根据具体业务逻辑的需求去实现其中的几个虚函数就可以了。

/*
// Sample demonstrating interoperability of OpenCV UMat with Direct X surface
// Base class for Windows application
*/
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>


#define WINCLASS "WinAppWnd"

class WinApp
{
public:
    WinApp(int width, int height, std::string& window_name)
    {
        m_width       = width;
        m_height      = height;
        m_window_name = window_name;
        m_hInstance   = ::GetModuleHandle(NULL);
        m_hWnd        = 0;
    }

    virtual ~WinApp() {}

    virtual int create()
    {
        WNDCLASSEX wcex;

        wcex.cbSize        = sizeof(WNDCLASSEX);
        wcex.style         = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc   = &WinApp::StaticWndProc;
        wcex.cbClsExtra    = 0;
        wcex.cbWndExtra    = 0;
        wcex.hInstance     = m_hInstance;
        wcex.hIcon         = LoadIcon(0, IDI_APPLICATION);
        wcex.hCursor       = LoadCursor(0, IDC_ARROW);
        wcex.hbrBackground = 0;
        wcex.lpszMenuName  = 0L;
        wcex.lpszClassName = WINCLASS;
        wcex.hIconSm       = 0;

        ATOM wc = ::RegisterClassEx(&wcex);
        if (!wc)
            return -1;

        RECT rc = { 0, 0, m_width, m_height };
        if(!::AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, false))
            return -1;

        m_hWnd = ::CreateWindow(
                     (LPCTSTR)wc, m_window_name.c_str(),
                     WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
                     rc.right - rc.left, rc.bottom - rc.top,
                     NULL, NULL, m_hInstance, (void*)this);

        if (!m_hWnd)
            return -1;

        ::ShowWindow(m_hWnd, SW_SHOW);
        ::UpdateWindow(m_hWnd);
        ::SetFocus(m_hWnd);

        return 0;
    } // create()


    int run()
    {
        MSG msg;
        ::ZeroMemory(&msg, sizeof(msg));
        while (msg.message != WM_QUIT)
        {
            if (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
            {
                ::TranslateMessage(&msg);
                ::DispatchMessage(&msg);
            }
            else
            {
                idle();
            }
        }

        return static_cast<int>(msg.wParam);
    } // run()


    virtual int cleanup()
    {
        ::DestroyWindow(m_hWnd);
        ::UnregisterClass(WINCLASS, m_hInstance);
        return 0;
    } // cleanup()

protected:
    // dispatch message handling to method of class
    static LRESULT CALLBACK StaticWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        WinApp* pWnd;

        if (message == WM_NCCREATE)
        {
            LPCREATESTRUCT pCreateStruct = reinterpret_cast<LPCREATESTRUCT>(lParam);
            pWnd = static_cast<WinApp*>(pCreateStruct->lpCreateParams);
            ::SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pWnd));
        }

        pWnd = GetObjectFromWindow(hWnd);

        if (pWnd)
            return pWnd->WndProc(hWnd, message, wParam, lParam);
        else
            return ::DefWindowProc(hWnd, message, wParam, lParam);
    } // StaticWndProc()

    inline static WinApp* GetObjectFromWindow(HWND hWnd) { return (WinApp*)::GetWindowLongPtr(hWnd, GWLP_USERDATA); }

    // actual wnd message handling
    virtual LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) = 0;
    // idle processing
    virtual int idle() = 0;

    HINSTANCE   m_hInstance;
    HWND        m_hWnd;
    int         m_width;
    int         m_height;
    std::string m_window_name;
};

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值