Delphi 使用DrawThemeBackground绘图时,如何从右向左(RTL)方向绘制图元零件?
我试图从右向左绘制Delphi 使用DrawThemeBackground绘图时,如何从右向左(RTL)方向绘制图元零件?,delphi,winapi,right-to-left,windows-themes,uxtheme,Delphi,Winapi,Right To Left,Windows Themes,Uxtheme,我试图从右向左绘制Explorer::Treeview类的ttglyphmclosed元素(比如BiDiMode将是bdleftoright)。我有一个问题,我不知道如何使我的屏幕外位图是透明的。位图的背景始终为白色 我正在使用以下代码镜像图像: procedure TForm5.FormPaint(Sender: TObject); var bm: TBitmap; ARect: TRect; Details: TThemedElementDetails; begin
Explorer::Treeview
类的ttglyphmclosed
元素(比如BiDiMode
将是bdleftoright
)。我有一个问题,我不知道如何使我的屏幕外位图是透明的。位图的背景始终为白色
我正在使用以下代码镜像图像:
procedure TForm5.FormPaint(Sender: TObject);
var
bm: TBitmap;
ARect: TRect;
Details: TThemedElementDetails;
begin
if ExplorerTreeviewhTheme = 0 then
ExplorerTreeviewhTheme := OpenThemeData(0, 'Explorer::Treeview');
ARect := Rect(20, 20, 40, 40);
Details := ThemeServices.GetElementDetails(ttGlyphClosed);
DrawThemeBackground(ExplorerTreeviewhTheme, Canvas.Handle,
Details.Part, Details.State, ARect, nil); //Ok
bm := TBitmap.Create;
try
bm.Width := 20;
bm.Height := 20;
ARect := Rect(00, 00, 20, 20);
DrawThemeBackground(ExplorerTreeviewhTheme, bm.Canvas.Handle,
Details.Part, Details.State, ARect, nil);
// rendered result has white background
Canvas.Draw(60, 10, bm);
// rendered result is mirrored but has also white background
StretchBlt(Canvas.Handle, 100, 10, -20, 20, bm.Canvas.Handle, 0, 0, 20, 20, SRCCOPY);
finally
bm.Free;
end;
end;
问题是如何镜像由
DrawThemeBackground
函数绘制的元素(用于RTL读取)或如何使用此函数进行RTL(从右到左)渲染?您在stretchblt调用中使用了srccopy,但我认为您可能需要寻找替代方法,包括可能使用掩码
我已经有一段时间没有做过这件事了,所以我记不清了。使用
SetLayout
,正如特拉玛在他现在删除的答案中所示,在你画画之前切换画布的布局
function SetLayout(hdc: HDC; dwLayout: DWORD): DWORD; stdcall;
external 'gdi32' name 'SetLayout';
const
LAYOUT_RTL = $00000001;
procedure TForm1.FormPaint(Sender: TObject);
var
ExplorerTreeviewhTheme: HTHEME;
Details: TThemedElementDetails;
ARect: TRect;
Size: TSize;
begin
ExplorerTreeviewhTheme := OpenThemeData(Handle, 'Explorer::Treeview');
Details := ThemeServices.GetElementDetails(ttGlyphClosed);
GetThemePartSize(ExplorerTreeviewhTheme, Canvas.Handle, Details.Part,
Details.State, nil, TS_DRAW, Size);
ARect := Rect(20, 30, 20 + Size.cx, 30 + Size.cy);
// normal layout
DrawThemeBackground(ExplorerTreeviewhTheme, Canvas.Handle,
Details.Part, Details.State, ARect, nil);
// switched layout
SetLayout(Canvas.Handle, LAYOUT_RTL);
// calculate the rectangle for RTL as if it's in LTR
OffsetRect(ARect, 0, Size.cy); // align to the bottom of the first image so that we can see
ARect.Left := ClientWidth - ARect.Left - Size.cx;
ARect.Right := ARect.Left + Size.cx;
DrawThemeBackground(ExplorerTreeviewhTheme, Canvas.Handle,
Details.Part, Details.State, ARect, nil);
// restore layout
SetLayout(Canvas.Handle, 0);
CloseThemeData(ExplorerTreeviewhTheme);
end;
输出:
主题api绘制了一个6px宽的三角形,零件尺寸为16px(W7 aero)。由于无法知道零件中图像的位置,因此无法更好地对齐它