5

I have a small utility app written in Visual Basic 6 that has been happily running on XP clients for many years until recently a client who is using Windows 7 has notified and shown me that the behaviour is different.

When my VB app displays the dialog, it remains hidden until the user clicks on it in the taskbar.

I changed the code so rather than using a ".show vbModal" command, I changed to displaying the form with non-modally, and then added various API calls like BringWindowToFront and SetWindowPos to make it top most AND calling .focus on the form, despite these extra instructions the best result I can achieve is to make the form flash prompting the user to click on it.

No matter what I've tried I cannot make the window display topmost, and with focus, without user intervention.

Note. this is an ActiveX exe project and is being called by a Win16 app through COM.

Has anyone else encountered this behaviour and know of a solution?

Any suggestions/advice appreciated, thanks.

David Brown
  • 3,021
  • 3
  • 26
  • 46
  • 2
    Why the -1 ? What's unclear with this question? – David Brown May 31 '12 at 11:21
  • It's worth bearing in mind that the 16-bit app won't run on 64-bit Windows so you may want to look at updating it very soon. – Deanna May 31 '12 at 11:38
  • 1
    However you can still run them within a 32-bit VM. "XP Mode" is 32-bit XP SP3 I believe. – Bob77 May 31 '12 at 13:09
  • Ah, possibly, I've never had to run XP mode. That's not a good enough reason to keep running 16-bit code though :) – Deanna May 31 '12 at 14:50
  • 1
    I was assuming that if porting the 16-bit code was an easy solution it would have been done by now. I don't comsider XP Mode a "solution" just a "make do until" answer. – Bob77 May 31 '12 at 15:01
  • There is a possible workaround, see my answer to a similar question [here](http://stackoverflow.com/a/12582544/15639) – MarkJ Sep 25 '12 at 12:04

1 Answers1

5

Applications can't (without lying to Windows) steal focus. The calling app should really call AllowSetForegroundWindow() (if it's available on win16) to allow the COM process to steal the focus, or call SetForegroundWindow() itself.

See the help for SetForegroundWindow() for the conditions on setting focus.

Deanna
  • 23,876
  • 7
  • 71
  • 156
  • Yeah I read about that 'AllowSetForegroundWindow()' somewhere else and suspected this may be the cause. Unfortunately I won't have access to the process ID, as we are just creating the activex object using COM instructions such as DIM obj as Object, SET obj = CREATEOBJECT("x.x") – David Brown May 31 '12 at 11:16
  • I'll try the SetForegroundWindow() approach though and see if that helps. – David Brown May 31 '12 at 11:17
  • You can add a method to get the process ID/window handle in the caller, or just globally unlock it by passing `ASFW_ANY` – Deanna May 31 '12 at 11:35
  • I've created a test case myself using a 32-bit client (another VB6 program). Everything works just fine on XP or Vista, but the ZOrder problem occurs in Win7 (tested SP1). Even AllowSetForegroundWindow() made no difference, and I confirmed I was calling it from the ActiveX EXE's process. – Bob77 May 31 '12 at 13:03
  • Erm, it needs to be called from the process that already has the focus. It's a bit silly if a random application that doesn't have focus could allow itself to. – Deanna May 31 '12 at 14:50
  • I checked the call's result (and displayed the PIDs of both processes) and it returns True so all's well there. – Bob77 May 31 '12 at 15:11
  • You can also try using ZOrder. – BobRodes Jun 07 '12 at 04:31