使用启用了Aero Glass的DwmExtendFrameIntoClientArea
API调用就可以了。但是,我希望它在Aero Glass被禁用时也能正常工作,就像它在Windows控制面板中的工作方式一样:
注意框架是如何扩展到客户区的,即使Aero Glass被禁用了?当我在我的应用程序中进行DwmExtendFrameIntoClientArea
API调用时,返回的HRESULT肯定不会成功,我的应用程序最终看起来像这样:
http://img197.imageshack.us/img197/9629/clientapplication.png
通常情况下,启用Aero Glass后,边框会向下延伸到导航按钮下方,就像在控制面板中一样。我该怎么做呢? DwmExtendFrameIntoClientArea
显然无效。
顺便说一句,如果它是相关的,我的应用程序是一个WPF应用程序。
答案 0 :(得分:7)
Nir的回答是正确的;当组合被禁用时,你必须自己绘制该区域。
我可以向我展示我在表单顶部的面板的绘制处理程序中的代码 - 通常负责绘制0x00000000透明黑色以使玻璃显示的面板:
procedure DrawGlassHeaderArea(g: Graphics; r: Rectangle; IsFormFocused: Boolean);
const
clFakeGlassColor = $00EAD1B9; //(185, 209, 234) This is the fake foreground glass color (for use when composition is disabled)
clFakeGlassColorUnfocused = $00F2E4D7; //(215, 228, 242) This is the fake background glass color (for use when composition is disabled)
begin
if Dwm.IsCompositionEnabled then
begin
g.FillRectangle(r, 0x00000000); //fill rectangle with transparent black
end
else
//Composition disabled; fake it like Microsoft does
//The color to use depends if the form has focused or not
Color glassColor;
if (IsFormFocused) then
c = clFakeGlassColor
else
c = clFakeGlassColorUnfocused;
g.FillRectangle(r, glassColor); //fill rectangle with fake color
//Now we have to draw the two accent lines along the bottom
Color edgeHighlight = ColorBlend(Colors.White, glassColor, 0.33); //mix 33% of glass color to white
Color edgeShadow = ColorBlend(Colors.Black, glassColor, 0.33); //mix 33% of glass color to black
//Draw highlight as 2nd-last row:
g.DrawLine(edgeHighlight, Point(r.Left, r.Bottom-2), Point(r.Right, r.Bottom-2);
//Draw shadow on the very last row:
g.DrawLine(edgeHighlight, Point(r.Left, r.Bottom-1), Point(r.Right, r.Bottom-1);
end;
end;
procedure MyForm.PaintBox1Paint(PaintEventArgs e)
begin
DrawGlassHeaderArea(e.Graphics, PaintBox1.ClientRectangle, this.HasFocus);
end;
@JakePetroules是对的,我错了。用于假玻璃的“blue” 不硬编码到Windows中。使用GetThemeColor
可以访问 。
我为 Window 类编制了所有可用的颜色(TMT_COLOR
):
注意:有关类,部件和状态的详细信息,请参阅Aero Style Classes, Parts, and States
使用时:
Window
WP_CAPTION
并获取颜色代码 propertyID :
TMT_FILLCOLORHINT
:当窗口具有焦点时TMT_BORDERCOLORHINT
:当窗口没有焦点时你得到两个重要的颜色:
我现在使用伪代码来获取假玻璃颜色:
public Color GetFakeClassColor(Boolean isWindowFocused=true)
{
static Color fakeGlass= 0x00B8D0E9; //the correct answer anyway
if ((GetThemeAppProperties() && STAP_ALLOW_CONTROLS) == 0)
return fakeGlass;
hTheme = OpenThemeData(GetDesktopWindow(), "Window");
if (hTheme = 0)
return fakeGlass;
Int32 propID;
if (isWindowFocused)
propID= TMT_FILLCOLORHINT; //The color used as a fill color hint for custom controls.
else
propID= TMT_BORDERCOLORHINT; //The color used as a border color hint for custom controls.
DWORD rgb;
if (Failed(GetThemeColor(hTheme, WP_CAPTION, 0, propID, ref rgb))
return fakeGlass;
Result = new Color(rgb);
}
实际上,因为我使用Delphi,我的实际代码是:
function GetFakeGlassColor(IsWindowFocused: Boolean=True): TColor;
var
ted: TThemedElement;
hTheme: THandle;
propID: Integer;
rgb: DWORD;
begin
Result := $00B8D0E9; //the correct answer anyway
//We can't use the ThemeServcies.ThemesEnabled, as that mistakenly checks for version 6 of the common controls library
//Themes can be enabled without using ComCtl V6, or common controls at all
if not ThemeServices.ThemesAvailable then
Exit;
if (GetThemeAppProperties and STAP_ALLOW_CONTROLS) = 0 then
Exit;
htheme := ThemeServices.Theme[teWindow];
if hTheme = 0 then
Exit;
if IsWindowFocused then
propID := TMT_FILLCOLORHINT //The color used as a fill color hint for custom controls.
else
propID := TMT_BORDERCOLORHINT; //The color used as a border color hint for custom controls.
if Failed(GetThemeColor(hTheme, WP_CAPTION, 0, propID, {var}rgb)) then
Exit;
Result := rgb;
end;
答案 1 :(得分:2)
你必须自己把它描绘成框架状。
您必须使用DwmIsCompositionEnabled
检查DWM是否已启用并处理WM_DWMCOMPOSITIONCHANGED
以检测DWM状态是否已更改。
然后你必须分开绘制窗口的方式,如果启用DWM则使用DwmExtendFrameIntoClientArea
,如果禁用,则自己绘制“框架”。
我不知道如何在WPF中复制Aero框架(在我的应用程序中我有自己的配色方案而我没有使用Auro框架。)
这很烦人但是当DWM被禁用时,系统会回退到XP风格的绘图,并且DWM的服务都不起作用 - 即使那些与玻璃效果无关的服务也是如此。
答案 2 :(得分:2)
您需要自己绘制窗口背景。您不应该像以前的帖子建议的那样对颜色进行硬编码,而是使用主题函数来检索它们,如下所示(半伪代码):
DWORD rgb;
HANDLE hTheme = OpenThemeData(GetDesktopWindow(), L"WINDOW");
GetThemeColor(hTheme, WP_CAPTION, CS_ACTIVE,
<is active window> ? TMT_FILLCOLORHINT : TMT_BORDERCOLORHINT, &rgb);
// Can use these functions to retrieve the individual RGB values
BYTE r = GetRValue(rgb);
BYTE g = GetGValue(rgb);
BYTE b = GetBValue(rgb);
即使用户更改控制面板中的标题栏颜色(与使用COLOR_ACTIVECAPTION / COLOR_GRADIENTACTIVECAPTION不同),这些颜色仍将保持正确。在尝试获取主题颜色之前,您还应该使用IsThemeActive()
检查主题是否处于活动状态。
用于快速参考的常量值: