Перемещение за клиентскую область

Здесь на конкретном примере (перемещение формы за любую точку клиентской области) продемонстрировано, как можно самостоятельно определять положение некоторых важных элементов окна. Под элементами окна здесь подразумеваются:

• строка заголовка (предназначена не только для отображения текста заголовка, но и служит областью захвата при перемещении окна мышью);

• границы окна (при щелчке кнопкой мыши на верхней, нижней, правой и левой границе можно изменять размер окна, правда, если стиль окна это допускает);

• четыре угла окна (предназначены для изменения размера окна с помощью мыши);

• системные кнопки закрытия, разворачивания, сворачивания, контекстной справки (обычно расположены в строке заголовка окна);

• горизонтальная и вертикальная полосы прокрутки;

• системное меню (раскрывается щелчком кнопкой мыши на значке окна);

• меню – полоса меню (обычно расположена вверху окна);

• клиентская область – по умолчанию все пространство окна, кроме строки заголовка, меню и полос прокрутки.

Каждый раз, когда над окном перемещается указатель мыши либо происходит нажатие кнопки мыши, система посылает соответствующему окну сообщение WM_ NCHITTEST для определения того, над которой из перечисленных выше областей окна находится указатель. Обработчик этого сообщения, вызываемый по умолчанию, информирует систему о расположении элементов окна в привычных для пользователя местах: заголовка – сверху, правой границы – справа и т. д.

Как вы, наверное, уже догадались, реализовав свой обработчик сообщения WM_ NCHITTEST, можно изменить назначение элементов окна. Этот прием как раз и реализован в листинге 1.21.

Листинг 1.21. Перемещение окна за клиентскую область

procedure TfrmMoveClient.WMNCHitTest(var Message: TWMNCHitTest);

var

rc: TRect;

p: TPoint;

begin

//Если точка приходится на клиентскую область, то заставим систему

//считать эту область частью строки заголовка

rc:= GetClientRect();

p.X:= Message.XPos;

p.Y:= Message.YPos;

p:= ScreenToClient(p);

if PtInRect(rc, p) then

Message.Result:= HTCAPTION

else

//Обработка по умолчанию

Message.Result:= DefWindowProc(Handle, Message.Msg, 0, 65536 * Message.YPos + Message.XPos);

end;

Приведенный в листинге 1.21 обработчик переопределяет положение только строки заголовка, возвращая значение HTCAPTION. Этот обработчик может возвращать следующие значения (целочисленные константы, возвращаемые функцией DefWindowProc):

• HTBORDER – указатель мыши находится над границей окна (размер окна не изменяется);

• HTBOTTOM, HTTOP, HTLEFT, HTRIGHT – указатель мыши находится над нижней, верхней, левой или правой границей окна соответственно (размер окна можно изменить, «потянув» за границу);

• HTBOTTOMLEFT, HTBOTTOMRIGHT, HTTOPLEFT, HTTOPRIGHT – указатель мыши находится в левом нижнем, правом нижнем, левом верхнем или правом верхнем углу окна (размер окна можно изменять по диагонали);

• HTSIZE, HTGROWBOX – указатель мыши находится над областью, предназначенной для изменения размера окна по диагонали (обычно в правом нижнем углу окна);

• HTCAPTION – указатель мыши находится над строкой заголовка окна (за это место окно перемещается);

• HTCLIENT – указатель мыши находится над клиентской областью окна;

• HTCLOSE – указатель мыши находится над кнопкой закрытия окна;

• HTHELP – указатель мыши находится над кнопкой вызова контекстной справки;

• HTREDUCE, HTMINBUTTON – указатель мыши находится над кнопкой минимизации окна;

• HTZ OOM, HTMAXBUTTON – указатель мыши находится над кнопкой максимизации окна;

• HTMENU – указатель мыши находится над полосой меню окна;

• HTSYSMENU – указатель мыши находится над значком окна (используется для вызова системного меню);

• HTHSCROLL, HTVSCROLL – указатель находится над вертикальной или горизонтальной полосой прокрутки, соответственно;

• HTTRANSPARENT – если возвращается это значение, то сообщение пересылается окну, находящемуся под данным окном (окна должны принадлежать одному потоку);

• HTNOWHERE – указатель не находится над какой-либо из областей окна (например, на границе между окнами);

• HTERROR – то же, что и HTNOWHERE, только при возврате этого значения обработчик по умолчанию (DefWindowProc) воспроизводит системный сигнал, сигнализирующий об ошибке.

Более 800 000 книг и аудиокниг! 📚

Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением

ПОЛУЧИТЬ ПОДАРОК

Данный текст является ознакомительным фрагментом.