Creating a custom title bar and border at runtime, TMainMenu acts

I am working on a rather large project that uses custom forms and would like to draw the non-client area of ​​these forms myself. I can’t use vcl styles, because many forms must have a title and a border in the color selected at runtime, and as far as I know, styles are applied by design.

What I have done so far is to draw the title bar and border using the caption, disabling the minimize, maximize and close buttons and replace them with my own. I achieved this by intercepting the WM_NCPaint and WM_NCACTIVATE messages and calling my own procedure after the inherited keyword while processing WM_NCACTIVATE and sending the WM_ACTIVATE message without processing the WM_NCPAINT message as such:

SendMessage(Handle, WM_NCACTIVATE, ORD(active), -1);

The reason I did this was because I couldn’t get TMainMenu to draw sequentially, after passing through the code, the seemingly processed WM_NCACTIVATE message beautifully displays the main menu. Another approach I tried was to call UpdateItems in the main menu, but this did not produce any result.

I disabled the top right buttons by processing the WM_NCHITTEST message as such:

procedure TBasicForm.WMNCHITTEST(var message : TMessage);
begin
  inherited;
  case message.Result of
    HTMINBUTTONE, HTMAXBUTTON, HTCLOSE: message.Result := HTCAPTION;
  end;
end;

( , WM_NCACTIVATE), WM_NCLBUTTONDOWN, , . (, .

.

  • .
  • , .
  • ( ) .

, ? , - , , , , ?

, , - , .

, , WM_NCHITTEST, WM_NCACTIVATE WM_NCPAINT, .

...
procedure WMNCHITTEST(var message : TMessage); message WM_NCHITTEST;
procedure WMNCACTIVATE(var message : TMessage); message WM_NCACTIVATE;
procedure WMNCPAINT(var message : TMessage); message WM_NCPAINT;
...
implementation
...
procedure TBasicForm.WMNCHITTEST(var message : TMessage);
begin
  inherited;
  case message.Result of
    HTMINBUTTONE, HTMAXBUTTON, HTCLOSE: message.Result := HTCAPTION;
  end;
end;

procedure TBasicForm.WMNCACTIVATE(var message : TMessage);
begin
  inherited;
  Canvas.Brush.Style := bsSolid;
  Canvas.Brush.Color := clRed;

  Canvas.Rectangle(0, 0, Width, GetSystemMetric(SM_CYCAPTION) + GetSystemMetric(SM_CYBORDER));
  Canvas.Rectangle(0, 0, GetSystemMetric(SM_CXBORDER), Height);
  Canvas.Rectangle(Width - GetSystemMetric(SM_CXBORDER), 0, Width, Height);
  Canvas.Rectangle(Width - GetSystemMetric(SM_CXBORDER), Heigth - GetSystemMetric(SM_CYBORDER), Width, Height);
end;

procedure TBasicForm.WMNCPAINT(var message : TMessage);
begin
  SendMessage(Handle, WM_NCACTIVATE, ORD(active), -1);
end;
...

, , , ( , ), , . ( alt + f4) .

+4
1

, , Windows , . , .

. .

Q. , - draw , , - (TBitmap), , , Canvas. , .

. , .

. .

. ( ) .

Q , , , WM_WINDOWPOSCHANGING, WM_SIZE, WM_MOVE, WM_NCMOUSEMOVE, WM_NCLBUTTONDOWN, WM_NCRBUTTONDOWN ..

, VCL Styles, TFormStyleHook , , RegisterStyleHook

TStyleManager.Engine.RegisterStyleHook(TMyForm1, TMyCustomformStyleHook1);
TStyleManager.Engine.RegisterStyleHook(TMyForm2, TMyCustomformStyleHook2);
+4

Source: https://habr.com/ru/post/1542372/


All Articles