开发者

Windows Client graphics written off the window to upper-left of screen

开发者 https://www.devze.com 2023-01-31 12:53 出处:网络
I have a Windows WinMain() window in which I write simple graphics -- merely LineTo() and FillRect().The rectangles move around.After about an hour, the output that used o go to the main window, all o

I have a Windows WinMain() window in which I write simple graphics -- merely LineTo() and FillRect(). The rectangles move around. After about an hour, the output that used o go to the main window, all of a sudden goes to the upper left corner of my screen -- as if client coordinates were being interpreted as screen coordinates. My GetDC()'s and ReleaseDC()'s seem to be balanced, and I even checked the return value from ReleaseDC(), make sure it is not 0 (per MSDN). Sometime开发者_开发知识库s the output moves back to my main window. When I got to the debugger (VS 2010), my coordinates do not seem amiss--but output is going to the wrong place. I handle WM_PAINT, WM_CREATE, WM_TIMER, and a few others. I do not know how to debug this. Any help would be appreciated.


This has 'not checking return values' written all over it. Pretty crucial in raw Win32 programming, most every API function returns a boolean or a handle where FALSE or NULL indicates failure. GetLastError() provides the error code.

A cheap way to check for this without modifying code is by using the debugger to look at the EAX register value after the API call. A 0 indicates failure. In Visual Studio you can do so by using the @eax and @err pseudo variables in the Watch window, respectively the function return value and the GetLastError value.

This goes bad once Windows starts failing API calls, probably because of a resource leak. You can see it with TaskMgr.exe, Processes tab. View + Select Columns and tick Handles, USER objects and GDI objects. It is usually the latter, restoring the device context and releasing drawing objects is very easy to fumble. You don't have to wait until it fails, a steadily climbing number in one of those columns is the giveaway. It goes belly-up when the value hits 10,000


You must be calling GetDC(NULL) somewhere by mistake, which would get the DC for the entire desktop.

You could make all your GetDC calls call a wrapper function which asserts if the argument is NULL to help track this down:

#include <assert.h>
HDC GetDCAssert(HWND hWnd)
{
    assert(hWnd);
    return ::GetDC(hWnd);
}
0

精彩评论

暂无评论...
验证码 换一张
取 消