2015-04-16 109 views
2

這是我在這個論壇上的第一篇文章,如果我沒有發佈在正確的地方或者如果我做錯了什麼,請不要在論壇上發帖許多。所以,我有GetPixel函數的這個問題。基本上,它應該返回x,y處的顏色小數。我即將發佈的代碼在Windows 7 32bit上完美工作,但最近我購買了新的筆記本電腦y50-70與Windows 8.1 64位和相同的代碼完全不同。我找不到解決問題的辦法,甚至無法形容。我認爲這可能與桌面處理,HDC,GetDC(),GetPixel(),甚至與我的電腦分辨率,刷新率或類似的東西有關......我甚至錄製了一些視頻,可以幫助您瞭解我遇到的問題,因爲我甚至無法正確描述它。它就像真正的顏色是x = 219,y = 407遠離我的鼠標指向的地方。新的筆記本電腦是3周大,我甚至試圖做系統恢復1次,但這並沒有解決問題。GetPixel返回不正確的值

隨意使用此代碼,希望它會正常工作對您:

#include <iostream> 
#include <Windows.h> 
using namespace std; 

void Detect(); 

int main() 
{ 
    Detect(); 

    return 0; 
} 

void Detect() 
{ 
    POINT p; 
    HDC hDC = GetDC(0); 
    int x, y; 

    while (!GetAsyncKeyState(VK_INSERT)) // Press insert to stop 
    { 
     GetCursorPos(&p); 
     x = p.x; 
     y = p.y; 
     hDC = GetDC(0); 
     cout << x << " " << y << " " << GetPixel(hDC, x, y) << endl; 
     Sleep(50); 
    } 
    ReleaseDC(0, hDC); 
} 

鏈接下面的問題: https://youtu.be/q2H2M8WLHVI

如果任何人都可以至少幫助好歹告訴什麼要去哪裏,我會非常非常欣賞它。我開始編程的主要原因之一是因爲類似的東西,使用顏色,條件等......現在我不能進一步提高,這真的很難過。希望聽到回覆。謝謝。

+0

我不認爲這是這個問題,但你應該從循環外部移除'GetDC'並將'ReleaseDC'移到循環中。 –

+0

謝謝。我會將ReleaseDC添加到循環中,並且爲什麼我在外部添加GetDC的原因是因爲它是未定義的,使用VisualStudio 2013,但這不是主要問題的解決方案。 –

回答

3

這可能是DPI縮放問題。

如果您的新顯示器的每英寸點數高於平均值,則默認情況下,Windows會拉伸圖形。默認情況下,Windows假定程序忽略DPI。如果Windows沒有拉伸圖形,那麼沒有針對DPI進行調整的程序會在高密度顯示器上的小窗口中顯示小文本。

這是一個黑客。一些Windows API和消息可以讓你詢問顯示器和窗口,將平均值轉換爲每平方英寸96像素和實際DPI顯示器之間的座標。同樣,允許您調整大小的API也會進行相反的轉換。所以這對程序來說基本上都是透明的。但這並不完美,因爲並不是所有的API都能以一致的方式進行縮放。

所以我的猜測是你的筆記本電腦有一個高分辨率的顯示器,GetPixel不轉換座標DPI縮放,並且鼠標位置轉換爲DPI縮放。結果就是你要求一個像素不符合鼠標。

我建議的解決方案是告訴你的程序是「DPI感知」的窗口。有幾種方法可以做到這一點。您的案例中最簡單的方法是在程序開始時撥打SetProcessDPIAware。你也可以這樣做,在清單中標記你的程序。根據您使用的編譯器,可能會有一個命令行選項來自動創建您需要的清單。

+0

非常感謝! SetProcessDPIAware()解決了它!我在main()函數中包含了這個函數,希望沒關係。無論如何,我可以評價你的文章作爲答案?只是想再次表示感謝。 :) –

+0

由於DPI虛擬化,如果一個應用程序查詢另一個具有DPI相關信息的不同感知級別,系統將自動縮放值以匹配調用者的感知級別。其中一個例子是如果您調用GetWindowRect並傳遞由另一個應用程序創建的窗口。使用上述情況,假設PROCESS_DPI_UNAWARE應用程序在顯示器C上創建了一個500乘500的窗口。如果您從另一個應用程序查詢窗口矩形,則矩形的大小將根據應用程序的DPI感知而變化。來自:http://bit.ly/1RpUnHx – mikew

+0

@mikew:我不確定你想要做什麼。這裏沒有應用程序間通信。 Sakire Sileteik正在使用的兩個API中只有一個應用縮放。 –

0

對我而言,另一種替代方法是更改​​控制面板中的設置,以禁用每臺設備的DPI縮放。你正在運行多臺顯示器?

Win 8.1在控制面板中引入了一個新設置,其中顯示「讓我選擇一個DPI縮放比例爲全部顯示」。通過defualt這是關閉。打開它已經爲我工作。

看到這部影片找到設置: https://www.youtube.com/watch?v=sE3IUTPy1WA

我很好奇,所以讓我知道是否適合你,當你不使用SetProccesDPIAware()