Winapi Direct2D:移动窗口将变为灰色
我从一个非常简单的示例开始使用Direct2D。 获取factory和ID2D1HwndRenderTarget,然后处理WM_PAINT消息,使用“清除”功能仅绘制纯色背景 在我开始移动窗户之前,一切正常。当窗口移动时,它会变成灰色,就像什么都没有画一样。我试着画一个椭圆,结果是一样的 当窗口移动时,如何显示窗口内容 以防需要代码Winapi Direct2D:移动窗口将变为灰色,winapi,direct2d,Winapi,Direct2d,我从一个非常简单的示例开始使用Direct2D。 获取factory和ID2D1HwndRenderTarget,然后处理WM_PAINT消息,使用“清除”功能仅绘制纯色背景 在我开始移动窗户之前,一切正常。当窗口移动时,它会变成灰色,就像什么都没有画一样。我试着画一个椭圆,结果是一样的 当窗口移动时,如何显示窗口内容 以防需要代码 #include <Windows.h> #include <d2d1_1.h> #pragma comment(lib,"d2d1")
#include <Windows.h>
#include <d2d1_1.h>
#pragma comment(lib,"d2d1")
ID2D1Factory * d2factory_ptr = NULL;
ID2D1HwndRenderTarget * renderTarget_ptr = NULL;
LRESULT CALLBACK mainWinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI wWinMain(
HINSTANCE hInstance
, HINSTANCE prevInstance
, LPWSTR cmd
, int nCmdShow
) {
WNDCLASSEX wndClassStruct;
ZeroMemory(&wndClassStruct, sizeof(WNDCLASSEX));
wndClassStruct.cbSize = sizeof(WNDCLASSEX);
wndClassStruct.hbrBackground = (HBRUSH)COLOR_WINDOW;
wndClassStruct.style = CS_HREDRAW | CS_VREDRAW;
wndClassStruct.hInstance = hInstance;
wndClassStruct.lpfnWndProc = mainWinProc;
wndClassStruct.lpszClassName = TEXT("MainWnd");
RegisterClassEx(&wndClassStruct);
RECT windowRect = { 0,0,640,480};
AdjustWindowRectEx(&windowRect, WS_OVERLAPPEDWINDOW, 0, WS_EX_APPWINDOW);
HWND hWnd = CreateWindowEx(WS_EX_APPWINDOW, TEXT("MainWnd"), TEXT("Direct 2D Test Window"), WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE, CW_USEDEFAULT, 0, windowRect.right-windowRect.left, windowRect.bottom-windowRect.top, NULL, NULL, hInstance, 0);
{
D2D1_FACTORY_OPTIONS fo;
ZeroMemory(&fo, sizeof(D2D1_FACTORY_OPTIONS));
IID const factoryIID = IID_ID2D1Factory1;
HRESULT res = S_OK;
if (S_OK != (res = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &factoryIID, &fo, &d2factory_ptr))) {
return 0;
}
RECT clientRect;
GetClientRect(hWnd, &clientRect);
D2D1_RENDER_TARGET_PROPERTIES renderTargetProps;
ZeroMemory(&renderTargetProps, sizeof(D2D1_RENDER_TARGET_PROPERTIES));
renderTargetProps.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
renderTargetProps.pixelFormat = (D2D1_PIXEL_FORMAT) { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED };
renderTargetProps.dpiX = 0;
renderTargetProps.dpiY = 0;
renderTargetProps.usage = D2D1_RENDER_TARGET_USAGE_FORCE_BITMAP_REMOTING;
renderTargetProps.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
D2D1_HWND_RENDER_TARGET_PROPERTIES hwndRenderProps;
ZeroMemory(&hwndRenderProps, sizeof(D2D1_HWND_RENDER_TARGET_PROPERTIES));
hwndRenderProps.hwnd = hWnd;
hwndRenderProps.pixelSize = (D2D1_SIZE_U) { clientRect.right - clientRect.left, clientRect.bottom - clientRect.top };
hwndRenderProps.presentOptions = D2D1_PRESENT_OPTIONS_NONE;
if (S_OK != (res = d2factory_ptr->lpVtbl->CreateHwndRenderTarget(d2factory_ptr, &renderTargetProps, &hwndRenderProps, &renderTarget_ptr))) {
return 0;
}
}
ShowWindow(hWnd, nCmdShow);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
DestroyWindow(hWnd);
if(NULL != renderTarget_ptr)
renderTarget_ptr->lpVtbl->Base.Base.Base.Release((IUnknown*)renderTarget_ptr);
if (NULL != d2factory_ptr)
d2factory_ptr->lpVtbl->Base.Release((IUnknown*)d2factory_ptr);
return 0;
}
LRESULT onPaintMainWindow() {
ID2D1RenderTargetVtbl renderTargetFuncs = renderTarget_ptr->lpVtbl->Base;
ID2D1RenderTarget * This = (ID2D1RenderTarget*)renderTarget_ptr;
D2D1_TAG tag1, tag2;
D2D1_COLOR_F backgroundClr = (D2D1_COLOR_F) { 0.0, 0.5, 1.0, 1.0 };
renderTargetFuncs.BeginDraw(This);
renderTargetFuncs.Clear(This, &backgroundClr);
renderTargetFuncs.EndDraw(This, &tag1, &tag2);
return 0;
}
LRESULT CALLBACK mainWinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
if (WM_PAINT == uMsg)
return onPaintMainWindow();
if (WM_DESTROY == uMsg) {
PostQuitMessage(0); return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
#包括
#包括
#pragma注释(lib,“d2d1”)
ID2D1Factory*d2factory\u ptr=NULL;
ID2D1HwndRenderTarget*renderTarget_ptr=NULL;
LRESULT回调mainWinProc(HWND HWND、UINT uMsg、WPARAM WPARAM、LPARAM LPARAM);
int-WINAPI-wWinMain(
实例句柄
,例如
,LPWSTR cmd
,int nCmdShow
) {
WNDCLASSEX wndClassStruct;
零内存(&wndClassStruct,sizeof(WNDCLASSEX));
wndClassStruct.cbSize=sizeof(WNDCLASSEX);
wndClassStruct.hbrBackground=(HBRUSH)颜色窗口;
wndClassStruct.style=CS_HREDRAW | CS_VREDRAW;
wndClassStruct.hInstance=hInstance;
wndClassStruct.lpfnWndProc=mainWinProc;
wndClassStruct.lpszClassName=文本(“MainWnd”);
RegisterClassEx(&wndClassStruct);
RECT windowRect={0,0640480};
调整WindowRectex(&windowRect,WS_OVERLAPPEDWINDOW,0,WS_EX_APPWINDOW);
HWND HWND=CreateWindowEx(WS_EX_APPWINDOW,TEXT(“MainWnd”),TEXT(“直接2D测试窗口”),WS_重叠| WS_字幕| WS_系统菜单| WS_最小化框| WS|u可见,CW_USEDEFAULT,0,windowRect.right-windowRect.left,windowRect.bottom-windowRect.top,NULL,NULL,hInstance,0);
{
D2D1_工厂_选项fo;
零内存(&fo,sizeof(D2D1工厂选项));
IID const factoryId=IID_ID2D1Factory1;
HRESULT res=S_正常;
如果(S_OK!=(res=D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,&factoryid,&fo,&d2factory_ptr))){
返回0;
}
直肠系膜;
GetClientRect(hWnd和clientRect);
D2D1_渲染_目标_属性renderTargetProps;
ZeroMemory(&renderTargetProps,sizeof(D2D1_RENDER_TARGET_PROPERTIES));
renderTargetProps.type=D2D1\u RENDER\u TARGET\u type\u默认值;
renderTargetProps.pixelFormat=(D2D1_像素_格式){DXGI_格式_B8G8R8A8_UNORM,D2D1_ALPHA_模式_预乘};
renderTargetProps.dpiX=0;
renderTargetProps.dpiY=0;
renderTargetProps.usage=D2D1\u渲染\u目标\u使用\u强制\u位图\u远程处理;
renderTargetProps.minLevel=D2D1\u功能\u级别\u默认值;
D2D1_HWND_RENDER_TARGET_PROPERTIES hwndRenderProps;
ZeroMemory(&HwnRenderProps,sizeof(D2D1\u HWND\u RENDER\u TARGET\u PROPERTIES));
hwndRenderProps.hwnd=hwnd;
hwndRenderProps.pixelSize=(D2D1_SIZE_){clientRect.right-clientRect.left,clientRect.bottom-clientRect.top};
hwndrendrprops.presentOptions=D2D1\u PRESENT\u OPTIONS\u NONE;
如果(S_OK!=(res=d2factory_ptr->lpVtbl->CreateHwndRenderTarget(d2factory_ptr,&renderTargetProps,&hwndRenderProps,&renderTarget_ptr))){
返回0;
}
}
显示窗口(hWnd、nCmdShow);
味精;
while(GetMessage(&msg,NULL,0,0)){
翻译信息(&msg);
发送消息(&msg);
}
窗口(hWnd);
if(NULL!=渲染目标\u ptr)
renderTarget\u ptr->lpVtbl->Base.Base.Base.Release((IUnknown*)renderTarget\u ptr);
if(NULL!=D2工厂ptr)
d2factory\u ptr->lpVtbl->Base.Release((IUnknown*)d2factory\u ptr);
返回0;
}
LRESULT OnPaintMain窗口(){
ID2D1RenderTargetVtbl renderTargetFuncs=renderTarget\u ptr->lpVtbl->Base;
ID2D1RenderTarget*此=(ID2D1RenderTarget*)renderTarget\u ptr;
D2D1_标签tag1、tag2;
D2D1_COLOR_F backgroundClr=(D2D1_COLOR_F){0.0,0.5,1.0,1.0};
renderTargetFuncs.BeginDraw(此);
renderTargetFuncs.Clear(This和backgroundClr);
EndDraw(This,&tag1,&tag2);
返回0;
}
LRESULT回调mainWinProc(HWND HWND、UINT uMsg、WPARAM WPARAM、LPARAM LPARAM){
if(WM_PAINT==uMsg)
返回PaintMainWindow();
if(WM_DESTROY==uMsg){
PostQuitMessage(0);返回0;
}
返回DefWindowProc(hWnd、uMsg、wParam、lParam);
}
将WNDCLASSEX配置为没有背景画笔
替换此行:
wndClassStruct.hbrBackground = (HBRUSH)COLOR_WINDOW;
为此:
wndClassStruct.hbrBackground = GetStockObject(NULL_BRUSH);
或者,您可以修改mainWndProc以吞下WM_橡皮擦BKGND消息。它通过在发出WM_绘制之前不允许窗口擦除自身来实现相同的效果
LRESULT CALLBACK mainWinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
if (WM_PAINT == uMsg)
return onPaintMainWindow();
if (uMsg == WM_ERASEBKGND)
{
// ignore requests to erase the background since the wm_paint
// handler is going to redraw the entire window.
return 0;
}
if (WM_DESTROY == uMsg) {
PostQuitMessage(0); return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
将WNDCLASSEX配置为没有背景笔刷 替换此行:
wndClassStruct.hbrBackground = (HBRUSH)COLOR_WINDOW;
为此:
wndClassStruct.hbrBackground = GetStockObject(NULL_BRUSH);
或者,您可以修改mainWndProc以吞下WM_橡皮擦BKGND消息。它通过在发出WM_绘制之前不允许窗口擦除自身来实现相同的效果
LRESULT CALLBACK mainWinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
if (WM_PAINT == uMsg)
return onPaintMainWindow();
if (uMsg == WM_ERASEBKGND)
{
// ignore requests to erase the background since the wm_paint
// handler is going to redraw the entire window.
return 0;
}
if (WM_DESTROY == uMsg) {
PostQuitMessage(0); return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
我们需要查看代码。我们需要查看代码。谢谢!两人都在工作。什么是更好的决定?NULL_BRUSH或WM_ERASEBKGND?我会使用WM_ERASEBKGND修复程序,因为这意味着windows甚至不会尝试进行像素更新。您应该阅读,因为它建议您应该返回1而不是0。非常感谢!我将处理WM_擦除BKGND消息。谢谢!两人都在工作。什么是更好的决定?NULL_BRUSH或WM_ERASEBKGND?我会使用WM_ERASEBKGND修复程序,因为这意味着windows甚至不会尝试进行像素更新。您应该阅读,因为它建议您应该返回1而不是0。非常感谢!我将处理WM_擦除BKGND消息。