您的位置:首页 > 其它

窗体皮肤实现 - 重绘窗体非客户区(二)

2014-09-06 01:38 246 查看
第一个实现了基本处理。窗体边框的宽度有些肥大,需要进行瘦身。

实现:

1、改变外框线宽度 ([b]WM_NCCALCSIZE)[/b]

2、改变外框样式 ([b]WM_WINDOWPOSCHANGING)[/b]

通过 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;


调整窗体样式

procedure TTest.ChangeSize;
var
hTmp: HRGN;
begin
/// 调整窗体样式
FChangeSizeCalled := True;
try
hTmp := FRegion;
try
/// 创建 倒角为3的矩形区域。
///    在这里可以实现不规则界面的创建,可以通过bmp创建绘制区域
///
///  注:
///    HRGN 句柄是是图形对象,由window管理的资源,不释放会出现内存泄露,
///    后果,你懂得。
FRegion := CreateRoundRectRgn(0, 0, FWidth, FHeight, 3, 3);
SetWindowRgn(Handle, FRegion, True);
finally
if hTmp <> 0 then
DeleteObject(hTmp); // 释放资源
end;
finally
FChangeSizeCalled := False;
end;
end;


调整后的最终效果,瘦身感觉不错还算精致。



代码下载: TestCaptionToolbar(v0.2).7z
http://pan.baidu.com/s/1jG64aFW https://github.com/cmacro/simple
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: