如何解决BeginDraw在状态栏上绘制-不遵守renderTarget的大小调整
我有一个带窗口的Direct2D应用程序,并通过常用控件在窗口中添加了状态栏:
InitCommonControls();
HWND hStatus = CreateWindowEx(0,STATUSCLASSNAME,NULL,WS_CHILD | WS_VISIBLE | SBARS_SIZEgrip,hWnd,(HMENU)ID_STATUSBAR,GetModuleHandle(NULL),NULL);
状态栏显示得很好,但是,尽管我定义了高度,但一旦我在消息循环中激活BeginDraw()
&EndDRaw()
函数,状态栏就会被覆盖。 rendertarget
初始化时
res = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,&factory);
GetClientRect(windowHandle,&rectwindow);
GetClientRect(statusHandle,&rectStatus);
rectRender.width = rectwindow.right;
rectRender.height = rectwindow.bottom - (rectStatus.bottom - rectStatus.top);
res = factory->CreateHwndrendertarget(
D2D1::rendertargetProperties(),D2D1::HwndrendertargetProperties(windowHandle,rectRender),&rendertarget);
RECT rectwindow{ 0 },rectStatus{ 0 };
D2D1_SIZE_U rectRender{ 0 };
GetClientRect(windowHandle,&rectStatus);
rectRender.width = rectwindow.right;
rectRender.height = rectwindow.bottom - (rectStatus.bottom - rectStatus.top);
rendertarget->Resize(rectRender);
InvalidateRect(windowHandle,FALSE);
,并在WM_SIZING
和WM_SIZE中调用:
case WM_SIZE:
case WM_SIZING:
hStatus = GetDlgitem(hWnd,ID_STATUSBAR);
gfx->Resize(hWnd,hStatus);
SendMessage(hStatus,WM_SIZE,0);
BeginDraw()
是否不尊重rendertarget的尺寸并仅占据整个窗口?如果是这样,我应该考虑使用图层还是我的代码有问题?
编辑:对于这个问题,我收到了一些反对意见。如果我的帖子有问题,请告诉我,我会尽力改善。我在win32领域仍然很新鲜,但是我从这个平台中学到了很多。我很乐意为您提供有趣的问题和答案,但是简单的-1并不能为我提供改进的线索。我已经在MSDN和各种论坛上阅读了两个晚上的主题演讲,但没有发现我做错了什么。我试图通过编写说明问题的完整示例代码来尽可能地完善。
完整代码以供参考
#include <windows.h>
#include <CommCtrl.h>
#include <d2d1.h>
#pragma comment(lib,"comctl32.lib")
#pragma comment(lib,"d2d1.lib")
#define ID_STATUSBAR 1000
LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WParaM wParam,LParaM lParam);
class Graphics
{
ID2D1Factory* factory;
ID2D1Hwndrendertarget* rendertarget;
ID2D1SolidColorBrush* brush;
public:
Graphics()
{
factory = NULL;
rendertarget = NULL;
brush = NULL;
}
~Graphics()
{
if (factory) factory->Release();
if (rendertarget) rendertarget->Release();
if (brush) brush->Release();
}
bool Init(HWND windowHandle,HWND statusHandle);
void BeginDraw() { rendertarget->BeginDraw(); }
void EndDraw() { rendertarget->EndDraw(); }
void Resize(HWND windowHandle,HWND statusHandle);
void DrawCircle(float x,float y,float r);
};
HINSTANCE hInstance;
Graphics* gfx;
int WINAPI wWinMain(HINSTANCE hInstance,HINSTANCE,PWSTR pCmdLine,int nCmdshow)
{
InitCommonControls();
WNDCLASS wc = { };
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = TEXT("mainwindow");
RegisterClass(&wc);
HWND hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,TEXT("mainwindow"),TEXT("MainWindow"),WS_OVERLAPPEDWINDOW,100,800,600,hInstance,NULL);
if (!hWnd) return -1;
HWND hStatus = CreateWindowEx(0,NULL);
gfx = new Graphics;
if (!gfx->Init(hWnd,hStatus))
{
delete gfx;
return -1;
}
ShowWindow(hWnd,nCmdshow);
MSG message{ 0 };
bool runGame = true;
while (runGame)
{
while (PeekMessage(&message,PM_REMOVE))
{
TranslateMessage(&message);
dispatchMessage(&message);
if (message.message == WM_QUIT)
runGame = false;
}
gfx->BeginDraw();
gfx->DrawCircle(400.0f,100.0f,100.0f);
gfx->DrawCircle(400.0f,300.0f,500.0f,100.0f);
gfx->EndDraw();
}
return 0;
}
LRESULT CALLBACK WindowProc(HWND hWnd,LParaM lParam)
{
HWND hStatus;
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_SIZE:
case WM_SIZING:
hStatus = GetDlgitem(hWnd,ID_STATUSBAR);
gfx->Resize(hWnd,hStatus);
SendMessage(hStatus,0);
return 0;
}
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
bool Graphics::Init(HWND windowHandle,HWND statusHandle)
{
RECT rectwindow{ 0 },rectStatus{ 0 };
D2D1_SIZE_U rectRender{ 0 };
HRESULT res = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,&factory);
if (res != S_OK) return false;
GetClientRect(windowHandle,&rectwindow);
GetClientRect(statusHandle,&rectStatus);
rectRender.width = rectwindow.right;
rectRender.height = rectwindow.bottom - (rectStatus.bottom - rectStatus.top);
res = factory->CreateHwndrendertarget(
D2D1::rendertargetProperties(),&rendertarget);
if (res != S_OK) return false;
res = rendertarget->CreateSolidColorBrush(D2D1::ColorF(1,0),&brush);
if (res != S_OK) return false;
return true;
}
void Graphics::Resize(HWND windowHandle,HWND statusHandle)
{
if (rendertarget != NULL)
{
RECT rectwindow{ 0 },rectStatus{ 0 };
D2D1_SIZE_U rectRender{ 0 };
GetClientRect(windowHandle,&rectwindow);
GetClientRect(statusHandle,&rectStatus);
rectRender.width = rectwindow.right;
rectRender.height = rectwindow.bottom - (rectStatus.bottom - rectStatus.top);
rendertarget->Resize(rectRender);
}
}
void Graphics::DrawCircle(float x,float r)
{
brush->SetColor(D2D1::ColorF(1.0f,0.0f,1.0f));
rendertarget->DrawEllipse(D2D1::Ellipse(D2D1::Point2F(x,y),r,r),brush,1.0f);
}
解决方法
您可以将WS_CLIPCHILDREN
窗口样式添加到MainWindow
:
HWND hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,TEXT("mainwindow"),TEXT("MainWindow"),WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,100,800,600,NULL,hInstance,NULL);
或者,您可以创建另一个子窗口(同级到状态栏),并将其用于您的Direct2D
目标。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。