C++ GetPixel返回不正确的值

C++ GetPixel返回不正确的值,c++,getpixel,C++,Getpixel,这是我在这个论坛上的第一篇文章,如果我没有在正确的地方发表,或者如果我做错了什么,请不要对我太苛刻,我不经常在论坛上发表文章。所以,我有一个GetPixel函数的问题。基本上,它应该返回x,y处的颜色小数。我将要发布的代码在Windows7 32位上运行得非常好,但最近我买了一台新的笔记本电脑y50-70,带有Windows8.1 64位,同样的代码工作原理完全不同。我找不到任何解决问题的方法,甚至无法描述它。我认为它可能与桌面句柄、HDC、GetDC()、GetPixel()有关,甚至可能与我

这是我在这个论坛上的第一篇文章,如果我没有在正确的地方发表,或者如果我做错了什么,请不要对我太苛刻,我不经常在论坛上发表文章。所以,我有一个GetPixel函数的问题。基本上,它应该返回x,y处的颜色小数。我将要发布的代码在Windows7 32位上运行得非常好,但最近我买了一台新的笔记本电脑y50-70,带有Windows8.1 64位,同样的代码工作原理完全不同。我找不到任何解决问题的方法,甚至无法描述它。我认为它可能与桌面句柄、HDC、GetDC()、GetPixel()有关,甚至可能与我的计算机分辨率、刷新率或类似的东西有关。。。我甚至录制了一些视频,可以帮助你理解我遇到的问题,因为我甚至不能正确地描述它。这就像真正的颜色是x=219,y=407远离我的鼠标指向的地方。新的笔记本电脑已经使用了3周,我甚至试着做了1次系统恢复,但这并没有解决问题

请随意使用此代码,希望它能很好地为您服务:

#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);
}
#包括
#包括
使用名称空间std;
void Detect();
int main()
{
检测();
返回0;
}
void Detect()
{
p点;
HDC HDC=GetDC(0);
int x,y;
而(!GetAsyncKeyState(VK_INSERT))//按INSERT停止
{
GetCursorPos&p;
x=p.x;
y=p.y;
hDC=GetDC(0);

cout这可能是DPI缩放的问题

如果新显示器的每英寸点数高于平均值,则默认情况下,Windows将拉伸图形。默认情况下,Windows假定程序忽略DPI。如果Windows不拉伸图形,则未针对DPI进行调整的程序将在高密度显示器上的小窗口中显示微小文本

这有点像黑客。一些Windows API和消息允许您询问显示器和Windows,它们会在“平均值”之间转换坐标每英寸96像素,以及显示器的实际DPI值。同样,允许您调整大小的API会进行相反的转换。因此,这对程序来说基本上是透明的。但这并不完美,因为并非所有API都能以一致的方式进行缩放

所以我猜你的笔记本电脑有一个高分辨率显示器,GetPixel不会转换坐标进行DPI缩放,而鼠标位置会转换为DPI缩放。结果是你要求的像素与鼠标不对齐


我建议的解决方案是告诉windows您的程序“支持DPI”。有几种方法可以做到这一点。在您的情况下,最简单的方法可能是在程序开始时调用。您也可以通过在清单中标记程序来实现这一点。根据您使用的编译器,可能会有一个命令行选项来自动创建所需的清单。

这可能是DPI缩放

如果新显示器的每英寸点数高于平均值,则默认情况下,Windows将拉伸图形。默认情况下,Windows假定程序忽略DPI。如果Windows不拉伸图形,则未针对DPI进行调整的程序将在高密度显示器上的小窗口中显示微小文本

这有点像黑客。一些Windows API和消息允许您询问显示器和Windows,它们会在“平均值”之间转换坐标每英寸96像素,以及显示器的实际DPI值。同样,允许您调整大小的API会进行相反的转换。因此,这对程序来说基本上是透明的。但这并不完美,因为并非所有API都能以一致的方式进行缩放

所以我猜你的笔记本电脑有一个高分辨率显示器,GetPixel不会转换坐标进行DPI缩放,而鼠标位置会转换为DPI缩放。结果是你要求的像素与鼠标不对齐


我建议的解决方案是告诉windows您的程序“支持DPI”。有几种方法可以做到这一点。在您的情况下,最简单的方法可能是在程序开始时调用。您也可以在清单中标记您的程序。根据您使用的编译器,可能有一个命令行选项可以自动创建所需的清单。

另一种方法是rked对我来说,是更改控制面板中的设置,以禁用每个设备的DPI缩放。是否运行多个监视器

Win 8.1在控制面板中引入了一个新的设置,该设置表示“让我为所有显示选择一个DPI缩放”。通过解除此设置,此功能已关闭。打开它对我有效

查看此视频以查找设置:


我很好奇,所以当您不使用
SetProccesDPIAware()

时,让我知道这是否适用于您。另一个对我有效的替代方法是更改控制面板中的设置,禁用每个设备的DPI缩放。您正在运行多个监视器吗

Win 8.1在控制面板中引入了一个新的设置,该设置表示“让我为所有显示选择一个DPI缩放”。通过解除此设置,此功能已关闭。打开它对我有效

查看此视频以查找设置:


我很好奇,所以当您不使用
SetProccesDPIAware()时,请告诉我这是否适用于您

我认为这不是问题所在,但是您应该从循环外部删除
GetDC
,并将
ReleaseDC
移动到循环中。谢谢。我将向循环中添加ReleaseDC,我之所以在外部添加GetDC,是因为它未定义,使用VisualStudio 2013,但这不是主要问题的解决方案。我不要认为这是问题所在,但您应该从循环外部删除
GetDC
,并移动
ReleaseDC