您的位置:首页 > 其它

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

2018-01-11 13:13 483 查看
我们来创建我们的第一个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
a882
(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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: