我正在开发一个项目,我必须先拆分,然后重新调整桌面上的窗口大小。我可以使用pinvoke服务TileWindows
拆分桌面屏幕。但我被困在另一部分,以调整桌面上的窗口大小。因为首先我必须抓住一些窗口在桌面上重新调整大小的事件。为了抓住这个事件,我使用了在{答案>中回答的this代码。
[DllImport("user32.dll", SetLastError = true)]
internal static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, WinEventProc lpfnWinEventProc, int idProcess, int idThread, uint dwflags);
[DllImport("user32.dll")]
internal static extern int UnhookWinEvent(IntPtr hWinEventHook);
internal delegate void WinEventProc(IntPtr hWinEventHook, uint iEvent, IntPtr hWnd, int idObject, int idChild, int dwEventThread, int dwmsEventTime);
const uint WINEVENT_OUTOFCONTEXT = 0;
const uint EVENT_SYSTEM_FOREGROUND = 3;
private IntPtr winHook;
private WinEventProc listener;
public void StartListeningForWindowChanges()
{
listener = new WinEventProc(EventCallback);
//setting the window hook
winHook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, listener, 0, 0, WINEVENT_OUTOFCONTEXT);
}
public void StopListeningForWindowChanges()
{
UnhookWinEvent(winHook);
}
private static void EventCallback(IntPtr hWinEventHook, uint iEvent, IntPtr hWnd, int idObject, int idChild, int dwEventThread, int dwmsEventTime)
{
MessageBox.Show("I am here");
}
我得到的问题是,即使我没有在屏幕上调整任何窗口大小,事件也会被触发。正如您所看到的,我在messageBox
函数中添加了eventCallback
并弹出,但有趣的是它在ok
按钮上没有显示任何内容。
答案 0 :(得分:0)
正如@HansPassant已经说过你应该使用
EVENT_SYSTEM_MOVESIZEEND
= 0x000B
常量,表示:窗口的移动或调整大小已经完成。您也从任何窗口接收活动。如果你看一下SetWinEventHook
function的签名:
HWINEVENTHOOK WINAPI SetWinEventHook(
_In_ UINT eventMin,
_In_ UINT eventMax,
_In_ HMODULE hmodWinEventProc,
_In_ WINEVENTPROC lpfnWinEventProc,
_In_ DWORD idProcess,
_In_ DWORD idThread,
_In_ UINT dwflags
);
你会发现:
idProcess
- 指定挂钩函数从中接收事件的进程的ID。指定零(0)以从当前桌面上的所有进程接收事件。然而,在您的代码中,您已将0
空格:
winHook = SetWinEventHook(
EVENT_SYSTEM_FOREGROUND,
EVENT_SYSTEM_FOREGROUND,
IntPtr.Zero,
listener,
0, // <--- idProcess
0,
WINEVENT_OUTOFCONTEXT);
您需要获取进程的ID才能只收听有关窗口的事件。为此,您可以使用Process.Id
Property。我认为这应该有效(对我有用):
const uint EVENT_SYSTEM_MOVESIZESTART = 0x000B;
Process currentProcess = Process.GetCurrentProcess();
winHook = SetWinEventHook(
EVENT_SYSTEM_MOVESIZEEND,
EVENT_SYSTEM_MOVESIZEEND,
IntPtr.Zero,
listener,
currentProcess.Id,
0,
WINEVENT_OUTOFCONTEXT);