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) .