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

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

原文 http://blog.csdn.net/qq_37422196/article/details/79032979

2018-01-12 02:02:15阅读(457)

我们来创建我们的第一个Direct2D程序。这个程序并没有什么特别之处——它只是绘制一个填满窗口客户区域的圆圈。但是这个程序引入了许多重要的Direct2D概念。
<a href=Windows桌面应用程序(1-2-4-4th) 您的第一个Direct2D程序" title="" alt="这里写图片描述" src="https://msdn.microsoft.com/dynimg/IC405525.png">
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

最新发布

CentOS专题

关于本站

5ibc.net旗下博客站精品博文小部分原创、大部分从互联网收集整理。尊重作者版权、传播精品博文,让更多编程爱好者知晓!

小提示

按 Ctrl+D 键,
把本文加入收藏夹