2016-07-07 56 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 *消息用于鼠标移动和点击/向下/向上 - 并且通过您自己处理所有这些消息,可以制作您自己的尺寸例程。 –