第一個實現了基本處理。窗體邊框的寬度有些肥大,需要進行瘦身。
實現:
1、改變外框線寬度 (WM_NCCALCSIZE)
2、改變外框樣式 (WM_WINDOWPOSCHANGING)
通過 WM_NCCALCSIZE 消息可以實現目的。

procedure WMNCCalcSize(var message: TWMNCCalcSize); message WM_NCCALCSIZE; procedure TTest.WMNCCalcSize(var message: TWMNCCalcSize); const SIZE_BORDER = 5; SIZE_CAPTION = 28; begin // 改變邊框尺寸 with TWMNCCALCSIZE(Message).CalcSize_Params^.rgrc[0] do begin Inc(Left, SIZE_BORDER); Inc(Top, SIZE_CAPTION); Dec(Right, SIZE_BORDER); Dec(Bottom, SIZE_BORDER); end; Message.Result := 0; Handled := True; end;
窗體的四個角的表現樣式可以看出是XP的界面輪廓。倒角的幅度感覺有些大改小些。

調整外框樣式需要在窗體改變尺寸時進行處理,這種方法還可以實現不規則窗體。
WM_WINDOWPOSCHANGING 這個消息可以滿足需要。
處理是需要注意的問題:
1、因為是在調整過程中實際窗體的尺寸是無法通過 GetWindowRect 這個函數獲取調整后的狀態,因此需要保存有這個消息產生的窗體調整尺寸信息。
2、這個消息會有很多模式,這個消息的觸發來源 SetWindowPos 可以設置很多參數。我們只要處理窗體改變大小的模式,其他需要交由系統默認處理。
調用控件默認消息處理
procedure TTest.CallDefaultProc(var message: TMessage); begin /// /// 調用控件默認消息處理過錯 /// 為防止出現循環調用,需要使用狀態控制(FCallDefaultProc) /// if FCallDefaultProc then FControl.WindowProc(message) else begin FCallDefaultProc := True; FControl.WindowProc(message); FCallDefaultProc := False; end; end;
記錄窗體位置和尺寸,並對窗體進行調整外框樣式
procedure TTest.WMWindowPosChanging(var Message: TWMWindowPosChanging); var bChanged: Boolean; begin /// 由外部優先處理消息,完成以下默認的控制 CallDefaultProc(TMessage(Message)); Handled := True; bChanged := False; /// 防止嵌套 if FChangeSizeCalled then Exit; /// 調整窗體外框 /// 如果窗體尺寸有調整時需要重新生成窗體外框區域。 /// if (Message.WindowPos^.flags and SWP_NOSIZE = 0) or (Message.WindowPos^.flags and SWP_NOMOVE = 0) then begin if (Message.WindowPos^.flags and SWP_NOMOVE = 0) then begin FLeft := Message.WindowPos^.x; FTop := Message.WindowPos^.y; end; if (Message.WindowPos^.flags and SWP_NOSIZE = 0) then begin bChanged := ((Message.WindowPos^.cx <> FWidth) or (Message.WindowPos^.cy <> FHeight)) and (Message.WindowPos^.flags and SWP_NOSIZE = 0); FWidth := Message.WindowPos^.cx; FHeight := Message.WindowPos^.cy; end; end; if (Message.WindowPos^.flags and SWP_FRAMECHANGED <> 0) then bChanged := True; // 進行調整和重繪處理 if bChanged then begin ChangeSize; InvalidateNC; end; end;
調整窗體樣式
1 procedure TTest.ChangeSize; 2 var 3 hTmp: HRGN; 4 begin 5 /// 調整窗體樣式 6 FChangeSizeCalled := True; 7 try 8 hTmp := FRegion; 9 try 10 /// 創建 倒角為3的矩形區域。 11 /// 在這里可以實現不規則界面的創建,可以通過bmp創建繪制區域 12 /// 13 /// 注: 14 /// HRGN 句柄是是圖形對象,由window管理的資源,不釋放會出現內存泄露, 15 /// 后果,你懂得。 16 FRegion := CreateRoundRectRgn(0, 0, FWidth, FHeight, 3, 3); 17 SetWindowRgn(Handle, FRegion, True); 18 finally 19 if hTmp <> 0 then 20 DeleteObject(hTmp); // 釋放資源 21 end; 22 finally 23 FChangeSizeCalled := False; 24 end; 25 end;
調整后的最終效果,瘦身感覺不錯還算精致。

代碼下載: TestCaptionToolbar(v0.2).7z
http://pan.baidu.com/s/1jG64aFW
https://github.com/cmacro/simple
