Border around a form with rounded corner in c++ bu

2020-07-11 09:46发布

问题:

I have made a C++ Builder XE form with rounded corner with the help of the following code

BorderStyle = bsNone; 

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

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

It looks cool but the border is missing, I tried many thing but not get good result so please help me to draw border of color RGB(96,96,96)

And I want to make whole form dragable.

回答1:

1. Painting a dark grey border

This one's easy, depending on how complex you want the border to look. If you just want an outline in dark grey, either draw it using a combination of lines and arcs, or use the FrameRgn function to draw an outline around your region with a specific brush. Doing this is the best solution since you already have a region you've used to define the shape of the window.

However, the MSDN documentation for SetWindowRgn says, "After a successful call to SetWindowRgn, the system owns the region specified by the region handle hRgn. The system does not make a copy of the region. Thus, you should not make any further function calls with this region handle." You'll need to create your region again for the paint method.

Some code for your paint method:

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. Making the window draggable without its title bar

The short summary is that you need to handle the WM_NCHITTEST message. Windows sends this to see if the mouse is over the title bar ('NC' stands for 'non-client'; it's actually testing to see if it's anywhere in the non-client area, which can be any window border, not just the top one.) You can make your window draggable by saying 'yes, the mouse is in the caption right now' even when it isn't. Some code:

// 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;
  }
}

You can perform some hit testing of your own to restrict what parts of your window appear to be the title bar, in order to create a title bar of your own.

Example Delphi code.

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