-2

I am trying to get a windows position by it's handle. Then I want to draw a cross at the windows 0, 0 position like so (notepad is near the top-left of the display):

how it should look

but if I move notepad near the bottom right it looks like this:

enter image description here

That's totally weird for me. I've logged the values of rect.Left and rect.Top and compared them with the values of Spy++, they were the same.

What i've tried: from user32.dll:

GetWindowRect(handle, out var rect);

from dwmapi.dll:

DwmGetWindowAttribute(handle, DWMWINDOWATTRIBUTE.ExtendedFrameBounds, out var rect, size);

That worked a bit better, but still the same behaviour.

Someone knows a way to find the windows 0, 0 independently where the window is?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • Can we see the code where you draw the cross? And the actual numeric values from the rect in both of the cases shown? – 15ee8f99-57ff-4f92-890c-b56153 May 22 '19 at 14:45
  • 1
    What is the DPI awareness level of your program? – Raymond Chen May 22 '19 at 15:08
  • Here is the whole code https://pastebin.com/pzrufqaR (sorry its a bit unstructured but i think you can see how its drawn) The important part is in the Render method. Its drawn on a transparent windows form ( settings: BackColor: Black, FormBorderStyle: None, ShowIcon: false, ShowInTaskBar: false, TopMost: true, WindowState: Maximized) – Markus Gauwatz May 22 '19 at 15:11
  • GetWindowRect() tells a lot of appcompat lies. Start by declaring your app [to be dpiAware](https://stackoverflow.com/a/13228495/17034). Consider GetClientRect(). And consider to never need to do this. – Hans Passant May 22 '19 at 15:14
  • Okay it seems like it has nothing todo with GetWindowRect. when i draw with GDI on the Desktop (GetDC(IntPtr.Zero)) the cross fits perfectly on the top left corner. So it has something todo with directX drawing on a transparent fullscreen form. – Markus Gauwatz May 22 '19 at 21:45

2 Answers2

0

Direct3D uses the world coordinate system, and GetWindowRect gets a screen coordinate. That's the problem.

Draw Line with another method instead, such as, Graphics class:

Graphics g;
g = this.CreateGraphics();
Pen myPen = new Pen(Color.Red);
myPen.Width = 1;
g.DrawLine(myPen, point1x, point1y, point2x, point2y);

In addition, regardless of the problem, the code line in your link:

SetWindowLong(this.Handle, GWL_EXSTYLE,(IntPtr)(GetWindowLong(this.Handle, GWL_EXSTYLE) ^ WS_EX_LAYERED ^ WS_EX_TRANSPARENT));

if what you want is style additions, you should:

SetWindowLong(this.Handle, GWL_EXSTYLE,(IntPtr)(GetWindowLong(this.Handle, GWL_EXSTYLE) | WS_EX_LAYERED | WS_EX_TRANSPARENT));
Drake Wu
  • 6,927
  • 1
  • 7
  • 30
0

finally i found the Problem myself. i had to set the FormWindowState back to Normal and FormBorderStyle to None but not in the Designer but in the Method InitDevice at Top. Afterwards i set the Bounds of the Form to the Screen Bounds and that's it. Now it exactly works as expected.