Direct2D基础窗体编程
来源:互联网 发布:积分商城 php源代码 编辑:程序博客网 时间:2024/06/06 01:18
Direct2D基于Windows窗体,因此必须了解一些基本的Windows窗体编程:
首先,最基本的,可以使用Windows API写一个窗体:
#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库后,窗体编程的事件过程可以简化很多:
#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示例(显示一个带颜色的窗体):
#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
- Direct2D基础窗体编程
- Direct2D 几何图形绘制基础
- 用户窗体编程基础
- Direct2D编程入门
- Direct2D 编程入门
- Windows编程基础--窗体篇
- 正交投影的DIRECT2D绘图基础部分
- Windows编程基础--窗体篇[转载]
- Windows窗体编程基础学习:文件读写
- javaSE基础编程——GUI窗体
- opencv Mat显示到指定窗体 Direct2D实现
- Direct2D随笔3——构建游戏基础结构
- [引]Windows窗体编程基础学习: 对话框组件
- vb.net 教程 3-1 窗体编程基础 1
- vb.net 教程 3-1 窗体编程基础 2
- Windows编程基础--第18节 MFC之窗体操作
- Direct2D 1.1
- Direct2D入门
- chrome为什么不支持网银
- web测试需要了解的知识
- mmap
- 黑马训练营 ------------ 银行调度系统
- Arguments对象
- Direct2D基础窗体编程
- 代码里的命名规则:错误的和正确的对比
- Interactive Python:Mini-project #4 - "Pong"
- S3C6410异常处理机制——异常向量表
- 黑马训练营 ---------------- 交通灯
- The software trap
- protobuf 与xml,还有json
- Ios多线程编程:NSOperation和NSOperationQueue
- Direct2D 几何图形