lcl, win32: use GetTextExtent as suggested in MSDN to get the correct text bounds before use of DrawThemeText() (issue #0021964)

git-svn-id: trunk@41646 -
This commit is contained in:
paul 2013-06-10 05:58:07 +00:00
parent da07c70180
commit 951d803183
4 changed files with 46 additions and 7 deletions

View File

@ -847,6 +847,7 @@ type
procedure DoShowWindow; override; procedure DoShowWindow; override;
procedure UpdateRegion; procedure UpdateRegion;
procedure SetColor(Value: TColor); override; procedure SetColor(Value: TColor); override;
function UseThemes: Boolean;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
destructor Destroy; override; destructor Destroy; override;

View File

@ -87,7 +87,7 @@ begin
if not HandleAllocated then if not HandleAllocated then
Exit; Exit;
if (Color = clInfoBk) or (Color = clDefault) then if UseThemes then
begin begin
Details := ThemeServices.GetElementDetails(tttStandardNormal); Details := ThemeServices.GetElementDetails(tttStandardNormal);
ARect := ClientRect; ARect := ClientRect;
@ -104,6 +104,11 @@ begin
UpdateRegion; UpdateRegion;
end; end;
function THintWindow.UseThemes: Boolean;
begin
Result := (Color = clInfoBk) or (Color = clDefault);
end;
function THintWindow.GetDrawTextFlags: Cardinal; function THintWindow.GetDrawTextFlags: Cardinal;
var var
EffectiveAlignment: TAlignment; EffectiveAlignment: TAlignment;
@ -150,7 +155,7 @@ var
Details: TThemedElementDetails; Details: TThemedElementDetails;
begin begin
ARect := ClientRect; ARect := ClientRect;
if (Color = clInfoBk) or (Color = clDefault) then if UseThemes then
begin begin
// draw using themes // draw using themes
Details := ThemeServices.GetElementDetails(tttStandardNormal); Details := ThemeServices.GetElementDetails(tttStandardNormal);
@ -243,11 +248,15 @@ begin
if AHint = '' then if AHint = '' then
begin begin
Result := Rect(0, 0, 0, 0); Result := Rect(0, 0, 0, 0);
exit; Exit;
end; end;
if MaxWidth <= 0 then if MaxWidth <= 0 then
MaxWidth := Screen.Width - 4 * HintBorderWidth; MaxWidth := Screen.Width - 4 * HintBorderWidth;
Result := Rect(0, 0, MaxWidth, Screen.Height - 4 * HintBorderWidth); Result := Rect(0, 0, MaxWidth, Screen.Height - 4 * HintBorderWidth);
if UseThemes then
Result := ThemeServices.GetTextExtent(Canvas.GetUpdatedHandle([csFontValid]),
ThemeServices.GetElementDetails(tttStandardNormal), AHint, DT_NOPREFIX or DT_WORDBREAK, @Result)
else
DrawText(Canvas.GetUpdatedHandle([csFontValid]), PChar(AHint), Length(AHint), DrawText(Canvas.GetUpdatedHandle([csFontValid]), PChar(AHint), Length(AHint),
Result, DT_CALCRECT or DT_NOPREFIX or DT_WORDBREAK); Result, DT_CALCRECT or DT_NOPREFIX or DT_WORDBREAK);
inc(Result.Right, 4 * HintBorderWidth); inc(Result.Right, 4 * HintBorderWidth);

View File

@ -37,6 +37,7 @@ type
function GetDetailRegion(DC: HDC; Details: TThemedElementDetails; const R: TRect): HRGN; override; function GetDetailRegion(DC: HDC; Details: TThemedElementDetails; const R: TRect): HRGN; override;
function GetStockImage(StockID: LongInt; out Image, Mask: HBitmap): Boolean; override; function GetStockImage(StockID: LongInt; out Image, Mask: HBitmap): Boolean; override;
function GetOption(AOption: TThemeOption): Integer; override; function GetOption(AOption: TThemeOption): Integer; override;
function GetTextExtent(DC: HDC; Details: TThemedElementDetails; const S: String; Flags: Cardinal; BoundingRect: PRect): TRect; override;
procedure DrawElement(DC: HDC; Details: TThemedElementDetails; const R: TRect; procedure DrawElement(DC: HDC; Details: TThemedElementDetails; const R: TRect;
ClipRect: PRect = nil); override; ClipRect: PRect = nil); override;
@ -280,6 +281,22 @@ begin
end; end;
end; end;
function TWin32ThemeServices.GetTextExtent(DC: HDC; Details: TThemedElementDetails;
const S: String; Flags: Cardinal; BoundingRect: PRect): TRect;
var
w: widestring;
begin
if ThemesEnabled then
with Details do
begin
w := UTF8ToUTF16(S);
GetThemeTextExtent(Theme[Element], DC, Part, State, PWideChar(W), Length(W),
Flags, BoundingRect, Result);
end
else
Result := inherited GetTextExtent(DC, Details, S, Flags, BoundingRect);
end;
function TWin32ThemeServices.UseThemes: Boolean; function TWin32ThemeServices.UseThemes: Boolean;
begin begin
Result := UxTheme.UseThemes and (GetFileVersion(comctl32) >= ComCtlVersionIE6); Result := UxTheme.UseThemes and (GetFileVersion(comctl32) >= ComCtlVersionIE6);

View File

@ -479,6 +479,7 @@ type
function GetDetailRegion(DC: HDC; Details: TThemedElementDetails; const R: TRect): HRGN; virtual; function GetDetailRegion(DC: HDC; Details: TThemedElementDetails; const R: TRect): HRGN; virtual;
function GetStockImage(StockID: LongInt; out Image, Mask: HBitmap): Boolean; virtual; function GetStockImage(StockID: LongInt; out Image, Mask: HBitmap): Boolean; virtual;
function GetOption(AOption: TThemeOption): Integer; virtual; function GetOption(AOption: TThemeOption): Integer; virtual;
function GetTextExtent(DC: HDC; Details: TThemedElementDetails; const S: String; Flags: Cardinal; BoundingRect: PRect): TRect; virtual;
function ColorToRGB(Color: LongInt; Details: PThemedElementDetails = nil): COLORREF; function ColorToRGB(Color: LongInt; Details: PThemedElementDetails = nil): COLORREF;
function ContentRect(DC: HDC; Details: TThemedElementDetails; BoundingRect: TRect): TRect; virtual; function ContentRect(DC: HDC; Details: TThemedElementDetails; BoundingRect: TRect): TRect; virtual;
@ -821,7 +822,8 @@ end;
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
function TThemeServices.GetElementDetails(Detail: TThemedListview): TThemedElementDetails; function TThemeServices.GetElementDetails(Detail: TThemedListView
): TThemedElementDetails;
var var
Base: Integer; Base: Integer;
begin begin
@ -1911,6 +1913,16 @@ begin
end; end;
end; end;
function TThemeServices.GetTextExtent(DC: HDC; Details: TThemedElementDetails;
const S: String; Flags: Cardinal; BoundingRect: PRect): TRect;
begin
if Assigned(BoundingRect) then
Result := BoundingRect^
else
Result := Rect(0, 0, 0, 0);
LCLIntf.DrawText(DC, PChar(S), Length(S), Result, DT_CALCRECT or Flags);
end;
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
function TThemeServices.ColorToRGB(Color: LongInt; Details: PThemedElementDetails = nil): COLORREF; function TThemeServices.ColorToRGB(Color: LongInt; Details: PThemedElementDetails = nil): COLORREF;