执行 pInvoke 并无法获得正确的 hDC

发布于 2024-09-15 21:09:17 字数 822 浏览 11 评论 0原文

因此,我试图获取正确的设备上下文,以便我可以在 N 显示器配置 (2+) 中的各个显示器上设置伽玛斜坡。

我已经尝试

[DllImport("gdi32.dll")]
static extern IntPtr CreateDC(string lpszDriver, string lpszDevice, string lpszOutput, IntPtr lpInitData);

过使用这种方法,我为 lpszDriver 使用字符串“DISPLAY”,我使用另一个 pInvoke 方法枚举显示器,并获取显示设备名称,最终类似于“\Registry\Machine\System\CurrentControlSet\” Control\Class{4d36e96e-e325-11ce-bfc1-08002be10318}\0042" 并作为 lpszDevice 传入。 lpszOutput 为 null,lpInitData 为 IntPtr.Zero。返回的 hDC 可以工作,但似乎是全局的。

通过

[DllImport("user32.dll")]
public static extern IntPtr GetDC(IntPtr hWnd);

这种方法,我尝试使用实际的窗口窗体句柄。

我正在使用

[DllImport("gdi32.dll")]
private static extern int SetDeviceGammaRamp(IntPtr hDC, ref RAMP lpRamp);

它确实设置了伽玛斜坡,但它总是设置两个显示器。 有什么想法吗?

So I'm trying to get the right Device Context so I can set the gamma ramp on individual monitors in an N monitor configuration (2+).

I've tried

[DllImport("gdi32.dll")]
static extern IntPtr CreateDC(string lpszDriver, string lpszDevice, string lpszOutput, IntPtr lpInitData);

With this method I'm using the string "DISPLAY" for lpszDriver, I'm enumerating displays with another pInvoke method and getting the Display device name which ends up being something like "\Registry\Machine\System\CurrentControlSet\Control\Class{4d36e96e-e325-11ce-bfc1-08002be10318}\0042" and passing in as lpszDevice. lpszOutput is null and lpInitData is IntPtr.Zero. The hDC that comes back works, but seems to be global.

and

[DllImport("user32.dll")]
public static extern IntPtr GetDC(IntPtr hWnd);

With this method I've tried using the actual window form handle.

I'm using

[DllImport("gdi32.dll")]
private static extern int SetDeviceGammaRamp(IntPtr hDC, ref RAMP lpRamp);

It does set the gamma ramp, but it always sets both monitors.
Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

陈独秀 2024-09-22 21:09:17

使用设备名称“DISPLAY”将为您提供整个显示系统的 DC,因此设置伽马斜坡(对于您的示例)会影响系统中的所有显示器。

您可以通过调用 EnumDisplayMonitors 检索每个显示器的 HMONITOR,然后使用 MONITORINFOEX 调用 GetMonitorInfo 来获取单个显示器的设备名称每个 HMONITOR 结构。 MONITORINFOEX 包含一个 szDevice 成员,您可以将其传递给 GetDC 以获取专门用于监视(驱动卡)的 DC,并设置 gamma它的坡道。

请注意,这实际上会为您提供显示器所连接的显卡的设备名称。如果内存正常,使用旧的硬件和/或软件,连接到同一张卡的两个显示器总是卡在相同的伽玛斜坡等。使用当前的硬件/软件,带有两个显示器的单张卡在系统看来就像两张卡(如果没记错的话,名称末尾带有“:0”或“:1”之类的内容),因此即使两个显示器连接到同一个物理卡,从设置伽玛斜坡的角度来看,它仍然被视为两个单独的显示器)。顺便说一句,我不确定到底需要多少新的硬件和/或软件才能将驱动多个显示器的单个物理卡视为多个虚拟卡。

Using the device name "DISPLAY" is getting you a DC for the whole display system, so setting the gamma ramp (for your example) affects all displays in the system.

You can get a device name for an individual monitor by calling EnumDisplayMonitors to retrieve an HMONITOR for each monitor, then GetMonitorInfo with a MONITORINFOEX structure for each HMONITOR. The MONITORINFOEX contains an szDevice member that you pass to GetDC to get a DC specifically for (the card driving) that monitor, and set the gamma ramp for it.

Note that this actually gets you a device name for the graphics card to which the monitor is attached. If memory serves, with older hardware and/or software, two monitors attached to the same card were always stuck with the same gamma ramp and such. With current hardware/software, a single card with two monitors will look to the system like two cards (with something like a ":0" or ":1" on the end of the name, if memory serves), so even if the two monitors are attached to the same physical card, from a viewpoint of setting the gamma ramp, it's still treated as two separate ones). Offhand, I'm not sure of exactly how new of hardware and/or software is needed to treat a single physical card driving multiple monitors as multiple virtual cards.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文