Делаю программу которая поверх целевого окна будет рисовать то что мне нужно,но когда я рисую,отрисовка идет не на те координаты,которые я указал.Более того,размер буфера почему то не соответствует тем параметрам которые я задаю.Так я инициализирую 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 вручную:
pRenderTarget->SetDpi(96, 96);
Либо же при инициализации:
pFactory->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_HARDWARE, D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),96,96),//D2D1_RENDER_TARGET_TYPE_DEFAULT
D2D1::HwndRenderTargetProperties(cheatEspHWND, D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top)),
&pRenderTarget);
Спасибо @Qwertiy за наводящий ответ.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Тема наследованиеЗадача -Разработать иерархическую структуру классов для обработки данных
Я много читал о том, как работать с потоками в QtКто-то наследуется от QThread и переопределяет void run();, кто-то наследует класс worker от QObject, связывает...