0

I'm looking for a solution to the following problem. I have 2 monitors, I want to find the second window on a certain monitor.

The reason I need the second window is because on that monitor I have a running application which is always on top and I don't need that window so the one after that.

Hiding and showing the topmost is not an option because this results in flickering.

Any help will be much appreciated.

Edit

Since it wasn't clear enough I will try to explain it a bit better.

I have 2 monitors, M1 and M2, where M1 is my main monitor. There is an application running that will always be topmost, this is an application I made myself.

I want to find the topmost window on M1 but ignore my own application. So the second one in line.

For more clarity, Youre making an application in delphi, when youre debugging your form will pop up but what I am looking for is that the HWND of RAD Studio is returned instead of your own form.

Hope its better to understand now.

P.s. David got what I meant with his last comment.

Community
  • 1
  • 1
Teun Pronk
  • 1,367
  • 12
  • 24
  • 1
    Use `GetWindow` passing `GW_HWNDFIRST` to get the top window, and then `GW_HWNDNEXT` to move down the z-order. – David Heffernan Jan 14 '15 at 09:50
  • @DavidHeffernan I looked at that but I dont know how this works on dual monitor, lets say I have a window focussed on my second monitor wont that be the second I will get? while I need the second window that is on monitor 1. – Teun Pronk Jan 14 '15 at 09:54
  • 1
    You'll get the windows on all the monitors. You then need to check whether a specific window is on the desired monitor. – David Heffernan Jan 14 '15 at 10:25
  • @Teun PLease [edit] your question, it is unclear. "I have 2 monitors, I want to find the second window on that monitor." There is no 'that monitor' in your question. Also, what does 'second window' mean? – Jan Doggen Jan 14 '15 at 10:42
  • @JanDoggen He wants to know which top-level window, that resides on a specific monitor, is second in the z-order. – David Heffernan Jan 14 '15 at 10:45

1 Answers1

0

If I understand your question correct, you might use womething like this:

TYPE
  TEnumParm = RECORD
                Monitor : TMonitor;
                ZOrder  : Cardinal;
                Handle  : HWND;
              PUBLIC
                CLASS FUNCTION Create(M : TMonitor ; Z : Cardinal) : TEnumParm; static;
                PROCEDURE   Initialize(M : TMonitor ; Z : Cardinal);
              END;
  PEnumParm = ^TEnumParm;

PROCEDURE TEnumParm.Initialize(M : TMonitor ; Z : Cardinal);
  BEGIN
    Monitor:=M; ZOrder:=Z; Handle:=0
  END;

CLASS FUNCTION TEnumParm.Create(M : TMonitor ; Z : Cardinal) : TEnumParm;
  BEGIN
    Result.Initialize(M,Z)
  END;

FUNCTION Enumerator(Handle : HWND ; Parm : PEnumParm) : BOOL; stdcall;
  VAR
    Rect    : TRect;

  BEGIN
    Result:=GetWindowRect(Handle,Rect);
    IF Result AND Parm^.Monitor.BoundsRect.IntersectsWith(Rect) THEN BEGIN
      DEC(Parm^.ZOrder);
      Result:=(Parm^.ZOrder>0);
      IF NOT Result THEN Parm^.Handle:=Handle
    END
  END;

FUNCTION FindWindowOnMonitor(M : TMonitor ; ZOrder : Cardinal = 1) : HWND;
  VAR
    P   : TEnumParm;

  BEGIN
    P.Initialize(M,ZOrder);
    EnumWindows(@Enumerator,LPARAM(@P));
    Result:=P.Handle
  END;

You may need to tweak the filtering done in the Enumerator function, depending on what precisely it is you are looking for (it's not entirely clear to me), but this will probably get you started on the right track.

HeartWare
  • 7,464
  • 2
  • 26
  • 30
  • Does EnumWindows enumerate respecting z order? – David Heffernan Jan 14 '15 at 12:40
  • According to what I have found on the net, yes. See http://stackoverflow.com/questions/295996/is-the-order-in-which-handles-are-returned-by-enumwindows-meaningful for example. It's not guaranteed, however, but for the usage needed here, I think it'll be all right to make that assumption. – HeartWare Jan 14 '15 at 12:42