#c #winapi
Вопрос:
Я пытаюсь написать dll, чтобы предотвратить изменение размера окна, но я не могу понять, как правильно указать lParam в этом случае.
Из документов:
HCBT_MOVESIZE: Указывает длинный указатель на прямоугольную структуру, содержащую координаты окна. Изменяя значения в структуре, процедура привязки CBTProc может задать конечные координаты окна.
Текущий код:
#include "pch.h"
#include <Windows.h>
extern "C" __declspec(dllexport) LRESULT CALLBACK CBTProc(
_In_ int nCode,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
if (nCode < 0) return CallNextHookEx(nullptr, nCode, wParam, lParam);
switch(nCode)
{
case HCBT_MOVESIZE: // A window is about to be moved or sized.
/*
For operations corresponding to the following CBT hook codes, the return value must be 0 to allow the operation, or 1 to prevent it.
HCBT_ACTIVATE
HCBT_CREATEWND
HCBT_DESTROYWND
HCBT_MINMAX
HCBT_MOVESIZE
HCBT_SETFOCUS
HCBT_SYSCOMMAND
*/
/*
switch(LOWORD(lParam)) //
{
case EVENT_SYSTEM_MOVESIZESTART:
return 1; // Prevent
}
*/
}
return 0;
}
Ответ №1:
В случае HCBT_MOVESIZE
, lParam
содержит адрес памяти a RECT
, поэтому просто введите lParam
его в RECT*
указатель, например:
extern "C" __declspec(dllexport) LRESULT CALLBACK CBTProc(
_In_ int nCode,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
if (nCode < 0) return CallNextHookEx(nullptr, nCode, wParam, lParam);
switch(nCode)
{
case HCBT_MOVESIZE: // A window is about to be moved or sized.
{
HWND hwnd = reinterpret_cast<HWND>(wParam);
RECT *rc = reinterpret_cast<RECT*>(lParam);
// use hwnd and *rc as needed...
if (should not resize)
return 1;
break;
}
...
}
return 0;
}
Комментарии:
1. Как правильно переключаться между «событиями», и в случае, если ширина/высота окна будут отличаться от заданного значения, измените его размер обратно? Что у меня в банкомате: pastebin.com/mhuj8EE9 Размер окна не изменяется до нужной ширины/высоты, просто сбрасывается до ее первоначального размера.
2. В нем нет «событий»
HCBT_MOVESIZE
, это не говорит вам, ПОЧЕМУ окно перемещается/изменяется размер.EVENT_SYSTEM_MOVESIZESTART
используется только сSetWinEventHook()
, а не сSetWindowsHookEx()
. ВHCBT_MOVESIZE
, все, что вы можете, это посмотреть на содержимоеRECT
, чтобы проверить, находится ли оно в нужном вам диапазоне, а если нет, то вы можете либо изменить содержимоеRECT
(вместо использованияSetWindowPos()
) иreturn 0
принять изменения, либоreturn 1
вообще заблокировать перемещение/размер.
Ответ №2:
LPARAM-это значение размером с указатель. Он может содержать любое значение, которое помещается в указатель. Значение значения обычно зависит от контекста.
При обработке HCBT_MOVESIZE
обратного вызова он обозначает
длинный указатель на ПРЯМУЮ структуру
Чтобы использовать его, клиентский код должен преобразовать значение в значение соответствующего типа. В C это делается с помощью приведения, например
switch(nCode)
{
case HCBT_MOVESIZE: {
auto pRect{ reinterpret_cast<RECT*>(lParam) };
// Use `pRect` to read from or write to the rectangle
}
break;
// ...
}