Я работаю над проектом, в котором я должен сначала разделить, а затем изменить размер окна на рабочем столе. Я могу разделить экран рабочего стола, используя службу pinvoke TileWindows
. Но я застрял в другой части, чтобы изменить размер окон на рабочем столе. Потому что сначала я должен поймать событие, что какое-то окно размером на рабочем столе. Чтобы поймать это событие, я использовал этот код в SO.
[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
.
Поскольку @HansPassant уже сказал, что вы должны использовать
EVENT_SYSTEM_MOVESIZEEND
= 0x000B
константа, которая указывает, что: движение или изменение размера окна окончено. вы также получаете события из ЛЮБОГО окна. Если вы посмотрите на подпись функции SetWinEventHook
:
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
- указывает идентификатор процесса, из которого функция hook получает события. Укажите нуль (0) для приема событий из всех процессов на текущем рабочем столе. однако в вашем коде вы разместили 0
:
winHook = SetWinEventHook(
EVENT_SYSTEM_FOREGROUND,
EVENT_SYSTEM_FOREGROUND,
IntPtr.Zero,
listener,
0, // <--- idProcess
0,
WINEVENT_OUTOFCONTEXT);
Вам нужно получить идентификатор вашего процесса, чтобы слушать только события о вашем окне. Для этого вы можете использовать свойство Process.Id
. Я думаю, что это должно сработать (это работает для меня):
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);