2016-07-07 7 views
3

У меня есть панели инструментов с формами с границами bsSizeToolWin, у меня есть специальная обработка движений окна и пользовательских подпрограмм для приклеивания/выравнивания панелей инструментов с границами основной формы (почти как функция стыковки), но проблема в том, что с bsSizeToolWin border-style У меня есть все углы/стороны границы.Как установить только 1 конкретный размер границы границы?

Возможно ли сделать только одну конкретную граничную сторону? (например, когда панель инструментов прикреплена к левой границе основной формы, я хочу только правую границу панели размером, cuz верхний и нижний координаты панели выравниваются в соответствии с высотой клиентской области основной формы и левой координатой, прикрепленной к правой границе основного не форма)

+0

Почему бы не использовать разветвитель? – Johan

+0

Ну, это нормально использовать сплиттер с состыкованными формами, но не в этом случае. –

ответ

4

с визуальной точки зрения, по умолчанию, если окно имеет значительные границы, то все края рисуются значительными, в противном случае ни из них, не существует в промежутке между как Win32 API не имеет концепция стилей границ границ, только стили границ всего окна. Если вы хотите, чтобы различные границы выглядели по-разному, вам, скорее всего, придется вручную нарисовать границы, обратив непосредственно сообщения и WM_NCPAINT.

От функциональный точки зрения, довольно легко предотвратить изменение размера окна на конкретных краях. Самый простой способ состоит в том, чтобы панель обрабатывала сообщение WM_NCHITTEST. Дайте панели нормальные размеры границ (при необходимости нарисованные на заказ), а затем сначала передайте полученное сообщение WM_NCHITTEST обработчику по умолчанию, а затем отредактируйте результат по мере необходимости. Преимущество этого подхода заключается в том, что ОС не позволит пользователю захватывать любой край, который сообщается как HTBORDER (несущественная граница), и не будет визуальной обратной связи, что край может быть изменен (даже если это действительно так).

Например, давайте воспользуемся примером панели с выравниванием по левому краю. Если обработчик по умолчанию возвращает HTBOTTOM, HTBOTTOMLEFT, HTLEFT, HTTOPLEFT, или HTTOP, вместо этого возвращает HTBORDER. Если обработчик по умолчанию возвращает HTBOTTOMRIGHT или HTTOPRIGHT, вместо этого возвращает HTRIGHT. В противном случае возвратите возвращаемый обработчик по умолчанию.

Отрегулируйте значения по мере необходимости, исходя из того, на каком краю панели вы хотите быть значительными.

Например:

type 
    TMyPanelForm = class(TForm) 
    private 
    fWhichSideCanBeResized: TAlign; 
    procedure WMNCHitTest(var Message: TMessage); message WM_NCHITTEST; 
    end; 

procedure TMyPanelForm.WMNCHitTest(var Message: TMessage); 
begin 
    inherited; 
    case fWhichSideCanBeResized of 
    alLeft: 
    begin 
     case Message.Result of 
     HTBOTTOM, HTBOTTOMRIGHT, HTRIGHT, HTTOPRIGHT, HTTOP: 
      Message.Result := HTBORDER; 
     HTBOTTOMLEFT, HTTOPLEFT: 
      Message.Result := HTLEFT; 
     end; 
    end; 
    alRight: 
    begin 
     case Message.Result of 
     HTBOTTOM, HTBOTTOMLEFT, HTLEFT, HTTOPLEFT, HTTOP: 
      Message.Result := HTBORDER; 
     HTBOTTOMRIGHT, HTTOPRIGHT: 
      Message.Result := HTRIGHT; 
     end; 
    end; 
    alTop: 
    begin 
     case Message.Result of 
     HTLEFT, HTBOTTOMLEFT, HTBOTTOM, HTBOTTOMRIGHT, HTRIGHT: 
      Message.Result := HTBORDER; 
     HTTOPLEFT, HTTOPRIGHT: 
      Message.Result := HTTOP; 
     end; 
    end; 
    alBottom: 
    begin 
     case Message.Result of 
     HTLEFT, HTTOPLEFT, HTTOP, HTTOPRIGHT, HTRIGHT: 
      Message.Result := HTBORDER; 
     HTBOTTOMLEFT, HTBOTTOMRIGHT: 
      Message.Result := HTBOTTOM; 
     end; 
    end; 
    end; 
end; 

В качестве альтернативы:

procedure TMyPanelForm.WMNCHitTest(var Message: TMessage); 
begin 
    inherited; 
    case Message.Result of 
    HTLEFT: 
     if fWhichSideCanBeResized <> alLeft then 
     Message.Result := HTBORDER; 
    HTRIGHT: 
     if fWhichSideCanBeResized <> alRight then 
     Message.Result := HTBORDER; 
    HTTOP: 
     if fWhichSideCanBeResized <> alTop then 
     Message.Result := HTBORDER; 
    HTBOTTOM: 
     if fWhichSideCanBeResized <> alBottom then 
     Message.Result := HTBORDER; 
    HTTOPLEFT: 
     case fWhichSideCanBeResized of 
     alTop: Message.Result := HTTOP; 
     alLeft: Message.Result := HTLEFT; 
     else 
     Message.Result := HTBORDER; 
     end; 
    HTBOTTOMLEFT: 
     case fWhichSideCanBeResized of 
     alBottom: Message.Result := HTBOTTOM; 
     alLeft: Message.Result := HTLEFT; 
     else 
     Message.Result := HTBORDER; 
     end; 
    HTTOPRIGHT: 
     case fWhichSideCanBeResized of 
     alTop: Message.Result := HTTOP; 
     alRight: Message.Result := HTRIGHT; 
     else 
     Message.Result := HTBORDER; 
     end; 
    HTBOTTOMRIGHT: 
     case fWhichSideCanBeResized of 
     alBottom: Message.Result := HTBOTTOM; 
     alRight: Message.Result := HTRIGHT; 
     else 
     Message.Result := HTBORDER; 
     end; 
    end; 
end; 
+0

Хорошо о визуальной точке зрения - я не думаю, что эта разница в 1 пиксель в ширине края действительно имеет значение =) Ando я также немного искал сообщения NC * - и я вижу, что было бы непросто сделать вашу собственную обработку размеров через эти сообщения, и поэтому вам вообще не нужны собственные значимые границы =) –

+0

Если вы отключите собственные значимые границы, а затем попытайтесь выманить 'HTBORDER'' 'HTLEFT/RIGHT/TOP/BOTTOM' на основе координат мыши в окне , он фактически не позволит изменять размер, поскольку для начала границы не были изменены. Другими словами, вы можете предотвратить изменение размера значительной границы, но вы не можете разрешить изменение размера границы без изменения размера. Если вы не планируете вручную отслеживать активность мыши, чтобы вручную изменить размер окна с помощью симулятора. Что больше работы. –

+0

Я имел в виду, что есть сообщения NC * для перемещения мыши и нажатия/вниз/вверх - и при обработке всех этих сообщений самостоятельно можно создавать свои собственные процедуры калибровки. –