Author Topic: How to force display/focus to "last window"?  (Read 1913 times)

0 Members and 1 Guest are viewing this topic.

Offline John Montenigro

  • Newbie
  • *
  • Posts: 8
  • User-Rate: +0/-1
How to force display/focus to "last window"?
« on: August 29, 2017, 08:48:49 PM »
In PB Win10.04, I'm writing a small app to automate loading of data into a program that has no import ability, so I'm using SendKeys.inc to load its key buffer.
However, I would like to assure the user that the data won't just pour into any open window, so I'm trying to activate the "last window" that was active. It is possible that my app may sit idle for awhile, and the user may do many other tasks in other windows before starting the transfer, so I cannot rely on which window was "last active" at the time my app started running; it has to be at the time the transfer button is clicked.

Here's my confusion: I have read tons of material about SetFocus and all those related parent/child, visible/hidden API functions, but I have not found the right way to identify which window would be brought forward as if the user pressed ALT-TAB. It seems the more I read, the less I understand. I've even bought 2 antique books on Win32 programming, but this is still eluding me.

I *THINK* I'm supposed to find the window that is "next" in the z-order from the top (the one "below" my app), and ignore its Child windows and find their parent. Is this the right way?

I'm at work now, so cannot post code, but I'll return tomorrow with samples of what I've tried (that didn't work).

Meanwhile, if anyone can point me in the direction of good, clear information, I'd be grateful and read it right away.

Thanks!
-John




Offline John Montenigro

  • Newbie
  • *
  • Posts: 8
  • User-Rate: +0/-1
Re: How to force display/focus to "last window"?
« Reply #1 on: August 29, 2017, 09:18:42 PM »
I found some code that I had been experimenting with. I was trying every combination known to man!

Yes, I know this looks crazy, but when you've read everything you can get your hands on and it still makes no sense, you start to experiment...

-John

...in main loop:
Code: [Select]
   Dialog New 0, "MyApp", s.lDlgLeft, s.lDlgTop, s.lDlgWidth, s.lDlgHeight, %WS_Visible Or %WS_SysMenu Or _
      %WS_MinimizeBox Or %WS_Caption Or %DS_3DLook Or %DS_NoFailCreate Or %DS_SetFont, _
      %WS_Ex_Left Or %WS_Ex_LtrReading Or %WS_Ex_RightScrollbar Or %WS_Ex_ControlParent, To _
      ghDlg


Code: [Select]
Function PerformAltTab As Dword
   Local d, f As Dword
   Local m As String

   'To check if your application window is the foreground window,
   '  compare the handle returned by GetForegroundWindow
   '  to that of your application window.

   f = GetForegroundWindow
   m &= "GetForegroundWindow:   " & Trim$(f) & $CrLf

   d = AfxGetTopEnabledWindow                                          '1
   m &= "AfxGetTopEnabledWindow: " & Trim$(d)

   'd = AfxGetTopLevelWindow(ghDlg)                         '2    ' NOT the same as the Foreground or TopEnabled
   'd = AfxGetTopLevelWindow(d)                                         '3
   'm &= "AfxGetTopLevelWindow: " & Trim$(d)

   'd = AfxGetTopLevelParent(ghDlg)                         '4
   'd = AfxGetTopLevelParent(d)   ok in combo with last sibling?        '5

   'd = AfxGetFirstChild(ghDlg)                             '6
   'd = AfxGetFirstChild(d)                                             '7

   'd = AfxGetFormHandle(ghDlg)                             '8
   'd = AfxGetFormHandle(d)                                             '9

   'd = AfxGetFirstSibling(ghDlg)                           '10
   d = AfxGetFirstSibling(d)                                           '11

   'd = AfxGetLastSibling(ghDlg)                            '12
   'd = AfxGetLastSibling(d)                                            '13

   'd = AfxGetNextSibling(ghDlg)    ' shows promise!        '14
   d = AfxGetNextSibling(d)    ' shows promise!                        '15
   'd = AfxGetNextSibling(d)    ' shows promise!                        '16
   'd = AfxGetNextSibling(d)    ' shows promise!                        '17

   'd = AfxGetPrevSibling(ghDlg)      ' not good!           '18
   'd = AfxGetPrevSibling(d)    ' shows promise!                        '19
   'd = AfxGetPrevSibling(d)    ' shows promise!                        '20
   'd = AfxGetPrevSibling(d)    ' shows promise!                        '21

   ? m,,"experimenting"

'   AfxForceSetForegroundWindow(d)
'these stay together:                                                   ' 4 + 7 + 15 = self
   SetForegroundWindow(d)
   BringWindowToTop(d)
   SetFocus(d)
End Function
« Last Edit: August 29, 2017, 09:22:56 PM by John Montenigro »

Offline John Montenigro

  • Newbie
  • *
  • Posts: 8
  • User-Rate: +0/-1
Re: How to force display/focus to "last window"?
« Reply #2 on: August 29, 2017, 10:57:01 PM »
OK, I had a chance to experiment a bit more, and it would appear that GetNextSibling finds that "next window"...

Here's what seems to be working:

Code: [Select]
Function PerformAltTab As Dword
   Local d As Dword

   d = AfxGetNextSibling(ghDlg)
   SetForegroundWindow(d)
   BringWindowToTop(d)
   SetFocus(d)
   If Err Then Function = %TRUE    ' failed

End Function   


I'll post if I find out anything better.
-John



« Last Edit: August 30, 2017, 04:14:51 PM by John Montenigro »

Offline John Montenigro

  • Newbie
  • *
  • Posts: 8
  • User-Rate: +0/-1
Re: How to force display/focus to "last window"?
« Reply #3 on: September 05, 2017, 04:10:48 AM »
Turns out that I've missed something...

I'm expecting that when my PerformAltTab function completes, the user will be immediately able to start typing into that other window.

Unfortunately, I can bring the other window to the forefront and give it focus, but it is not ready to accept user keystrokes.

Can anyone see what I'm doing wrong?

Thanks,
-John