Windows基礎表單編程

來源:互聯網
上載者:User

Direct2D基於Windows表單,因此必須瞭解一些基本的Windows表單編程:

首先,最基本的,可以使用Windows API寫一個表單:

View Code

#include <Windows.h>typedef LRESULT (* message_callback)(HWND, WPARAM, LPARAM);struct message_handler{    UINT message;    message_callback handler;};static message_handler s_handlers[] = {    {        WM_PAINT, [] (HWND window, WPARAM, LPARAM) -> LRESULT        {            PAINTSTRUCT ps;            BeginPaint(window, &ps);            OutputDebugString(L"PAINT!\r\n");            EndPaint(window, &ps);            return 0;        }    },     {        WM_DESTROY, [] (HWND, WPARAM, LPARAM) -> LRESULT        {            PostQuitMessage(0);            return 0;        }    }};int __stdcall wWinMain(HINSTANCE module, HINSTANCE, PWSTR, int){    WNDCLASS wc = {};    wc.style = CS_HREDRAW | CS_VREDRAW;    wc.hCursor = LoadCursor(nullptr, IDC_ARROW);    wc.hInstance = module;    wc.lpszClassName = L"window";    wc.lpfnWndProc = [] (HWND window, UINT message, WPARAM wparam, LPARAM lparam) -> LRESULT    {        for (auto h = s_handlers; h != s_handlers + _countof(s_handlers); ++h)        {            if (message == h->message)            {                return h->handler(window, wparam, lparam);            }        }        return DefWindowProc(window, message, wparam, lparam);    };    RegisterClass(&wc);    auto hwnd = CreateWindow(wc.lpszClassName, L"title", WS_OVERLAPPEDWINDOW | WS_VISIBLE,         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,         nullptr, nullptr, module, nullptr);    MSG message;    BOOL result;        while (result = GetMessage(&message, 0, 0, 0))    {        if (result != -1)        {            DispatchMessage(&message);        }    }}

然後,加入ATL庫後,表單編程的事件程序可以簡化很多: 

View Code

#include <Windows.h>#include <atlbase.h>#include <atlwin.h>struct SampleWindow :    CWindowImpl<SampleWindow, CWindow, CWinTraits<WS_OVERLAPPEDWINDOW | WS_VISIBLE>>{    DECLARE_WND_CLASS_EX(L"window", CS_HREDRAW | CS_VREDRAW, -1);    BEGIN_MSG_MAP(SampleWindow)        MESSAGE_HANDLER(WM_PAINT, PaintHandler)        MESSAGE_HANDLER(WM_DESTROY, DestroyHandler)    END_MSG_MAP()    LRESULT PaintHandler(UINT, WPARAM, LPARAM, BOOL&)    {        PAINTSTRUCT ps;        BeginPaint(&ps);        EndPaint(&ps);        return 0;    }    LRESULT DestroyHandler(UINT, WPARAM, LPARAM, BOOL&)    {        PostQuitMessage(0);        return 0;    }};int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int){    SampleWindow window;    window.Create(nullptr, 0, L"Title", WS_OVERLAPPEDWINDOW | WS_VISIBLE);    MSG message;    BOOL result;    while (result = GetMessage(&message, 0, 0, 0))    {        if (result != -1)        {            DispatchMessage(&message);        }    }}

要加入D2D1,需要引入COM組件,然而,COM比較複雜,微軟引用WRL來簡化COM的一些引用計數之類的操作,以下是一個基本的D2D1樣本(顯示一個帶顏色的表單):

View Code

#include "Precompiled.h"#include <d2d1.h>#include <wrl.h>#pragma comment(lib, "d2d1")using namespace D2D1;using namespace Microsoft::WRL;struct SampleWindow    : CWindowImpl<SampleWindow, CWindow, CWinTraits<WS_OVERLAPPEDWINDOW | WS_VISIBLE>>{    ComPtr<ID2D1Factory> m_factory;    ComPtr<ID2D1HwndRenderTarget> m_target;    DECLARE_WND_CLASS_EX(L"My D2D1 Window", CS_HREDRAW | CS_VREDRAW, -1);    BEGIN_MSG_MAP(SampleWindow)        MESSAGE_HANDLER(WM_PAINT, PaintHandler)        MESSAGE_HANDLER(WM_DESTROY, DestroyHandler)        MESSAGE_HANDLER(WM_SIZE, SizeHandler)        MESSAGE_HANDLER(WM_DISPLAYCHANGE, DisplayChangeHandler)    END_MSG_MAP()    LRESULT DisplayChangeHandler(UINT, WPARAM, LPARAM, BOOL&)    {        Invalidate();        return 0;    }    LRESULT SizeHandler(UINT, WPARAM, LPARAM lparam, BOOL&)    {        if (m_target)        {            if (m_target->Resize(SizeU(LOWORD(lparam), HIWORD(lparam))) != S_OK)            {                m_target.Reset();            }        }        return 0;    }    LRESULT PaintHandler(UINT, WPARAM, LPARAM, BOOL&)    {        PAINTSTRUCT ps;        VERIFY(BeginPaint(&ps));        Render();        EndPaint(&ps);        return 0;    }    LRESULT DestroyHandler(UINT, WPARAM, LPARAM, BOOL&)    {        PostQuitMessage(0);        return 0;    }    void Invalidate()    {        VERIFY(InvalidateRect(nullptr, false))    }    void Create()    {        D2D1_FACTORY_OPTIONS fo = {};#ifdef DEBUG        fo.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;#endif        D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,                           fo,                           m_factory.GetAddressOf());        CreateDeviceIndependentResources();        VERIFY(__super::Create(nullptr, 0, L"title"));    }    void CreateDeviceIndependentResources()    {    }    void CreateDeviceResources()    {    }    void Render()    {        if (!m_target)        {            RECT rect;            VERIFY(GetClientRect(&rect));            auto size = SizeU(rect.right, rect.bottom);            m_factory->CreateHwndRenderTarget(RenderTargetProperties(),                                               HwndRenderTargetProperties(m_hWnd, size),                                               m_target.GetAddressOf());            CreateDeviceResources();                    }        if (!(m_target->CheckWindowState() & D2D1_WINDOW_STATE_OCCLUDED))        {            m_target->BeginDraw();            Draw();            if (m_target->EndDraw() == D2DERR_RECREATE_TARGET)            {                m_target.Reset();            }        }    }    void Draw()    {        m_target->Clear(ColorF(1.0f, 1.0f, 0.0f));    }};int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int){    SampleWindow window;    window.Create();    MSG msg;    BOOL result;    while (result = GetMessage(&msg, 0, 0, 0))    {        if (result != -1)        {            DispatchMessage(&msg);        }    }}

不得不說的是,這些樣本和我原來在網上和書上看到的很不一樣,感覺他寫的更加優雅,通過他的講解,可以很容易理解。

More content at http://pluralsight.com, Direct2D Fundamentals

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.