0

I am trying to get the position of another processes main window. This is the code I have right now:

[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string className, string windowName);

[DllImport("user32.dll")]
private static extern int GetWindowRect(IntPtr hwnd, out Rectangle rect);


private void UpdatePosition()
{
    IntPtr windowHandle = new IntPtr();
    Process[] processes = Process.GetProcessesByName("Player");
    try
    {
        windowHandle = processes[0].MainWindowHandle;
    }
    catch //Player.exe is not open
    {
        Application.Exit();
        return;
    }

    Rectangle rect;
    GetWindowRect(windowHandle, out rect);
    Location = new Point(rect.X, rect.Y);
}

private void timer1_Tick(object sender, EventArgs e)
{
    UpdatePosition();
}

For some reason, the position of rect is always the middle of my screen (960, 540).
I have no clue why this happens, am I doing something wrong?

Yek
  • 1
  • What happens if you pass RECT struct to the function? -- Anyway, try the `GetWindowRectangle()` you find here [Move window when external application's window moves](https://stackoverflow.com/a/48812831/7444103), it uses `DwmGetWindowAttribute()`, which is Dpi Aware, while `GetWindowRect()` is not. The RECT struct has a `ToRectangle()` method, in case it's needed. – Jimi Aug 12 '22 at 02:57
  • Maybe because "Player" (whatever that is) main window (whatever that is) is always at the middle of your screen? ie: are you sure there's no window from player that is considered the main? – Simon Mourier Aug 12 '22 at 07:01
  • .NET devs just *love* convenience, much more than correctness. Microsoft have listened, and that's what the .NET framework implements: `MainWindowHandle` is a lie. It's a guess, sourced from opaque heuristics, unreliable, and should really be dumped. The [documentation](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.mainwindowhandle) hints to this, suggests workarounds, and finally closes with recommendations that are completely wrong. I pity anyone who assumes this were a useful API. – IInspectable Aug 12 '22 at 11:03
  • @SimonMourier Player has no other window – Yek Aug 12 '22 at 14:54
  • How have you checked? Have you checked this window's rect? Maybe this window is not really used by the Player application. – Simon Mourier Aug 12 '22 at 15:14
  • @Jimi Still did not work, I think I am just going to give up on using the API and do something else – Yek Aug 12 '22 at 15:20
  • @SimonMourier I have a decompiled version of the Player.exe lol – Yek Aug 12 '22 at 15:20
  • Difficult to say w/o a reproducing project. Try processes[0].Refresh() before getting the window handle – Simon Mourier Aug 12 '22 at 15:22
  • 1
    You should compare the Handle you get from the Process class with what e.g., Spy++ or Inspect tell you about that Window -- Also test a Process object generated by the process ID (i.e., `GetProcessById()`), if you're sure that the application has only one Process (or you know what Process owns the Window). Also test `EnumWindows()` directly (this is used by the Process class to get the handle of the *main* Window, but you can do that on your terms - and with your own *eyes*). UI Automation can also find all top-level Windows that have a Handle. Compare with `GetWindowThreadProcessId()`. – Jimi Aug 12 '22 at 15:47

0 Answers0