ShowWindowAsync() не показывает скрытое окно (SW_SHOW)

#windows #vb.net

#Windows #vb.net

Вопрос:

привет, я использую Visual Basic 2008

вот часть моего кода:

     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
  

код кнопки 1:

             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      
  

код кнопки 2:

             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  
  

когда я нажимаю button 1 (чтобы скрыть окно), это работает хорошо, но затем, когда я хочу отобразить окно обратно (щелчком button 2 ), функция возвращается FALSE , кто может сказать мне, почему? и как заставить это работать, скрыть окно, а затем показать его снова?

Ответ №1:

Потому что ShowWindowAsync() возвращает ноль, когда окно было ранее скрыто в соответствии с документацией MSDN, и ноль интерпретируется как FALSE . Возвращаемое значение не указывает, была ли функция выполнена успешно или нет.

Таким образом, при первом вызове ShowWindowAsync(mwh, SW_HIDE) для видимого окна функция возвращает ненулевое значение, указывающее на окно (которое сейчас / будет скрыто), которое раньше было видимым. ……. TRUE Потому что ShowWindowAsync() возвращает ненулевое значение, указывающее, что окно (которое сейчас / будет скрыто) было видимым.

Затем возвращается второй вызов ShowWindowAsync(mwh, SW_SHOW) для скрытого окна, FALSE потому что ShowWindowAsync() возвращает нулевое значение, указывающее на окно (которое сейчас / будет видно), которое раньше было скрыто.

Другими словами, это сделано специально, и функция должна работать так, как задумано (если mwh окно не отвечает на сообщения или не является недопустимым).

Но реальная проблема здесь в том, что как только вы скрываете окно, у Process::MainWindowHandle свойства больше нет дескриптора.

С процессом связано главное окно, только если процесс имеет графический интерфейс. Если у связанного процесса нет главного окна, значение MainWindowHandle равно нулю. Значение также равно нулю для процессов, которые были скрыты, то есть процессов, которые не видны на панели задач.Это может иметь место для процессов, которые отображаются в виде значков в области уведомлений в крайнем правом углу панели задач.

Что вам следует сделать, так это получить дескриптор окна через p(0).MainWindowHandle один раз и сохранить возвращенный дескриптор где-нибудь, чтобы вы могли показывать / скрывать окно. Конечно, вы должны убедиться, что вы обнуляете сохраненный дескриптор, когда окно уничтожается целевым процессом. В случае с блокнотом вы можете использовать Process::Exited событие.

Комментарии:

1. Силиконовое спасибо, у меня получилось, я определил MainWindowHandle только один раз, так что теперь работает как SW_HIDE, так и SW_SHOW, еще раз спасибо

Ответ №2:

Звучит как «по замыслу». Не рассматривайте возвращаемое значение «false» как ошибку.

Согласно 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(VS.85).aspx

Вероятно, вы могли бы заблокировать возникновение исключения, объявив импорт функции взаимодействия как 32-разрядный целочисленный тип вместо логического.

 Private Shared Function ShowWindowAsync(ByVal hwnd As IntPtr, ByVal nCmdShow As Integer) As Integer
  

Ответ №3:

При скрытии я сделал :

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

Затем при отображении я использовал WindowHandle переменную:

 ShowWindowAsync(WindowHandle, ShowWindowConstants.SW_SHOW)
  

Ответ №4:

Чтобы развернуть скрытое окно другого процесса, вы должны выполнить следующие 3 шага (очень просто)::

1- Получите дескриптор MainWindowHandle, поскольку приложение скрыто, дескриптор MainWindowHandle равен 0 (false). Чтобы преодолеть эту проблему, вы можете использовать FindWindow

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

2- Используйте ShowWindowAsync()

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

3- Реализовать одно из этих событий приложения: «GotFocus», «Activated» или «IsVisibleChanged»
(Я тестировал только событие «Активировано»)

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

Вы можете найти дополнительную информацию по этому url:
http://isolvable.blogspot.pt/2009/09/restoring-wpf-window-of-another-process.html

Надеюсь, эта информация может кому-то помочь!