Вопрос пользователя заключается в желании предотвратить возможность перемещения окна WinForms. Пользователь ищет способ "заморозить" окно так, чтобы оно не могло быть перемещено, сохраняя при этом видимость его границ при попытке перемещения. В контексте Win32 такая возможность существует, и пользователь пытается реализовать аналогичный функционал для WinForms.
Подходы к решению
Использование обработчика сообщений
Один из подходов заключается в перехвате сообщений, предназначенных для изменения положения окна. В приведенном примере кода используется процедура WMPosChanging, которая изменяет флаги SWP_NOMOVE в структуре WINDOWPOS, чтобы предотвратить перемещение окна.
procedure TViewFrm.WMPosChanging(var Msg: TMessage);
var
wp: PWINDOWPOS;
begin
if Frozen then
begin
wp := PWINDOWPOS(Msg.LParam);
wp^.flags := wp^.flags or SWP_NOMOVE;
end;
inherited;
end;
Переопределение OnHandleCreated
Пользователь также предложил код, который удаляет команду перемещения из системного меню окна, делая его не перемещаемым.
Public Class UnmovableForm
Protected Overrides Sub OnHandleCreated(ByVal e As System.EventArgs)
' Удаление команды перемещения из системного меню
Call RemoveMenu(GetSystemMenu(Me.Handle, False), SC_MOVE, MF_BYCOMMAND)
MyBase.OnHandleCreated(e)
End Sub
...
End Class
Использование SystemParametersInfo
Один из комментаторов предложил использовать функцию SystemParametersInfo для изменения параметров системы, чтобы предотвратить перемещение окна.
Private Sub frmMain_Move(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Move
Me.Location = New Point(0, 0)
' Код для изменения параметров системы
End Sub
Интерцепция событий мыши
Другой подход заключается в перехвате событий мыши, чтобы предотвратить перемещение окна, но при этом отображать его границы.
public partial class TestForm : Form {
...
protected override void WndProc(ref Message m) {
if (m.Msg = Win32.WM_NCLBUTTONDOWN) {
// Код для отображения границ окна
} else {
base.WndProc(ref m);
}
}
...
}
Подтвержденный ответ
Пользователь нашел решение своей проблемы, переопределив WndProc и предотвратив обработку сообщений, связанных с перемещением окна.
method MainForm.WndProc(var m: Message);
begin
if ((m.Msg = WM_SYSCOMMAND) and (m.WParam.ToInt32 = SC_MOVE)) or
((m.Msg = WM_NCLBUTTONDOWN) and (m.WParam.ToInt32 = HTCAPTION)) then
begin
exit;
end;
inherited WndProc(var m);
end;
Вывод
Пользователь достиг желаемого результата, заморозив положение окна WinForms, что позволило ему предотвратить перемещение окна без потери видимости его границ. Различные подходы, предложенные в сообщениях и комментариях, демонстрируют, что для решения этой задачи можно использовать как обработку сообщений, так и изменение системных параметров, а также перехват событий мыши.
Вопрос связан с замораживанием положения окна приложения на платформе WinForms, чтобы предотвратить его перемещение пользователем, сохраняя при этом видимость границ окна.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.