我正在制作一个程序,将在目标窗口顶部绘制我需要的东西,但是当我绘制时,绘图会转到我指定的错误坐标。此外,由于某种原因,缓冲区大小与我设置了。所以我初始化 d2d:
ID2D1Factory* pFactory;
ID2D1HwndRenderTarget* pRenderTarget;
ID2D1SolidColorBrush* ColorBrush;
bool init_render()
{
D2D1_FACTORY_OPTIONS CreateOpt = { D2D1_DEBUG_LEVEL_NONE };
if (S_OK != D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory), &CreateOpt, (void**)&pFactory))
{
MessageBox(0, "D2D1CreateFactory", "ERROR", MB_OK | MB_ICONERROR);
return 0;
}
create_canvas();
return 1;
}
void create_canvas()
{
RECT rc;
GetClientRect(targetHWND, &rc);
//std::cout<< rc.right - rc.left <<" "<< rc.bottom - rc.top<<std::endl;
pFactory->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_HARDWARE, D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED)),//D2D1_RENDER_TARGET_TYPE_DEFAULT
D2D1::HwndRenderTargetProperties(myHWND, D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top)),
&pRenderTarget);
pRenderTarget->CreateSolidColorBrush(color_brush, &ColorBrush);
}
我在循环中将窗口的大小调整为我们将在其上绘制的窗口的大小。当目标窗口大小发生变化时,我还会在窗口的消息处理程序中更改缓冲区大小:
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_SIZE:
if (pRenderTarget != NULL)pRenderTarget->Resize(D2D1::SizeU((UINT)LOWORD(lParam), (UINT)HIWORD(lParam)));
return 0;
case WM_SYSCOMMAND:
if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
}
但是如果你得到缓冲区的大小,那么它不等于我为它设置的大小,更准确地说,它不等于目标窗口的大小(以像素为单位):
void rect(float x,float y,float h,float w) {
D2D1_SIZE_F rtSize= pRenderTarget->GetSize();//получаем размер буфера
int width = static_cast<int>(rtSize.width);
int height = static_cast<int>(rtSize.height);
std::cout <<"Render target: "<< width<<" " << height << std::endl;//выводим размер буфера
ColorBrush->SetColor({0.0f,1.0f,0.0f,1.0f});
pRenderTarget->DrawRectangle(D2D1::RectF(x, y, x+h, y+w), ColorBrush,1.0f);//пробуем рисовать по заданным координатам
}
结果缓冲区的大小不合适,绘制的地方也不是我设置的,效果就好像我说要绘制的坐标(以像素为单位)大了一倍半(大约)。
我挖了一圈,找到了答案。原来,windows使用缩放,当用户设置一个大于100%的值时,系统dpi会发生变化。当我们创建directx上下文时,它默认使用系统dpi。设置手动 dpi(在我的情况下,你需要 100% 是水平和垂直 96dpi,因为我有方形像素),你必须
ID2D1RenderTarget在界面中手动设置 dpi:或在初始化时:
感谢@Qwertiy 的建议性回答。