CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    Feb 2003
    Posts
    417

    ShowWindow doesn't work

    Just that a call to the ShowWindow function is not working as it should.

    I have an application and a picture box on it, on the click event of which, as seen below, I trigger another EXE called "Workflow Designer.exe". But if Workflow Designer is already running then I wish only to maximize its window and do not wish to start another instance of it. I have written the code already. It works fine when Workflow Designer is not running any previous instances. However, if Workflow Designer is already running, even then everything works fine except the call to the ShowWindow function.

    The ShowWindow function returns 0, as it must if the window is already visible says the documentation, but even then it does not maximize the Workflow Designer Window.

    Code:
    Public Sub picWF_Click(Index As Integer)
    
    Dim hWndWorkflowDesigner As Long
    Dim LngRetVal As Long
        If Not BoolToolBarWorkflow Then Exit Sub
        
        mdiNew.WindowState = vbMinimized
        If IsProcessRunning(LngProcessIDWorkflowDesigner) Then
            hWndWorkflowDesigner = GethWndFromProcessID(LngProcessIDWorkflowDesigner)
            If hWndWorkflowDesigner <> 0 Then
                LngRetVal = ShowWindow(hWndWorkflowDesigner, SW_MAXIMIZE)
                If LngRetVal = 0 Then
                    Debug.Print Err.LastDllError
                End If
            End If
        Else
            LngProcessIDWorkflowDesigner = Shell(App.Path & "\Workflow Designer.exe", vbMaximizedFocus)
        End If
        
    End Sub


    In a global module

    Code:
    Public LngProcessIDWorkflowDesigner As Long
    
    Public Function IsProcessRunning(ByVal ProcessID As Long) As Boolean
        IsProcessRunning = (OpenProcess(&H100000, False, ProcessID) <> 0)
    End Function

  2. #2
    Join Date
    Dec 2002
    Location
    London, UK
    Posts
    1,569
    ShowWindow does not bring the window to the foreground. It only makes an invisible window visible.

    You want to use the MOVEWINDOW API. (Then change the Z order)
    Mike

  3. #3
    Join Date
    Feb 2003
    Posts
    417
    I actually did try the SetForeground Window prior to ShowWindow but that too did not work for me. How else do I maximize this window?

  4. #4
    Join Date
    Feb 2003
    Posts
    417
    Nope! MoveWindow doesn't work either. Lemme try SetWindowPos or BringWindowToTop. Yeah! I remember using BringWindowToTop. That must work here.


    Code:
    Public Sub picWF_Click(Index As Integer)
    
    Dim hWndWorkflowDesigner As Long
    Dim LngRetVal As Long
    Dim Arr() As String
    
        If Not BoolToolBarWorkflow Then Exit Sub
        mdiNew.WindowState = vbMinimized
        If IsProcessRunning(LngProcessIDWorkflowDesigner) Then
            hWndWorkflowDesigner = GethWndFromProcessID(LngProcessIDWorkflowDesigner)
            If hWndWorkflowDesigner <> 0 Then
                Arr = Split(GetScreenResolution, "x")
                LngRetVal = MoveWindow(hWndWorkflowDesigner, 0, 0, CLng(Arr(0)), CLng(Arr(1)), False)
                LngRetVal = SetForegroundWindow(hWndWorkflowDesigner)
                If LngRetVal = 0 Then
                    Debug.Print Err.LastDllError
                End If
            End If
        Else
            LngProcessIDWorkflowDesigner = Shell(App.Path & "\Workflow Designer.exe", vbMaximizedFocus)
        End If
        
    End Sub

  5. #5
    Join Date
    Feb 2003
    Posts
    417
    Darn! I tried SetwindowPos, BringWindowToTop, SetForegroundWindow, MoveWindow, ShowWindow...bah..none of them worked for me. Please help me out.

  6. #6
    Join Date
    Feb 2003
    Posts
    417
    Guys, this is crazy. I scratched my head hard and even sent a WM_SIZE to that window but that window won't budge from there.

    Code:
    Public Sub picWF_Click(Index As Integer)
    
    Dim hWndWorkflowDesigner As Long
    Dim LngRetVal As Long
    
        If Not BoolToolBarWorkflow Then Exit Sub
        mdiNew.WindowState = vbMinimized
        If IsProcessRunning(LngProcessIDWorkflowDesigner) Then
            hWndWorkflowDesigner = GethWndFromProcessID(LngProcessIDWorkflowDesigner)
            If hWndWorkflowDesigner <> 0 Then
                LngRetVal = SendMessage(hWndWorkflowDesigner, WM_SIZE, SIZE_MAXIMIZED, 0&)
            End If
        Else
            LngProcessIDWorkflowDesigner = Shell(App.Path & "\Workflow Designer.exe", vbMaximizedFocus)
        End If
        
    End Sub
    Please help me, please.

  7. #7
    Join Date
    May 2003
    Location
    Australia
    Posts
    155
    Have you tried using AppActivate?

    From memory, it uses the Window Caption or a ProcessID rather than the window handle, but you should be able to obtain either of those if you know the window handle.

    Hope this helps.

    Cheers,
    Tinbum747
    Zen-Programming:

    If a compiler beeps in the IDE forest, and nobody hears it, was there really a bug?

  8. #8
    Join Date
    Apr 2002
    Posts
    388
    Use SetWindowPos API!

    Code:
    Public Const SWP_NOMOVE = 2
    Public Const SWP_NOSIZE = 1
    Public Const FLAGS = SWP_NOMOVE Or SWP_NOSIZE
    Public Const HWND_TOPMOST = -1
    Public Const HWND_NOTOPMOST = -2
    
    Declare Function SetWindowPos Lib "USER32" _
                (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, _
                ByVal x As Long, ByVal y As Long, _
                ByVal cx As Long, ByVal cy As Long, _
                ByVal wFlags As Long) As Long
    
    Public Function SetTopMostWindow(hWnd As Long, Topmost As Boolean) As Long
       If Topmost = True Then 'Make the window topmost
          SetTopMostWindow = SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, FLAGS)
       Else
          SetTopMostWindow = SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, FLAGS)
          SetTopMostWindow = False
       End If
    End Function
    If it doesn't work, you possible get the false Windowhandle! You get the correct with this function:

    Code:
    Private Declare Function FindWindow Lib "user32"  Alias "FindWindowA" _
        (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare Function GetParent Lib "user32" _
        (ByVal hWnd As Long) As Long
    Private Declare Function GetWindowThreadProcessId Lib "user32" _
        (ByVal hWnd As Long, lpdwprocessid As Long) As Long
    Private Declare Function GetWindow Lib "user32" _   
     (ByVal hWnd As Long, ByVal wCmd As Long) As Long
    
    
    Private Function GetWinHandle(hInstance As Long) As Long
    'returns the belonging windowhandle to the instancehandle
       Dim tempHwnd As Long
       
       ' Grab the first window handle that Windows finds:
       tempHwnd = FindWindow(vbNullString, vbNullString)
       
       ' Loop until you find a match or there are no more window handles:
       Do Until tempHwnd = 0
          ' Check if no parent for this window
          If GetParent(tempHwnd) = 0 Then
             ' Check for PID match
             If hInstance = ProcIDFromWnd(tempHwnd) Then
                ' Return found handle
                GetWinHandle = tempHwnd
                ' Exit search loop
                Exit Do
             End If
          End If
       
          ' Get the next window handle
          tempHwnd = GetWindow(tempHwnd, GW_HWNDNEXT)
       Loop
    End Function
    
    Private Function ProcIDFromWnd(ByVal hWnd As Long) As Long
       Dim idProc As Long
       
       ' Get PID for this HWnd
       GetWindowThreadProcessId hWnd, idProc
       
       ' Return PID
       ProcIDFromWnd = idProc
    End Function
    I hope that helps you!
    Last edited by Ungi; June 25th, 2003 at 12:34 AM.
    mfg Ungi

    Music, music and VB. VB is like music: You never know how it is interpreted.

  9. #9
    Join Date
    Feb 2003
    Posts
    417
    Guys, I think I got the real problem. For a test, I made another project with an MDI and two child forms and a call from each of them to GetWindowThreadProcessID revealed that they all shared the same thread ID and but obviously the same process ID too. Now, while looping through all open windows in GethWndFromProcessID, it occured to me that while the ProcessID being matched therein was correct but it could be that one of the child windows was being encountered and its handle being returned to me, which I tried resizing and it had to fail since the MDI within which the child was contained was still minimized. While when I posted a WM_QUIT to the same window handle, it got destroyed. All this led me to think that my theory is somewhat correct. I am acting on a child window handle and so a WM_SIZE fails because the parent is minimized but a WM_QUIT on the child works fine because it passes it on to the MDI parent form.

    Now, I think I must use the GetAncestor and return from GethWndFromProcessID only if I encounter the parent/top level MDI form window and not otherwise.

    I did a search on my system but could not find Winuser.h. Can one of you please send me the value of GA_ROOT?

  10. #10
    Join Date
    Apr 2002
    Posts
    388
    Const GA_ROOT = 2
    mfg Ungi

    Music, music and VB. VB is like music: You never know how it is interpreted.

  11. #11
    Join Date
    Feb 2003
    Posts
    417
    Thanks, Ungi.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured