Delphi中如何实现DrawThemeBackground从右到左RTL方向绘制元素的全部技巧?

2026-04-10 02:531阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计477个文字,预计阅读时间需要2分钟。

Delphi中如何实现DrawThemeBackground从右到左RTL方向绘制元素的全部技巧?

我正在尝试从右到左绘制Explorer :: Treeview类的ttGlyphClosed元素(当BiDiMode是bdLeftToRight时)。我遇到一个问题,不知道如何使我的屏幕外位图透明。位图背景最初为白色。我正在使用以下代码:

我正在尝试从右到左绘制Explorer :: Treeview类的ttGlyphClosed元素(就像BiDiMode是bdLeftToRight时那样).我有一个问题,我不知道如何使我的屏幕外位图透明.位图的背景始终为白色.

Delphi中如何实现DrawThemeBackground从右到左RTL方向绘制元素的全部技巧?

我正在使用以下代码来镜像图像:

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(从右到左)渲染?

使用SetLayout作为TLama在他现在删除的答案中显示,在绘制之前切换画布的布局.

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).由于您无法知道图像在零件中的位置,因此无法更好地对齐它.

本文共计477个文字,预计阅读时间需要2分钟。

Delphi中如何实现DrawThemeBackground从右到左RTL方向绘制元素的全部技巧?

我正在尝试从右到左绘制Explorer :: Treeview类的ttGlyphClosed元素(当BiDiMode是bdLeftToRight时)。我遇到一个问题,不知道如何使我的屏幕外位图透明。位图背景最初为白色。我正在使用以下代码:

我正在尝试从右到左绘制Explorer :: Treeview类的ttGlyphClosed元素(就像BiDiMode是bdLeftToRight时那样).我有一个问题,我不知道如何使我的屏幕外位图透明.位图的背景始终为白色.

Delphi中如何实现DrawThemeBackground从右到左RTL方向绘制元素的全部技巧?

我正在使用以下代码来镜像图像:

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(从右到左)渲染?

使用SetLayout作为TLama在他现在删除的答案中显示,在绘制之前切换画布的布局.

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).由于您无法知道图像在零件中的位置,因此无法更好地对齐它.