Лучший способ позволить форме перемещаться - это имитировать, как форма перемещается при нажатии и перетаскивании строки заголовка.Поскольку в вашем окне нет строки заголовка, когда Windows нужно знать, на какой части вашей формы находится курсор мыши, вы ложитесь и говорите Windows, что он действительно находится над строкой заголовка.После этого перемещение работает нормально, так как начинает действовать стандартное поведение.
Для этого вы отвечаете на сообщение WM_NCHITTEST
, которое легко сделать с помощью , переопределяя форму WndProc
метод .Это сообщение отправляется в нескольких ситуациях (не только щелчки мышью или движение), поэтому не думайте о том, что делает пользователь, когда вы получаете это сообщение.Обработайте его, установив для результата сообщения значение HTCAPTION
, значение которого указывает на положение над строкой заголовка.
Важные моменты, на которые следует обратить внимание:
- Этот метод будет вызываться длякаждое сообщение, которое получает форма;не делайте здесь ничего медленного или сложного.
- Всегда позволяйте наследуемой по умолчанию реализации
WndProc
обрабатывать сообщение.Это важно для большинства сообщений, так как вы хотите изменить только это поведение, и если вы не вызовете унаследованную имплантацию, для сообщений вообще ничего не произойдет, но это важно и для этого сообщения, так как вы не знаетекакой код нужно отправить это сообщение.Т.е. вы хотите добавить, как ваша программа реагирует на это, а не заменить его.Это общее хорошее руководство для всей обработки сообщений, которые вы перехватываете / добавляете.В документации WndProc
это тоже упоминается. - Вы можете установить область формы в качестве перетаскиваемого бита, проверив координаты мыши.В приведенном ниже коде будут перетаскиваться только верхние 100 пикселей формы.
Пример кода:
void __fastcall TForm1::WndProc(Messages::TMessage& Message) {
TForm::WndProc(Message); // Inherited implementation
if (Message.Msg == WM_NCHITTEST) {
TWMNCHitTest& oMsg = reinterpret_cast<TWMNCHitTest&>(Message);
TPoint oPoint(oMsg.XPos, oMsg.YPos); // Screen coordinates
oPoint = ScreenToClient(oPoint); // Now in form-local coordinates
// It's in the title bar (caption) if it's in a rectangle at the top of the form
if ((oPoint.x > 0 && oPoint.x < ClientWidth) &&
(oPoint.y > 0 && oPoint.y < 100))
{
oMsg.Result = HTCAPTION;
}
}
}