1

I need to write application A, which intercepts the WM_ACTIVATE message to a window of application B in order to prevent B from becoming top-most application.

Is it possible to do this without DLL injection (add a hook on that message, process and "neutralize" it with a series of WinAPI calls) ?

Glory to Russia
  • 17,289
  • 56
  • 182
  • 325
  • 1
    Well, you can crack it if that's acceptable solution. Replace WM_ACTIVATE value with some WM_USER + something. – user1764961 May 14 '13 at 12:55
  • @user1764961 Thanks. Which functions can I use to do the replacement? – Glory to Russia May 14 '13 at 12:58
  • 1
    Is this some form of arms race? Will application B be updated to detect application A and stop it from performing the interception? – Damien_The_Unbeliever May 14 '13 at 13:51
  • Actually you don't need any "functions" here. Disassemble the code, find the window proc and locate code for handling the WM_ACTIVATE message. Instead of WM_ACTIVATE (0x6) put some WM_USER value (e.g. 0x7400). Or try modifying the memory location or register holding the WM_ACTIVATE value... There is no only one solution here. It depends on the code. – user1764961 May 14 '13 at 13:53
  • Are you saying App B is actually setting top-most when it becomes activated, or are you simply trying to activate it without making come to the foreground? Top-most is usually set as a style on the window itself, not usually applied when it becomes active, kinda redundant in most cases as the window will be on top because of activation. – Joel Lucsy May 14 '13 at 14:06
  • @Damien_The_Unbeliever Application B is an old application with ugly UI and no automation layer (i. e. I can't access its functionality via an API). Application A is a GUI application, which allows the user to operate application B (as well as several others) via a unified user interface. At the start, A launches B and all other integrated apps. The user interacts with A only and B (and other integrated apps) should not be visible. This works most of the time, but in one app some actions (like programmatically enter a text into a text box) lead to the app becoming visible (hiding A). – Glory to Russia May 14 '13 at 14:09
  • @JoelLucsy No, it's not topmost, but it gets overlaid over A (B hides a large portion of A's screen real estate). – Glory to Russia May 14 '13 at 14:10
  • If B handles the showcmd correctly, you could edit wShowWindow of the [startupinfo struct](http://msdn.microsoft.com/en-us/library/windows/desktop/ms686331(v=vs.85).aspx) you pass to createprocess. – typ1232 May 14 '13 at 15:59

1 Answers1

2

I think this is what you're after:

LockSetForegroundWindow

http://msdn.microsoft.com/en-us/library/windows/desktop/ms633532(v=vs.85).aspx

Remarks The system automatically enables calls to SetForegroundWindow if the user presses the ALT key or takes some action that causes the system itself to change the foreground window (for example, clicking a background window). This function is provided so applications can prevent other applications from making a foreground change that can interrupt its interaction with the user.

Just don't forget to unlock :)

Edit:

Try SetWinEventHook as described here:

Is there Windows system event on active window changed?

Then when the unwanted window comes to the front you can send it to the background.

Community
  • 1
  • 1
paulm
  • 5,629
  • 7
  • 47
  • 70
  • I tried it, but unfortunately it doesn't work (when I launch a console application X, which calls `LockSetForegroundWindow` and then launches a Windows Forms program, the latter application gets the top-most window). – Glory to Russia May 17 '13 at 09:59
  • Thanks. Your first solution works, if I execute `AllowSetForegroundWindow` before the call `LockSetForegroundWindow(1)`. – Glory to Russia May 17 '13 at 10:53