【问题标题】:Border around a form with rounded corner in c++ builder XEc++ builder XE中圆角表单的边框
【发布时间】:2011-09-04 16:08:11
【问题描述】:

借助以下代码,我制作了一个带有圆角的 C++ Builder XE 表单

BorderStyle = bsNone; 

void __fastcall TForm1::FormCreate(TObject *Sender)
{
     HRGN frmrgn;  

     frmrgn = CreateRoundRectRgn (0, 0, ClientWidth, ClientHeight,12,12);
     SetWindowRgn(Handle,frmrgn,true);
}

它看起来很酷,但是没有边框,我尝试了很多东西但没有得到很好的结果 所以请帮我绘制颜色 RGB(96,96,96) 的边框

我想让整个表单可以拖动。

【问题讨论】:

  • 我不知道,但BorderStyle = bsNone; 听起来你要求没有边界。如果您选择其他样式怎么办?
  • 这个问题的答案可能会对你有所帮助:stackoverflow.com/questions/5755719/…
  • @Bo Persson:BorderStyle 属性仅影响标准 Windows 矩形窗口边框。由于窗口有弯角,默认边框将被剪裁,看起来很奇怪——这就是@rudasgani 需要绘制自定义边框的原因。

标签: border c++builder drag rounding c++builder-xe


【解决方案1】:

1。绘制深灰色边框

这很简单,具体取决于您希望边框看起来有多复杂。如果您只想要深灰色的轮廓,可以使用线条和弧线的组合来绘制它,或者使用FrameRgn 函数使用特定的画笔在您的区域周围绘制轮廓。这样做是最好的解决方案,因为您已经有一个用于定义窗口形状的区域。

但是,SetWindowRgn 的 MSDN 文档说,“在成功调用 SetWindowRgn 后,系统拥有由区域句柄 hRgn 指定的区域。系统不会复制区域。因此,您不应使用此区域句柄进行任何进一步的函数调用。"您需要为绘制方法再次创建您的区域。

绘制方法的一些代码:

HRGN hRegion = ::CreateRoundRectRgn (0, 0, ClientWidth, ClientHeight,12,12);
Canvas->Brush->Style = bsSolid;
Canvas->Brush->Color = RGB(96, 96, 96);
::FrameRgn(Canvas->Handle, hRegion, Canvas->Brush->Handle, 2, 2);
::DeleteObject(hRegion); // Don't leak a GDI object

2。使窗口在没有标题栏的情况下可拖动

简短的总结是您需要处理WM_NCHITTEST 消息。 Windows 发送这个来查看鼠标是否在标题栏上(“NC”代表“非客户端”;它实际上是在测试它是否在非客户端区域中的任何位置,可以是任何窗口边框,而不仅仅是第一个。)您可以通过说“是的,鼠标现在在标题中”来使窗口可拖动,即使它不在。一些代码:

// In the 'protected' section of your form's class declaration
virtual void __fastcall WndProc(Messages::TMessage &Message);

// The implementation of that method:
void __fastcall TForm1::WndProc(Messages::TMessage& Message) {
  TForm::WndProc(Message); // inherited implementation
  if (Message.Msg == WM_NCHITTEST && Msg.Result == htClient) {
    Msg.Result = htCaption;
  }
}

您可以自己执行一些命中测试来限制窗口的哪些部分显示为标题栏,从而创建自己的标题栏。

Example Delphi code.

A good article about using this message, and things to be aware of / traps not to fall into.

【讨论】:

  • 非常非常非常非常感谢兄弟你的回答对我来说很有价值第一个正是我想要的但另一个有点令人困惑我必须做一些锻炼才能理解它但兄弟再次感谢请帮助未来的我也
  • 感谢大家对我的问题感兴趣,谢谢
  • 不客气。第二个有什么不明白的?如果是消息,这里有一些起始链接:en.wikipedia.org/wiki/Message_loop_in_Microsoft_Windows(关于消息和一般的“消息循环”)、msdn.microsoft.com/en-us/library/ms644927%28v=VS.85%29.aspx(MSDN 文档)和docwiki.embarcadero.com/VCL/en/Controls.TWinControl.WndProc(上面的窗口过程——记住 VCL 是面向对象的并且是 Windows 的低级消息循环/一般结构的包装器。)
  • 再次感谢兄弟,我不明白的消息,因为我以前没有在我的程序中使用它,但你提供的链接非常有用谢谢
  • @rudasagani:如果这个答案有帮助(听起来很像!)你能把它标记为答案吗?单击问题分数附近的复选标记/刻度线。在 SO 上,这有助于提高人们的声誉,无论是回答者(我)还是提问者(你——你都会在你的名字附近得到一个百分比,说明你标记为已接受的问题数量,如果这个百分比很低,人们不太可能回答你。 )
猜你喜欢
  • 2020-12-02
  • 1970-01-01
  • 2012-06-24
  • 1970-01-01
  • 1970-01-01
  • 2011-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多