2016-07-07 71 views
3

我有一些工具面板通過與bsSizeToolWin邊框形式,我有自定義處理窗口移動和自定義例程粘貼/對齊工具面板與主窗體的邊界(幾乎像對接功能),但問題與bsSizeToolWin邊框風格,我有邊界大小的所有角落/邊。如何僅設置1個特定尺寸邊框邊緣?

是否有可能只使一個特定的邊界大小? (例如,當工具面板粘貼到主窗體的左邊框時,我只希望面板的右邊框相當大,因此面板的頂部和底部座標根據主窗體的客戶區域的高度和左輔助框架的主高度右對齊形式)

+0

爲什麼不使用分離器? – Johan

+0

那麼可以使用分離器與停靠的窗體,但不是在這種情況下。 –

回答

4

視覺觀點出發,在默認情況下,如果一個窗口有相當大的邊界然後所有邊緣繪製相當大,否則它們都不是,沒有在其間的Win32 API的不具有每邊緣邊框樣式的概念,只有全窗口邊框樣式。如果您希望各種邊框看起來不同,您可能必須直接通過處理WM_NCCALCSIZEWM_NCPAINT消息來手動自定義繪製邊框。

功能的角度來看,防止用戶在特定邊緣上調整窗口大小是相當容易的。最簡單的方法是讓面板處理WM_NCHITTEST消息。給面板正常的大小調整邊框(如果需要自定義),然後讓它將任何收到的WM_NCHITTEST消息先傳遞給默認處理程序,然後根據需要調整結果。這種方法的好處是,操作系統不會允許用戶抓取任何報告爲HTBORDER(非可調邊界)的邊緣,並且不會有視覺反饋,表明邊緣可以調整大小(即使它真的是這樣)。

例如,讓我們使用面板對齊在左邊的示例。如果默認處理程序返回HTBOTTOM,HTBOTTOMLEFT,HTLEFT, HTTOPLEFTHTTOP,則返回HTBORDER。如果默認處理程序返回HTBOTTOMRIGHTHTTOPRIGHT,則返回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 *消息用於鼠標移動和點擊/向下/向上 - 並且通過您自己處理所有這些消息,可以製作您自己的尺寸例程。 –