我正在尝试编写一个没有窗户的蛇游戏,但冻结前景并在其上方绘制蛇。当游戏结束时,前景应该解冻。
我已经编写了一些测试代码,它应该在前景上绘制一个正方形,但它似乎只是将桌面冻结一秒钟并将窗口冻结在前景中,直到我最小化,最大化,关闭它,或者将另一个窗口带入前景,它不会绘制任何东西。在代码中,我尝试存储桌面的位图,以便我可以基本上将其重置为原始状态并将方块绘制在不同的位置。有人能用我的代码发现问题吗?
//Handle to the desktop window
HWND hDesktopWindow = GetDesktopWindow();
//Lock the window to prevent other applications drawing on it
if(!LockWindowUpdate(hDesktopWindow)){
return 1;
}
//Calling GetDC with argument NULL retrieves the desktop's DC
HDC hdcDesktop = GetDCEx(hDesktopWindow, NULL, DCX_CACHE | DCX_LOCKWINDOWUPDATE);
//Create a compatible DC to allow us to store a bitmap of the desktop
HDC hdcCompatible;
if((hdcCompatible = CreateCompatibleDC(hdcDesktop)) == NULL){
return 1;
}
//Create a compatible bitmap with the same dimensions as the desktop
HBITMAP hScrBitmap;
int cx = GetSystemMetrics(SM_CXSCREEN);
int cy = GetSystemMetrics(SM_CYSCREEN);
if((hScrBitmap = CreateCompatibleBitmap(hdcDesktop, cx, cy)) == NULL){
return 1;
}
//Select the bitmap into the compatible DC
SelectObject(hdcCompatible, hScrBitmap);
//Copy the Desktop into the bitmap
if(!BitBlt(hdcCompatible, 0, 0, cx, cy, hdcDesktop, 0, 0, SRCCOPY)){
return 1;
}
//Create a DC compatible with the bitmaps DC for drawing the rectangle
HDC hdcRectangle;
if(!CreateCompatibleDC((HDC)hScrBitmap)){
return 1;
}
//Create a compatible bitmap for the rectangle to be drawn in
HBITMAP hRectangleBitmap;
if(!CreateCompatibleBitmap(hdcRectangle, 100, 100)){
return 1;
}
//Fill the rectangle bitmap
if(!FloodFill(hdcRectangle, 0, 0, RGB(255,0,0))){
return 1;
}
//Copy the rectangle onto the desktop bitmap
if(!BitBlt(hdcCompatible, 100, 100, 100, 100, hdcRectangle, 0, 0, SRCCOPY)){
return 1;
}
//Copy the bitmap onto the actual desktop
if(!BitBlt(hdcDesktop, 0, 0, cx, cy, hdcCompatible, 0, 0, SRCCOPY)){
return 1;
}
//Allow time to view the result
Sleep(1000);
//Allow other applications to draw on the desktop again
LockWindowUpdate(NULL);
//Cleanup
ReleaseDC(hDesktopWindow, hdcDesktop);
DeleteDC(hdcCompatible);
DeleteObject(hScrBitmap);
非常感谢任何帮助:)
答案 0 :(得分:4)
尝试在桌面上直接执行此操作将会出现问题。通过拍摄桌面快照,然后创建一个与整个桌面大小相同的窗口,将快照复制到窗口,并在那里完成所有绘图,你会感觉更好。 (这是在旧版屏幕保护程序中执行的常见技巧,它可以“侵蚀”桌面。)
您不拥有桌面窗口,因此您始终会遇到无效和重新绘制的问题。
答案 1 :(得分:2)
if(!CreateCompatibleDC((HDC)hScrBitmap)){
return 1;
}
当你编写像这样的C代码时,单点返回往往非常重要。像这样的调用将返回FALSE,无法将HBITMAP强制转换为HDC,并且节目结果非常糟糕。没有诊断,也没有再次解锁的电话。
支持C ++ RAII模式以确保始终解锁:
class DesktopLocker {
public:
DesktopLocker() { LockWindowUpdate(GetDesktopWindow()); }
~DesktopLocker() { LockWindowUpdate(NULL); }
};
void foo() {
DesktopLocker lock;
// etc...
}
没有太多的智慧直接绘制到桌面窗口,几乎没有保证你画的任何东西都会持续。睡眠和锁定更新只是创可贴。看看source of Rainmeter,它做得很好。