Time ago I asked this question, it was solved here:
But now, and for unknown reason, the C# or Vb.Net code provided there is not working, and I don't understand why not.
I did some modifications to the original code provided there, but I tested the originals and didn't worked.
What happens is that I can't undide a hidden process, I'm not sure where I'm failing. At first view I think that the handle I get with FindWindowEx
does not really corresponds to the handle I want.
These are my P/Invoking function signatures and the showwindow enumeration:
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto,
BestFitMapping:=False, ThrowOnUnmappablechar:=True)>
Friend Shared Function FindWindow(
ByVal lpClassName As String,
ByVal lpWindowName As String
) As IntPtr
End Function
<DllImport("User32.dll", SetLastError:=True, CharSet:=CharSet.Auto,
BestFitMapping:=False, ThrowOnUnmappablechar:=True)>
Friend Shared Function FindWindowEx(
ByVal hwndParent As IntPtr,
ByVal hwndChildAfter As IntPtr,
ByVal strClassName As String,
ByVal strWindowName As String
) As IntPtr
End Function
<DllImport("user32.dll")>
Friend Shared Function GetWindowThreadProcessId(
ByVal hWnd As IntPtr,
ByRef processId As Integer
) As Integer
End Function
<DllImport("User32", SetLastError:=False)>
Friend Shared Function ShowWindow(
ByVal hwnd As IntPtr,
ByVal nCmdShow As ProcessUtil.WindowState
) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
Public Enum WindowState As Integer
Hide = 0
Normal = 1
ShowMinimized = 2
Maximize = 3
ShowMaximized = Maximize
ShowNoActivate = 4
Show = 5
Minimize = 6
ShowMinNoActive = 7
ShowNA = 8
Restore = 9
ShowDefault = 10
ForceMinimize = 11
End Enum
The function:
Public Function SetWindowState(ByVal p As Process,
ByVal windowState As ProcessUtil.WindowState) As Boolean
Dim pHandle As IntPtr = IntPtr.Zero
Dim pid As Integer
' If window is visible then...
If (p.MainWindowHandle <> IntPtr.Zero) Then
Return ProcessUtil.NativeMethods.ShowWindow(p.MainWindowHandle, windowState)
Else ' window is hidden.
' Check all open windows (not only the process we are looking),
' begining from the child of the desktop.
While (pid <> p.Id)
' Get child handle of window who's handle is "pHandle".
pHandle = NativeMethods.FindWindowEx(IntPtr.Zero, pHandle, Nothing, Nothing)
' Get PID from "pHandle".
NativeMethods.GetWindowThreadProcessId(pHandle, pid)
End While
Return NativeMethods.ShowWindow(pHandle, windowState)
End If
End Function
And the way that I'm trying to test the function, where first I hide the window of notepad process, then I try to unhide it.
Dim p As Process = Process.GetProcessesByName("notepad").First
ProcessUtil.SetWindowState(p, ProcessUtil.WindowState.Hide)
' I find again the process to renew the "p.MainWindowHandle" as IntPtr.Zero.
p = Process.GetProcessesByName("notepad").First
ProcessUtil.SetWindowState(p, ProcessUtil.WindowState.Restore)
The problem with notepad is that it has 3 windows (spy++, class names):
1. "Notepad"
2. "MSCTFIME UI"
3. "IME"
you are getting the handle of the second one (I got anyway), MSCTFIME UI, thats why you can't show it. You need to specify the class name Notepad to get the correct handle:
pHandle = FindWindowEx(IntPtr.Zero, pHandle, "Notepad", Nothing)