2

hello i'm using Visual Basic 2008

here is part of my code:

    Private Const SW_HIDE As Integer = 0
    Private Const SW_SHOW As Integer = 5

    <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
     Private Shared Function ShowWindowAsync(ByVal hwnd As IntPtr, ByVal nCmdShow As Integer) As Boolean
        End Function

button1 code:

            Try
               Dim p() As Process = Process.GetProcessesByName("notepad")
               Dim mwh = p(0).MainWindowHandle
               ShowWindowAsync(mwh, SW_HIDE)
            Catch ex As Exception
               MsgBox("error")
            End Try      

button2 code:

            Try         
               Dim p() As Process = Process.GetProcessesByName("notepad")
               Dim mwh = p(0).MainWindowHandle
               ShowWindowAsync(mwh, SW_SHOW)
            Catch ex As Exception
               MsgBox("error")
            End Try  

when i click button 1 ( to hide the window ) it works good, but then when i want to display window back ( by clicking button 2 ) the function returns FALSE, who can tell me why? and how to get it to work, to hide window and then to show it again?

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
John
  • 7,500
  • 16
  • 62
  • 95

4 Answers4

4

Because ShowWindowAsync() returns zero when the window was previously hidden according to the MSDN documentation, and zero is interpreted as FALSE. The return value does not indicate whether the function succeeded or not.

So the first time you call ShowWindowAsync(mwh, SW_HIDE) on a visible window the function returns TRUE because ShowWindowAsync() returns a non-zero value indicating the window (that is now/will be hidden) used to be visible.

Then the second call ShowWindowAsync(mwh, SW_SHOW) on a hidden window returns FALSE because ShowWindowAsync() returns a zero value indicating the window (that is now/will be visible) used to be hidden.

In other words, this is by design and the function should work as intended (unless the mwh window is not responding to messages or is invalid).

But the real problem here is that once you hide a window, Process::MainWindowHandle property doesn't have the handle anymore.

A process has a main window associated with it only if the process has a graphical interface. If the associated process does not have a main window, the MainWindowHandle value is zero. The value is also zero for processes that have been hidden, that is, processes that are not visible in the taskbar. This can be the case for processes that appear as icons in the notification area, at the far right of the taskbar.

What you should do is to obtain the window handle via p(0).MainWindowHandle once and save the returned handle somewhere, so that you can show/hide the window. Of course, you should make sure that you zero out the saved handle when the window gets destroyed by the target process. In Notepad's case, you can use the Process::Exited event.

In silico
  • 51,091
  • 10
  • 150
  • 143
  • Silico thanks i get it to work, i defined MainWindowHandle only once, so now works both SW_HIDE and SW_SHOW, thanks again – John May 01 '11 at 09:10
1

To Maximize a hidden window of another process you must do this 3 steps (very easy):

1- Get the MainWindowHandle Because the application is hidden the MainWindowHandle is 0 (false). To overcome this problem you can use the FindWindow

//Get the MainWindowHandle
IntPtr hwnd = FindWindow(null, <WINDOW TITLE>);

2- Use ShowWindowAsync()

bool result = ShowWindowAsync(hwnd, 3); //3= Maximize application

3- Implement one of this application events: "GotFocus", "Activated" or "IsVisibleChanged" (I only tested the "Activated" event)

private void WindowApplication_Activated(object sender, EventArgs e)
{
    Application.Current.MainWindow.Show();
}

You can find more information on this url: http://isolvable.blogspot.pt/2009/09/restoring-wpf-window-of-another-process.html

Hope this information can help someone!

1

Sounds like "by design". Don't treat the return value of "false" as an error.

As per MSDN:

If the window was previously visible, the return value is nonzero.

If the window was previously hidden, the return value is zero. 

http://msdn.microsoft.com/en-us/library/ms633549%28VS.85%29.aspx

You could likely block the exception from occurring by declaring the interop import of the function as a 32-bit integer type instead of a Boolean.

Private Shared Function ShowWindowAsync(ByVal hwnd As IntPtr, ByVal nCmdShow As Integer) As Integer
selbie
  • 100,020
  • 15
  • 103
  • 173
1

When hiding I did :

WindowHandle = Proc(0).MainWindowHandle
ShowWindowAsync(Proc(0).MainWindowHandle, ShowWindowConstants.SW_HIDE)

Then when showing I used the WindowHandle variable:

ShowWindowAsync(WindowHandle, ShowWindowConstants.SW_SHOW)