#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
Надеюсь, эта информация может кому-то помочь!