Dan*_*l W 2 c++ multiple-monitors visual-studio visual-c++
基本上,我正在制作一些模仿屏幕融化效果的东西,但我只能让它在我的主显示器上运行。我已经尽可能多地查找了,在 GetDC 上只有一个论坛适用于所有显示器,但它没有用,它所做的只是从我的主显示器到我的辅助显示器制作一个矩形,效果仍然只适用于我的主显示器。这是我读到的线程:GetDC(NULL) gets Primary Monitor or virtual screen?
LRESULT CALLBACK Melter(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) {
switch (Message) {
case WM_CREATE: {
HDC Desktop = GetDC(HWND_DESKTOP);
HDC Window = GetDC(hWnd);
BitBlt(Window, 0, 0, ScreenWidth, ScreenHeight, Desktop, 0, 0, SRCCOPY);
ReleaseDC(hWnd, Window);
ReleaseDC(HWND_DESKTOP, Desktop);
SetTimer(hWnd, 0, Interval, 0);
ShowWindow(hWnd, SW_SHOW);
break;
}
case WM_PAINT: {
ValidateRect(hWnd, 0);
break;
}
case WM_TIMER: {
HDC Window = GetDC(hWnd);
int uX = (rand() % ScreenWidth) - (150 / 2), uY = (rand() % 15), Width = (rand() % 150);
BitBlt(Window, uX, uY, Width, ScreenHeight, Window, uX, 0, SRCCOPY);
ReleaseDC(hWnd, Window);
break;
}
case WM_DESTROY: {
KillTimer(hWnd, 0);
PostQuitMessage(EXIT_SUCCESS);
break;
}
return EXIT_SUCCESS;
}
return DefWindowProc(hWnd, Message, wParam, lParam);
}
Run Code Online (Sandbox Code Playgroud)
我更改的行是HDC Window = GetDC(Window) to HDC Window = GetDC(NULL)
然后是其他一些内容,例如RECT
. 如果有人能帮助我那就太好了,谢谢:)
PS,ScreenWidth = 3600,ScreenHeight = 1080,而PMScreenWidth = 1920,PMScreenHeight = 1080。PM与主显示器一样,所以我将该函数中的所有内容设置为ScreenWidth/ScreenHeight,因此它是所有显示器的宽度/高度。但仍然不起作用。
GetDC(HWND_DESKTOP)
(与 相同GetDC(0)
)已返回所有监视器的 DC。上面代码的问题主要在于BitBlt
坐标的使用和选择。请参阅下面解决该问题的 MCVE。
不要响应 进行绘制WM_CREATE
,它只会在WM_PAINT
背景被擦除时被擦除。
不要打电话ValidateRect
回应WM_PAINT
。如果您想擦除窗口,则只需使用FillRect
,或从命令或其他路径强制重新绘制。
使用GetSystemMetrics(SM_CXVIRTUALSCREEN)
和GetSystemMetrics(SM_CYVIRTUALSCREEN)
返回虚拟监视器的宽度和高度。
还要确保该进程能够识别 DPI。SetProcessDPIAware();
为了进行测试,您可以在程序开始时调用。理想情况下,DPI 感知应在清单文件中设置。
Run Code Online (Sandbox Code Playgroud)int uX = (rand() % ScreenWidth) - (150 / 2); int uY = (rand() % 15); int Width = (rand() % 150); BitBlt(Window, uX, uY, Width, ScreenHeight, Window, uX, 0, SRCCOPY);
上面的代码是将客户端 DC 中的位复制到同一客户端 DC,它不会执行任何操作。大概您想要从桌面 DC 复制到客户端 DC。
而且,坐标基本上是随机选取的。它假设主显示器位于左上角。如果uX
大于窗口自身的宽度,则不会被复制,除非窗口拉伸整个虚拟监视器。
LRESULT CALLBACK Melter(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) {
switch(Message)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
auto hdc = BeginPaint(hWnd, &ps);
RECT rc;
GetClientRect(hWnd, &rc);
HDC hdesktop = GetDC(0);
int screenx = GetSystemMetrics(SM_XVIRTUALSCREEN);
int screeny = GetSystemMetrics(SM_YVIRTUALSCREEN);
int screenw = GetSystemMetrics(SM_CXVIRTUALSCREEN);
int screenh = GetSystemMetrics(SM_CYVIRTUALSCREEN);
StretchBlt(hdc, 0, 0, rc.right, rc.bottom,
hdesktop, screenx, screeny, screenw, screenh, SRCCOPY);
ReleaseDC(0, hdesktop);
EndPaint(hWnd, &ps);
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, Message, wParam, lParam);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4894 次 |
最近记录: |