2015-01-28 3 views
2

У меня есть TFrame, который я хочу, чтобы изменить размер, щелкнув и перетащив нижний правый угол. Функциональность должна быть;Как запрограммировать дескриптор размера на delphi TFrame?

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

Во время выполнения будут установлены элементы управления поверх фрейма, поэтому я не могу использовать событие OnMouseMove. Поэтому я использую это;

private 
    procedure WMSetCursor(var Msg: TWMSetCursor); message WM_SETCURSOR; 

procedure TfraApplet.WMSetCursor(var Msg: TWMSetCursor); 
var 
    Point: TPoint; 
begin 

    Point := ScreenToClient(Mouse.CursorPos); 
    Label1.Caption := 'X:' + IntToStr(Point.X) + ' Y:' + IntToStr(Point.Y); 

    // Resize area (bottom right) 
    if (Point.X >= (Width - 10)) and (Point.Y >= (Height - 10)) then 
    Screen.Cursor := crSizeNWSE 
    else 
    Screen.Cursor := crDefault; 

end; 

Однако, как только курсор получает значение crSizeNWSE моих программ перестает получать сообщение WM_SETCURSOR окна.

Есть ли другое сообщение Windows, которое я могу получить, когда курсор не установлен как стрелка по умолчанию?

+0

Вы не устанавливаете результат сообщения –

+0

Что заставило вас решить, что вы прекратите получать сообщение? –

+0

Дэвид, спасибо за указатель. Как вернуть значение? Если я использую функцию, возвращающую логическое значение, я получаю ошибку при компиляции. – srayner

ответ

3

Это не значит, что кадр перестает получать сообщения WM_SETCURSOR, это то, что курсор застревает в crSizeNWSE. Когда вы вернетесь к настройке crDefault в Screen.Cursor, произойдет то, что VCL отправляет WM_SETCURSOR в кадр, чтобы установить его по умолчанию. По сути, никакой курсор никогда не устанавливается. Курсор должен быть установлен, если вы хотите его изменить с предыдущим, заменить последнюю часть с:

// Resize area (bottom right) 
    if (Point.X >= (Width - 10)) and (Point.Y >= (Height - 10)) then begin 
    winapi.Windows.SetCursor(Screen.Cursors[crSizeNWSE]); 
    Message.Result := 1; 
    end else 
    inherited; 


В качестве альтернативы, вы можете справиться с WM_NCHITTEST, чтобы определить область как область шлихтования, а затем процедура окна по умолчанию кадра будет установлена ​​соответствующий курсор, когда он обработки WM_SETCURSOR:

procedure TfraApplet.WMNCHitTest(var Message: TWMNCHitTest); 
var 
    Point: TPoint; 
begin 

    Point := ScreenToClient(SmallPointToPoint(Message.Pos)); 
    Label1.Caption := 'X:' + IntToStr(Point.X) + ' Y:' + IntToStr(Point.Y); 

    // Resize area (bottom right) 
    if (Point.X >= (Width - 10)) and (Point.Y >= (Height - 10)) then 
    Message.Result := HTBOTTOMRIGHT 
    else 
    inherited; 

end; 

в качестве дополнительного преимущества вам не придется писать дополнительный код для изменения размера кадра.

+0

Я пошел с вашим первым решением вызова унаследованного вместо установки Screen.Cursor на crDefault. Он работает отлично. – srayner