Win32 Window 大约一分钟后不绘制
Win32 Window Doesn't Draw After minute or so
我的处境很棘手。
我在摆弄位图和 windows。
我遵循了这个教程:https://docs.microsoft.com/en-us/windows/win32/gdi/capturing-an-image
我基本上是拍摄多张桌面照片并将它们显示到 window。
它按预期工作得很好,但在大约一两分钟后,window 不会更新,我找不到错误或为什么会发生这种情况。
代码如下:
LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_DESTROY: {
PostQuitMessage(0); // Exit the program if the window gets closed.
} break;
case WM_SIZE: {
} break;
}
return DefWindowProc(hWnd, message, wParam, lParam); // Handle any messages the switch statement didn't
}
HWND SpawnWindow() {
WNDCLASSEX WindowClass;
SecureZeroMemory(&WindowClass, sizeof(WNDCLASSEX));
WindowClass.cbClsExtra = NULL;
WindowClass.cbWndExtra = NULL;
WindowClass.cbSize = sizeof(WNDCLASSEX);
WindowClass.style = CS_HREDRAW | CS_VREDRAW;
WindowClass.lpfnWndProc = WinProc;
WindowClass.hInstance = NULL;
WindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WindowClass.hIcon = LoadIcon(0, IDI_APPLICATION);
WindowClass.hIconSm = LoadIcon(0, IDI_APPLICATION);
WindowClass.hbrBackground = NULL;
WindowClass.lpszClassName = L"Class NAme";
WindowClass.lpszMenuName = L"Menu Name";
RegisterClassEx(&WindowClass);
return CreateWindowEx(NULL, L"Class Name", L"Window Title", WS_VISIBLE | WS_TILEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL);
}
void DoMessages() {
MSG msg = {};
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
std::cout << msg.message << "\n";
}
int main() {
HWND WindowToGetPic = SpawnWindow();
HDC DesktopDC = GetDC(0);
HDC WindowDC = GetDC(WindowToGetPic);
if (!DesktopDC)
std::cout << "DC NULL!\n";
HDC TempDC = CreateCompatibleDC(DesktopDC);
HDC TempDCWindow = CreateCompatibleDC(WindowDC);
if (!TempDC)
std::cout << "TempDC NULL!\n";
while (true) {
/*
after calling CreateCompatibleDC you mus then call CreateCompatiableBitmap with the DC recieved
then call SelectObject
*/
HBITMAP hBitmap = CreateCompatibleBitmap(TempDC, 1920, 1080);/* screen res */
SelectObject(TempDC, hBitmap);
SetStretchBltMode(TempDC, HALFTONE);
RECT WindowDimensions;
GetClientRect(WindowToGetPic, &WindowDimensions);
if (!BitBlt(WindowDC, 0, 0, WindowDimensions.right - WindowDimensions.left, WindowDimensions.bottom - WindowDimensions.top, DesktopDC, 0, 0, SRCCOPY))
std::cout << "BitBlt ERROR\n";
DoMessages();
InvalidateRect(WindowHwnd, NULL, TRUE);
}
std::cin.ignore();
return 0;
}
如果有人可以对此进行测试,或者找出为什么 window 在一两分钟后没有更新,我将不胜感激。
提前致谢!
我想你已经用光了所有的资源。
例如,
你每个周期都创建位图并且不释放它。
您调用了 SelectObject 并且没有return选择对象到原始状态。
您有几个资源泄漏:
当您处理完 GetDC
返回的 HDC 后,调用 ReleaseDC
当您处理完 CreateCompatibleDC
返回的 HDC 后,调用 DeleteDC
当您完成 hBitmap
后,select 将原始位图放回 DC 并调用 DeleteObject
。原始位图由SelectObject
.
返回
这些都包含在文档中(Google 会找到它)。
我的处境很棘手。
我在摆弄位图和 windows。
我遵循了这个教程:https://docs.microsoft.com/en-us/windows/win32/gdi/capturing-an-image
我基本上是拍摄多张桌面照片并将它们显示到 window。
它按预期工作得很好,但在大约一两分钟后,window 不会更新,我找不到错误或为什么会发生这种情况。
代码如下:
LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
case WM_DESTROY: {
PostQuitMessage(0); // Exit the program if the window gets closed.
} break;
case WM_SIZE: {
} break;
}
return DefWindowProc(hWnd, message, wParam, lParam); // Handle any messages the switch statement didn't
}
HWND SpawnWindow() {
WNDCLASSEX WindowClass;
SecureZeroMemory(&WindowClass, sizeof(WNDCLASSEX));
WindowClass.cbClsExtra = NULL;
WindowClass.cbWndExtra = NULL;
WindowClass.cbSize = sizeof(WNDCLASSEX);
WindowClass.style = CS_HREDRAW | CS_VREDRAW;
WindowClass.lpfnWndProc = WinProc;
WindowClass.hInstance = NULL;
WindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WindowClass.hIcon = LoadIcon(0, IDI_APPLICATION);
WindowClass.hIconSm = LoadIcon(0, IDI_APPLICATION);
WindowClass.hbrBackground = NULL;
WindowClass.lpszClassName = L"Class NAme";
WindowClass.lpszMenuName = L"Menu Name";
RegisterClassEx(&WindowClass);
return CreateWindowEx(NULL, L"Class Name", L"Window Title", WS_VISIBLE | WS_TILEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL);
}
void DoMessages() {
MSG msg = {};
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
std::cout << msg.message << "\n";
}
int main() {
HWND WindowToGetPic = SpawnWindow();
HDC DesktopDC = GetDC(0);
HDC WindowDC = GetDC(WindowToGetPic);
if (!DesktopDC)
std::cout << "DC NULL!\n";
HDC TempDC = CreateCompatibleDC(DesktopDC);
HDC TempDCWindow = CreateCompatibleDC(WindowDC);
if (!TempDC)
std::cout << "TempDC NULL!\n";
while (true) {
/*
after calling CreateCompatibleDC you mus then call CreateCompatiableBitmap with the DC recieved
then call SelectObject
*/
HBITMAP hBitmap = CreateCompatibleBitmap(TempDC, 1920, 1080);/* screen res */
SelectObject(TempDC, hBitmap);
SetStretchBltMode(TempDC, HALFTONE);
RECT WindowDimensions;
GetClientRect(WindowToGetPic, &WindowDimensions);
if (!BitBlt(WindowDC, 0, 0, WindowDimensions.right - WindowDimensions.left, WindowDimensions.bottom - WindowDimensions.top, DesktopDC, 0, 0, SRCCOPY))
std::cout << "BitBlt ERROR\n";
DoMessages();
InvalidateRect(WindowHwnd, NULL, TRUE);
}
std::cin.ignore();
return 0;
}
如果有人可以对此进行测试,或者找出为什么 window 在一两分钟后没有更新,我将不胜感激。
提前致谢!
我想你已经用光了所有的资源。 例如,
你每个周期都创建位图并且不释放它。
您调用了 SelectObject 并且没有return选择对象到原始状态。
您有几个资源泄漏:
当您处理完
GetDC
返回的 HDC 后,调用ReleaseDC
当您处理完
CreateCompatibleDC
返回的 HDC 后,调用DeleteDC
当您完成
返回hBitmap
后,select 将原始位图放回 DC 并调用DeleteObject
。原始位图由SelectObject
.
这些都包含在文档中(Google 会找到它)。