窗体边框基本的绘制和控制完成,在第二篇中主要遗留的问题。
- 标题区域图标和按钮没绘制
- 缩放时客户区显示有问题
解决完下面的问题,皮肤处理基本完整。大致的效果GIF
GIF中TShape的颜色表现有些问题,实际是正常的。
绘制标题区域内容
- 获取标题有效区域
- 绘制窗体图标
- 绘制按钮
- 绘制标题
标题区域主要考虑窗体是否在最大化状态,最大化后实际的标题绘制区域会有变化。可以通过 IsZoomed 或 GetWindowLong(Handle, GWL_STYLE) and WS_MAXIMIZE = WS_MAXIMIZE 的方式获取。
1 AMaxed := IsZoomed(Handle); // 获取窗体最大化状态 2 3 function TTest.GetCaptionRect(AMaxed: Boolean): TRect; 4 var 5 rFrame: TRect; 6 begin 7 rFrame := GetFrameSize; // 窗体上下左右的边框尺寸 8 // 最大化状态简易处理 9 if AMaxed then 10 Result := Rect(8, 8, FWidth - 9 , rFrame.Top) 11 else 12 Result := Rect(rFrame.Left, 3, FWidth - rFrame.right, rFrame.Top); 13 end;
绘制窗体图标稍微有些麻烦,需要获取窗体的Icon图标。窗体图标并不一定是程序图标。主要过程通过WM_GETICON 这个消息获取图标。
1 TmpHandle := THandle(SendMessage(Handle, WM_GETICON, ICON_SMALL, 0)); 2 if TmpHandle = 0 then 3 TmpHandle := THandle(SendMessage(Handle, WM_GETICON, ICON_BIG, 0));
如果上述方法无法获得,需要通过GetClassName 和 GetClassInfoEx 这2个API获取。
1 { Get instance } 2 GetClassName(Handle, @Buffer, SizeOf(Buffer)); 3 FillChar(Info, SizeOf(Info), 0); 4 Info.cbSize := SizeOf(Info); 5 6 if GetClassInfoEx(GetWindowLong(Handle, GWL_HINSTANCE), @Buffer, Info) then 7 begin 8 TmpHandle := Info.hIconSm; 9 if TmpHandle = 0 then 10 TmpHandle := Info.HICON; 11 end
上述这2种方法还是无法获取。那~~ 就没有办法了。如果非要绘制图标可以使用Application的图标进行代替。
1 Application.Icon.Handle
1 function TTest.GetIcon: TIcon; 2 var 3 IconX, IconY: integer; 4 TmpHandle: THandle; 5 Info: TWndClassEx; 6 Buffer: array [0 .. 255] of Char; 7 begin 8 /// 9 /// 获取当前form的图标 10 /// 这个图标和App的图标是不同的 11 /// 12 TmpHandle := THandle(SendMessage(Handle, WM_GETICON, ICON_SMALL, 0)); 13 if TmpHandle = 0 then 14 TmpHandle := THandle(SendMessage(Handle, WM_GETICON, ICON_BIG, 0)); 15 16 if TmpHandle = 0 then 17 begin 18 { Get instance } 19 GetClassName(Handle, @Buffer, SizeOf(Buffer)); 20 FillChar(Info, SizeOf(Info), 0); 21 Info.cbSize := SizeOf(Info); 22 23 if GetClassInfoEx(GetWindowLong(Handle, GWL_HINSTANCE), @Buffer, Info) then 24 begin 25 TmpHandle := Info.hIconSm; 26 if TmpHandle = 0 then 27 TmpHandle := Info.HICON; 28 end 29 end; 30 31 if FIcon = nil then 32 FIcon := TIcon.Create; 33 34 if TmpHandle <> 0 then 35 begin 36 IconX := GetSystemMetrics(SM_CXSMICON); 37 if IconX = 0 then 38 IconX := GetSystemMetrics(SM_CXSIZE); 39 IconY := GetSystemMetrics(SM_CYSMICON); 40 if IconY = 0 then 41 IconY := GetSystemMetrics(SM_CYSIZE); 42 FIcon.Handle := CopyImage(TmpHandle, IMAGE_ICON, IconX, IconY, 0); 43 FIconHandle := TmpHandle; 44 end; 45 46 Result := FIcon; 47 end;