Windows桌面应用程序(1-2-4-4th) 您的第一个Direct2D程序

我们来创建我们的第一个Direct2D程序。这个程序并没有什么特别之处——它只是绘制一个填满窗口客户区域的圆圈。但是这个程序引入了许多重要的Direct2D概念。
这里写图片描述
Circle程序的屏幕截图。

这是Circle程序的代码清单。该程序重新使用在管理应用程序状态主题中定义的BaseWindow类。稍后的主题将详细检查代码。

#include<windows.h>
#include<d2d1.h>
#pragma comment(lib, "d2d1")
#include"basewin.h"
template<class T>
void SafeRelease(T **ppT){
    if(*ppT){
        (*ppT)->Release();
        *ppT=NULL;
    }
}
class MainWindow:public BaseWindow<MainWindow>{
    ID2D1Factory *pFactory;
    ID2D1HwndRenderTarget *pRenderTarget;
    ID2D1SolidColorBrush *pBrush;
    D2D1_ELLIPSE ellipse;
    void CalculateLayout();
    HRESULT CreateGraphicsResources();
    void DiscardGraphicsResources();
    void OnPaint();
    void Resize();
    public:
    MainWindow():pFactory(NULL),pRenderTarget(NULL),pBrush(NULL){}
    PCWSTR ClassName()const{
        return L"Circle Window Class";
    }
    LRESULT HandleMessage(UINT uMsg,WPARAM wParam,LPARAM lParam);
};
// Recalculate drawing layout when the size of the window changes.
void MainWindow::CalculateLayout(){
    if(pRenderTarget!=NULL){
        D2D1_SIZE_F size=pRenderTarget->GetSize();
        const float x=size.width/2;
        const float y=size.height/2;
        const float radius=min(x,y);
        ellipse=D2D1::Ellipse(D2D1::Point2F(x,y),radius,radius);
    }
}
HRESULT MainWindow::CreateGraphicsResources(){
    HRESULT hr=S_OK;
    if(pRenderTarget==NULL){
        RECT rc;
        GetClientRect(m_hwnd,&rc);
        D2D1_SIZE_U size=D2D1::SizeU(rc.right,rc.bottom);
        hr=pFactory->CreateHwndRenderTarget(
            D2D1::RenderTargetProperties(),
            D2D1::HwndRenderTargetProperties(m_hwnd,size),
            &pRenderTarget
        );
        if(SUCCEEDED(hr)){
            const D2D1_COLOR_F color=D2D1::ColorF(1.0f,1.0f,0);
            hr=pRenderTarget->CreateSolidColorBrush(color,&pBrush);
            if(SUCCEEDED(hr))
                CalculateLayout();
        }
    }
    return hr;
}
void MainWindow::DiscardGraphicsResources(){
    SafeRelease(&pRenderTarget);
    SafeRelease(&pBrush);
}
void MainWindow::OnPaint(){
    HRESULT hr=CreateGraphicsResources();
    if(SUCCEEDED(hr)){
        PAINTSTRUCT ps;
        BeginPaint(m_hwnd,&ps);
        pRenderTarget->BeginDraw();
        pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::SkyBlue));
        pRenderTarget->FillEllipse(ellipse,pBrush);
        hr=pRenderTarget->EndDraw();
        if(FAILED(hr)||hr==D2DERR_RECREATE_TARGET)
            DiscardGraphicsResources();
        EndPaint(m_hwnd,&ps);
    }
}
void MainWindow::Resize(){
    if(pRenderTarget!=NULL){
        RECT rc;
        GetClientRect(m_hwnd,&rc);
        D2D1_SIZE_U size=D2D1::SizeU(rc.right,rc.bottom);
        pRenderTarget->Resize(size);
        CalculateLayout();
        InvalidateRect(m_hwnd,NULL,FALSE);
    }
}
int WINAPI wWinMain(HINSTANCE hInstance,HINSTANCE,PWSTR,int nCmdShow){
    MainWindow win;
    if(!win.Create(L"Circle",WS_OVERLAPPEDWINDOW))
        return 0;
    ShowWindow(win.Window(),nCmdShow);
    // Run the message loop.
    MSG msg={};
    while(GetMessage(&msg,NULL,0,0)){
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}
LRESULT MainWindow::HandleMessage(UINT uMsg,WPARAM wParam,LPARAM lParam){
    switch(uMsg){
        case WM_CREATE:
            if(FAILED(D2D1CreateFactory(
                D2D1_FACTORY_TYPE_SINGLE_THREADED,&pFactory
            )))
                return -1;// Fail CreateWindowEx.
            return 0;
        case WM_DESTROY:
            DiscardGraphicsResources();
            SafeRelease(&pFactory);
            PostQuitMessage(0);
            return 0;
        case WM_PAINT:
            OnPaint();
            return 0;
        case WM_SIZE:
            Resize();
            return 0;
    }
    return DefWindowProc(m_hwnd,uMsg,wParam,lParam);
}

您可以从Direct2D Circle Sample下载完整的Visual Studio项目。
D2D1命名空间
D2D1名称空间包含助手函数和类。这些不是Direct2D API的一部分——您可以在不使用Direct2D的情况下对其进行编程——但它们有助于简化您的代码。D2D1命名空间包含:

  • 用于构建颜色值的ColorF类。
  • 用于构建变换矩阵的Matrix3x2F
  • 一组函数来初始化Direct2D结构。

您将在整个模块中看到D2D1名称空间的示例。
下一个
呈现目标,设备和资源
相关话题
Direct2D圆圈样本


原文链接:Your First Direct2D Program

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值