【问题标题】:Creating a window-relative DeviceContext on multiple monitors在多个监视器上创建与窗口相关的 DeviceContext
【发布时间】:2016-10-19 12:16:11
【问题描述】:

我正在研究一个旧版 (1999) 代码库,该代码库有一个烦人的错误,即当窗口放置在非主监视器上时,滚动某些 GUI 元素时无法正确重绘。

据我所知(对 Windows 的 API 不是很熟悉),问题是代码获取 DeviceContext 以使用 GetDC(hwnd) 绘制,我可以从文档中获得 DC 用于仅主监视器(但文档不是很清楚,TBH)。

我已经设法在屏幕上画了东西,基本上使用:

RECT rect;
GetWindowRect(hwnd, &rect);
HMONITOR monitor = MonitorFromRect(&rect, MONITOR_DEFAULTTOPRIMARY);
MONITORINFOEX minfo;
minfo.cbSize = sizeof(MONITORINFOEX);
GetMonitorInfo(monitor, &minfo);
HDC = CreateDC(NULL, minfo.szDevice, NULL, NULL);

这会将内容绘制到正确的监视器上,但应用程序显然需要与窗口相关的内容,因为所有内容最终都位于桌面的左上角而不是窗口中。

现在,我的谷歌搜索似乎表明使用 EnumDisplayMonitors(GetDC(), &rect, PaintCallback, NULL) 运行两次绘制代码应该是正确的。不幸的是,我的代码不是 C 或 C++。这是一个 SmallTalk 图像(并且支持在 15 年前左右就结束了,所以向供应商抱怨已经结束了),我只是不确定绘画处理是否发生在我可以访问的代码中,或者它是否足够深入我无法理解的 SmallTalk 的胆量。

因此我的问题是:是否可以创建一个与我的窗口客户区相关的 DC(也许通过从 CreateDC 调整 DC)?我意识到如果窗口跨越两个监视器,这可能会中断,但至少比当前状态要少。

更新:

我已经成功地使用EnumDisplayMonitors 运行了两次渲染代码,但是以奇怪的方式崩溃(这很可能是 SmallTalk 问题;编译器是旧的并且是特殊的,但是在堆栈深处调试代码是有问题)。

回答cmets:我认为代码基本上是想在windows上绘制,是的。代表各种 GUI 元素的 SmallTalk 对象带有用于创建带有GetDC(hwnd) 的 DC 的窗口句柄,所以这很容易。所以听起来GetDC(hwnd)应该得到一个做正确事情的 DC,在这种情况下;可能是 ST 代码在某处缓存 DC,GetDC 将在窗口移动到不同屏幕时返回不同的 DC(从我粗略的了解来看,这听起来似乎是合理的)。

【问题讨论】:

  • 看起来你想在某个窗口上画画。使用 FindWindow 获取窗口句柄,或使用 Visual Studio 中的 Spy++ 实用程序查找窗口句柄。创建 DC:HDC hdc = GetDC(hwnd),完成后调用 ReleaseDC(hwnd, hdc)。但这当然是一种廉价的黑客攻击,您的图纸将很快被删除。为什么不通过创建自己的窗口来正确地做到这一点?
  • 我认为问题与 GetDC 本身无关。也许还有一些代码使用 GetClientRect/GetWindowRect 并且坐标是以某种方式相对于主屏幕获取的。

标签: windows winapi gdi


【解决方案1】:

看起来问题确实出在GetDC 创建的 DC 的缓存上。我破解了渲染代码以不使用缓存(或多或少,代码有点纠结),乍一看,它似乎成功了。

对于后代,如果有人在谷歌上搜索 Visual Smalltalk Enterprise 并找到这个答案,我所做的是编辑 GraphicsTool>>ifNilHandle: 以不实际检查句柄是否为 nil,但始终运行块以获得新句柄并返回最后是真的。这样,每次都会获取新的 DC。

更新:

这解决了我试图解决的直接问题,但不幸的是破坏了其他一些东西(最著名的是 WindowBuilder Pro,GUI 构建工具包)。问题显然是代码中某处过于急切地缓存 DC,但它需要以比上述大锤方法更集中的方式进行修复。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-09
    • 2021-11-09
    • 2014-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多