## 原因
為了拿到 process 的 MainWindowHandle 作隱藏/顯示。
但是在隱藏之後,process 的 MainWindowHandle 會等於 0
## 使用 AttachConsole GetConsoleWindow FreeConsole
其中一個方法是針對 console app 的作法是接到 console,拿到其 consolewindow 要到 ID,再離開。
使用 AttachConsole GetConsoleWindow FreeConsole
宣告需要:
```
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool AttachConsole(uint dwProcessId);
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern bool FreeConsole();
int GetSmsdMainWindowHandle(int procID)
Int32 tryHandle = 0;
try
{
AttachConsole((uint)procID);
tryHandle = GetConsoleWindow().ToInt32();
FreeConsole();
}
catch (Exception)
{
//pass
}
finally
{
FreeConsole();
}
return tryHandle;
}
```
使用方法:
```
int smsdMainWindowHandle = GetSmsdMainWindowHandle(xProc.Id);
```
## 使用 EnumChildWindows GetWindowThreadProcessId
另一個方法是列舉所有 子window 再拿到其 window thread 的 process ID。
使用 EnumChildWindows GetWindowThreadProcessId
宣告需要:
```
private struct SearchData
{
// You can put any vars in here...
public int currentTaskID;
public IntPtr currenthWnd;
}
private delegate bool EnumWindowsProc(IntPtr hWnd, ref SearchData data);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, ref SearchData data);
[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out int ProcessId);
bool EnumProc(IntPtr hWnd, ref SearchData data)
{
int lProcID;
GetWindowThreadProcessId(hWnd,out lProcID);
if (lProcID == data.currentTaskID)
{
data.currenthWnd = hWnd;
}
return true;
}
```
使用方法:
```
SearchData n = new SearchData();
n.currentTaskID = xProc.Id;
EnumChildWindows(IntPtr.Zero,new EnumWindowsProc(EnumProc),ref n);
int smsdMainWindowHandle = (int)n.currenthWnd;
```
這個方法的 VB Code 由 Cyrus 提供:
```
Dim currenthWnd = 0
Public Function fEnumWindowsCallback(ByVal hWnd As Integer, ByVal lpData As Integer) As Integer
fEnumWindowsCallback = 1
Dim lProcID As Integer
Call GetWindowThreadProcessId(hWnd, lProcID)
If lProcID = currentTaskID Then
currenthWnd = hWnd
End If
End Function
Call EnumChildWindows(0&, AddressOf fEnumWindowsCallback, 0&)
If currenthWnd <> 0 Then
If goSECSInterface.GEMObject.HideSMSD = True Then
ShowWindow(currenthWnd, SW_HIDE)
Else
ShowWindow(currenthWnd, SW_NORMAL)
End If
End If
```
## 參考:
- * https://stackoverflow.com/questions/8949652/do-windows-api-enumwindows-and-enumchildwindows-functions-behave-differently-in
沒有留言:
張貼留言