2012-05-06 156 views
4

我想在Windows中獲取光標圖標。 我覺得語言我用的是不是在這裏非常重要,所以我只寫與WinAPI的功能,我想用僞代碼:WinAPI獲取鼠標光標圖標

c = CURSORINFO.new(20, 1, 1, POINT.new(1,1)); 
GetCursorInfo(c); #provides correctly filled structure with hCursor 

DrawIcon(GetWindowDC(GetForegroundWindow()), 1, 1, c.hCursor); 

所以這部分工作得很好,它吸引光標當前活動窗口。 但這不是我想要的。我想獲得一組像素,所以我應該在內存中繪製它。

我試圖做這樣的:

hdc = CreateCompatibleDC(GetDC(0)); #returns non-zero int 
canvas = CreateCompatibleBitmap(hdc, 256, 256); #returns non-zero int too 

c = CURSORINFO.new(20, 1, 1, POINT.new(1,1)); 
GetCursorInfo(c); 

DrawIcon(hdc, 1, 1, c.hCursor); #returns 1 
GetPixel(hdc, 1, 1); #returns -1 

爲什麼不GetPixel()返回COLORREF?我錯過了什麼?

我對WinAPI不太瞭解,所以我可能會犯一些愚蠢的錯誤。

回答

4

您必須選擇您在設備上下文中創建的位圖。如果不是,則GetPixel function將返回CLR_INVALID(0xFFFFFFFF的):

位圖必須在設備範圍內進行選擇,否則,CLR_INVALID對所有像素返回。

此外,您顯示的僞代碼嚴重泄漏對象。無論何時您致電GetDC,當您完成使用時,您的必須請致電ReleaseDC。而且,無論何時創建GDI對象,在完成使用時都必須銷燬它。

最後,您似乎假定原點 - 即左上點 - 的座標爲(1,1)。他們實際上是(0,0)。

下面是我寫的代碼(檢查略去了錯誤):

// Get your device contexts. 
HDC hdcScreen = GetDC(NULL); 
HDC hdcMem = CreateCompatibleDC(hdcScreen); 

// Create the bitmap to use as a canvas. 
HBITMAP hbmCanvas = CreateCompatibleBitmap(hdcScreen, 256, 256); 

// Select the bitmap into the device context. 
HGDIOBJ hbmOld = SelectObject(hdcMem, hbmCanvas); 

// Get information about the global cursor. 
CURSORINFO ci; 
ci.cbSize = sizeof(ci); 
GetCursorInfo(&ci); 

// Draw the cursor into the canvas. 
DrawIcon(hdcMem, 0, 0, ci.hCursor); 

// Get the color of the pixel you're interested in. 
COLORREF clr = GetPixel(hdcMem, 0, 0); 

// Clean up after yourself. 
SelectObject(hdcMem, hbmOld); 
DeleteObject(hbmCanvas); 
DeleteDC(hdcMem); 
ReleaseDC(hdcScreen); 

但最後一個警告 - 該DrawIcon function可能並不像你期望的工作。它僅限於以默認大小繪製圖標或光標。在大多數系統上,這將是32x32。從文檔:

DrawIcon使用圖標的系統度量值指定的寬度和高度繪製圖標或光標;欲瞭解更多信息,請參閱GetSystemMetrics

相反,您可能要使用DrawIconEx function。以下代碼將以資源的實際大小繪製光標:

DrawIconEx(hdcMem, 0, 0, ci.hCursor, 0, 0, 0, NULL, DI_NORMAL);