1
votes

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.

================= EDIT =================

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.

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.

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

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

1
Rectangles use the current pen and the current BRUSH.BitBank
You can only draw on a window. You'll need a layered window (WS_EX_LAYERED) with the transparency key the same as the window background, see UpdateLayeredWindow().Hans Passant
@HansPassant Thanks, this is exactly what I needed.Josh

1 Answers

3
votes

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.

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.

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.