• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1844
  • Last Modified:

Wierd focus problem renders windows out of focus and clickability

I have created a piece of software which uses windows calls to give focus to different windows at different points of time. Clicking a button in one application may trigger another application to gain focus.

This actually works pretty well, however some times it results in the window getting focus however none of the buttons can be pressed, it seems as it is a window out of focus however it is the top one. Now the really wierd part is that by minimizing one of the other Applications the focus to the one with the problem is restored and one can continue.

Does anyone have any idea what could be the cause of this ?

This is the code which causes the conflict

Private Declare Function BringWindowToTop Lib "user32" (ByVal hwnd As Long) As Long
Public Function switchToCash(billToOpen As Long, Optional person_id As Long)
    On Error Resume Next
    Unload frmFront
    On Error GoTo here
    Dim nrs As New ADODB.Recordset
    If person_id <> 0 Then
        frmFront.storedPID = person_id
    ElseIf frmBusinessView.currentSetup.persLog Then
        If frmBusinessView.currentSetup.persCheckedIN Then
            nrs.Open "select personale_navn,personale_id from personale_db where personale_id in(select person_id from checks where checkedOut is null)", frmFront.bookingCnxn
        Else
            nrs.Open "select personale_navn,personale_id from personale_db", frmFront.bookingCnxn
        End If
        If nrs.EOF Then
            frmBusinessView.Show
            BringWindowToTop frmBusinessView.hwnd
            MsgBox "Der er intet personale checket ind"
            GoTo thisPlace
        End If
        frmPersLogin.Show
        BringWindowToTop frmPersLogin.hwnd
        frmPersLogin.Hide
        frmFront.storedPID = frmPersLogin.create(frmBusinessView)
    End If
    frmFront.tableID = -1
    frmFront.currentBill = billToOpen
    frmFront.Show
    BringWindowToTop frmFront.hwnd
    frmFront.Hide ''1, frmBusinessView
    frmFront.Show 1, frmBusinessView
    changeFocusToBook
thisPlace:
    Exit Function
here:
    MsgBox "Der opstod en fejl..." & vbNewLine & Err.Description
End Function
0
mSchmidt
Asked:
mSchmidt
1 Solution
 
Erick37Commented:
"Microsoft changed the rules with Win98 and Windows 2000 ("The OS formerly known as NT5"). The SetForegroundWindow API can no longer be used directly to take focus away from another application."

http://vb.mvps.org/samples/descriptions.asp#ForceFore

To bring a window in another process to the top and in focus, use the ForceForegroundWindow function from the link above.  Place the following code in a standard module, and call the function like this:

Call ForceForegroundWindow(hwnd)

'=========Standard Module code========

Option Explicit

' *********************************************************************
'  Copyright ©1998 Karl E. Peterson, All Rights Reserved
'  http://www.mvps.org/vb
' *********************************************************************
'  You are free to use this code within your own applications, but you
'  are expressly forbidden from selling or otherwise distributing this
'  source code without prior written consent.
' *********************************************************************
'
' Required Win32 API Declarations
'
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Private Declare Function AttachThreadInput Lib "user32" (ByVal idAttach As Long, ByVal idAttachTo As Long, ByVal fAttach As Long) As Long
Private Declare Function GetForegroundWindow Lib "user32" () As Long
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function IsIconic Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
'
' Constants used with APIs
'
Private Const SW_SHOW = 5
Private Const SW_RESTORE = 9

Public Function ForceForegroundWindow(ByVal hWnd As Long) As Boolean
   Dim ThreadID1 As Long
   Dim ThreadID2 As Long
   Dim nRet As Long
   '
   ' Nothing to do if already in foreground.
   '
   If hWnd = GetForegroundWindow() Then
      ForceForegroundWindow = True
   Else
      '
      ' First need to get the thread responsible for this window,
      ' and the thread for the foreground window.
      '
      ThreadID1 = GetWindowThreadProcessId(GetForegroundWindow, ByVal 0&)
      ThreadID2 = GetWindowThreadProcessId(hWnd, ByVal 0&)
      '
      ' By sharing input state, threads share their concept of
      ' the active window.
      '
      If ThreadID1 <> ThreadID2 Then
         Call AttachThreadInput(ThreadID1, ThreadID2, True)
         nRet = SetForegroundWindow(hWnd)
         Call AttachThreadInput(ThreadID1, ThreadID2, False)
      Else
         nRet = SetForegroundWindow(hWnd)
      End If
      '
      ' Restore and repaint
      '
      If IsIconic(hWnd) Then
         Call ShowWindow(hWnd, SW_RESTORE)
      Else
         Call ShowWindow(hWnd, SW_SHOW)
      End If
      '
      ' SetForegroundWindow return accurately reflects success.
      '
      ForceForegroundWindow = CBool(nRet)
   End If
End Function
0

Featured Post

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

Tackle projects and never again get stuck behind a technical roadblock.
Join Now