使用类似于 Inspect 的 GDI+(或 GDI)在屏幕上绘图

问题描述:

我正在尝试使用 GDI+ 在屏幕上(整个屏幕,在所有其他窗口的顶部)进行绘制.
我已将 NULL 传递给 GetDC 以将 HDC 传送到屏幕,然后使用它创建一个 Graphics 对象,并使用 DrawRectangle 在屏幕上绘制矩形.
一切正常......除了......矩形的内部不会更新.

I'm trying to draw on the screen (the whole screen, on top of every other window) using GDI+.
I've passed NULL to GetDC to get a HDC to the screen, and then used that to create a Graphics object, and used DrawRectangle to draw rectangles on the screen.
Everything works..except...the inside of the rectangle won't update.

就像我在命令提示符上绘制它并移动命令提示符一样,矩形的内部仍然是黑色的.我希望看到矩形下面是什么.

Like if I draw it over a command prompt, and move the command prompt, the inside of the rectangle remains black. I expect to see whats under the rectangle.

这是进行绘图的代码..

Here's the code that's doing the drawing..

Pen BluePen(Color(255, 0, 255, 0), 2);
Graphics graphics(screenDC);
graphics.DrawRectangle(&BluePen, myRect);

很简单,那么我需要做些什么才能在屏幕显示时更新矩形的内部?或者让它真正透明.

Pretty simple, so is there something I have to do to get the inside of the rectangle to update when the screen does? Or to get it truely transparent.

================= 编辑 ==================

好吧,我已经放弃了,并认为这是不可能的,直到……我意识到 Windows SDK 附带的 Inspect 工具可以完美地做到这一点.

Well I had given up on this, and assumed it wasn't possible, until...I realized the Inspect tool that comes with the Windows SDK does this perfectly.

我想重新创建类似于高亮矩形的东西,如果我选择一个窗口(例如 Firefox),然后将 Inspect 置于焦点上,我可以自由地移动它并完美更新所有内容.甚至没有任何闪烁.

I would like to recreate something similar to the highlight rectangle, and if I select a window (such as Firefox) and then bring Inspect into focus I can move it around freely with everything being updated perfectly. There's not even any flickering.

那么……有人知道 Inspect 是如何做到这一点的吗?

So...does anyone know how Inspect manages to do this?

在 GDI 而不是 GDI+ 中的答案也很好...

Also answers in GDI instead of GDI+ are fine...

在 windows 中,屏幕(和 windows ...)表面是 ... 易变的,就像沙箱一样.窗户的重叠"和未覆盖表面的重新粉刷是由适当的事件管理造成的错觉.

In windows the screen (and the windows ...) surface(s) are ... volatile, like sandboxes. The "overlapping" of windows and the re-painting of uncovered surfaces is an illusion made by proper event management.

所有被绘制的东西都留在那里,直到有其他东西被绘制在它上面.揭开"表面使代表该表面的窗口接收 WM_PAINT 消息.由该窗口过程通过重新绘制所有应该在其下的内容来对该消息做出反应.

Everything is drawn remain there until something else is drawn over it. "Uncovering" a surface makes the window representing that surface to receive a WM_PAINT message. It's up to that window procedure to react to that message by re-painting everything is supposed to be under it.

现在,除非您以某种方式拦截发送到桌面窗口的 WM_PAINT 消息,否则您几乎没有机会知道桌面需要重绘,因此不会调用您的绘画代码,也不会发生重绘.或者更好的是它只发生在桌面窗口更新代码之后,它不知道你的油漆.

Now, unless you intercept somehow the WM_PAINT message that is sent to the desktop window, you have mostly no chance to know the desktop needs a repaint and hence your paint code will not be called and no repaint will happen. Or better it happens following just the desktop window updating code, that's not aware of your paint.