如何将Delphi XE圆角窗口代码适配Delphi 2007并兼容Win7/8
问题解答
一、适配Delphi 2007及更早版本的修改方法
原代码无法在Delphi 2007及更早版本编译的核心原因是命名空间差异和部分API声明兼容性问题,具体修改点如下:
- 移除Winapi命名空间前缀
Delphi 2007及更早版本不使用Winapi.命名空间,直接引用原始单元名:
interface uses Windows; // 替换Winapi.Windows implementation uses Dwmapi; // 替换Winapi.Dwmapi
- 手动添加缺失的API声明
部分旧版本Delphi的Dwmapi单元未包含DwmSetWindowAttribute的声明,需在代码中手动添加函数原型:
// 在implementation段的常量定义后添加 function DwmSetWindowAttribute(hwnd: HWND; dwAttribute: DWORD; pvAttribute: Pointer; cbAttribute: DWORD): HRESULT; stdcall; external 'Dwmapi.dll';
- 类型与常量兼容检查
原代码中的Cardinal类型在Delphi 2007中可正常使用,所有常量定义无需修改。
修改后的完整单元代码:
unit delphi_rounded_corners; interface uses Windows; type TRoundedWindowCornerType = (RoundedCornerDefault, RoundedCornerOff, RoundedCornerOn, RoundedCornerSmall); procedure SetRoundedCorners(const TheHandle: HWND; const CornerType: TRoundedWindowCornerType); implementation uses Dwmapi; const DWMWCP_DEFAULT = 0; // 让系统决定是否启用圆角 DWMWCP_DONOTROUND = 1; // 强制禁用圆角 DWMWCP_ROUND = 2; // 适当情况下启用圆角 DWMWCP_ROUNDSMALL = 3; // 适当情况下启用小半径圆角 DWMWA_WINDOW_CORNER_PREFERENCE = 33; // 控制顶级窗口圆角策略的属性ID // 旧版Delphi需手动添加该函数声明 function DwmSetWindowAttribute(hwnd: HWND; dwAttribute: DWORD; pvAttribute: Pointer; cbAttribute: DWORD): HRESULT; stdcall; external 'Dwmapi.dll'; procedure SetRoundedCorners(const TheHandle: HWND; const CornerType: TRoundedWindowCornerType); var DWM_WINDOW_CORNER_PREFERENCE: Cardinal; begin case CornerType of RoundedCornerOff: DWM_WINDOW_CORNER_PREFERENCE := DWMWCP_DONOTROUND; RoundedCornerOn: DWM_WINDOW_CORNER_PREFERENCE := DWMWCP_ROUND; RoundedCornerSmall: DWM_WINDOW_CORNER_PREFERENCE := DWMWCP_ROUNDSMALL; else DWM_WINDOW_CORNER_PREFERENCE := DWMWCP_DEFAULT; end; DwmSetWindowAttribute(TheHandle, DWMWA_WINDOW_CORNER_PREFERENCE, @DWM_WINDOW_CORNER_PREFERENCE, sizeof(DWM_WINDOW_CORNER_PREFERENCE)); end; end.
二、Windows 7/8的兼容处理:必须动态调用DLL
Windows 7和8的DWM组件不支持DWMWA_WINDOW_CORNER_PREFERENCE(属性ID33),直接调用会返回运行时错误,因此必须通过动态加载DLL+系统版本判断实现兼容,修改方案如下:
unit delphi_rounded_corners; interface uses Windows; type TRoundedWindowCornerType = (RoundedCornerDefault, RoundedCornerOff, RoundedCornerOn, RoundedCornerSmall); procedure SetRoundedCorners(const TheHandle: HWND; const CornerType: TRoundedWindowCornerType); implementation type TDwmSetWindowAttribute = function(hwnd: HWND; dwAttribute: DWORD; pvAttribute: Pointer; cbAttribute: DWORD): HRESULT; stdcall; const DWMWCP_DEFAULT = 0; DWMWCP_DONOTROUND = 1; DWMWCP_ROUND = 2; DWMWCP_ROUNDSMALL = 3; DWMWA_WINDOW_CORNER_PREFERENCE = 33; procedure SetRoundedCorners(const TheHandle: HWND; const CornerType: TRoundedWindowCornerType); var hDwmApi: HMODULE; DwmSetWindowAttribute: TDwmSetWindowAttribute; DWM_WINDOW_CORNER_PREFERENCE: Cardinal; OSVersionInfo: TOSVersionInfo; begin // 仅在Windows 11及以上版本执行圆角设置(Win11内部版本号从22000开始) OSVersionInfo.dwOSVersionInfoSize := SizeOf(TOSVersionInfo); GetVersionEx(OSVersionInfo); if (OSVersionInfo.dwMajorVersion < 10) or (OSVersionInfo.dwMajorVersion = 10) and (OSVersionInfo.dwBuildNumber < 22000) then Exit; // 动态加载Dwmapi.dll hDwmApi := LoadLibrary('Dwmapi.dll'); if hDwmApi = 0 then Exit; try @DwmSetWindowAttribute := GetProcAddress(hDwmApi, 'DwmSetWindowAttribute'); if Assigned(DwmSetWindowAttribute) then begin case CornerType of RoundedCornerOff: DWM_WINDOW_CORNER_PREFERENCE := DWMWCP_DONOTROUND; RoundedCornerOn: DWM_WINDOW_CORNER_PREFERENCE := DWMWCP_ROUND; RoundedCornerSmall: DWM_WINDOW_CORNER_PREFERENCE := DWMWCP_ROUNDSMALL; else DWM_WINDOW_CORNER_PREFERENCE := DWMWCP_DEFAULT; end; DwmSetWindowAttribute(TheHandle, DWMWA_WINDOW_CORNER_PREFERENCE, @DWM_WINDOW_CORNER_PREFERENCE, sizeof(DWM_WINDOW_CORNER_PREFERENCE)); end; finally FreeLibrary(hDwmApi); end; end; end.
关键说明
- 通过系统版本判断,仅在Win11及以上版本执行圆角逻辑,避免Win7/8下的无效调用
- 动态加载Dwmapi.dll,避免静态链接导致的Win7/8下DLL加载失败问题
- 即使在Win11环境中,若函数获取失败(极端情况),也不会影响程序正常运行
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

