Delphi/GDI+:设备上下文何时创建/销毁?

2024-03-24

通常在 Delphi 中使用 GDI+ 你可以使用绘画盒,并在期间进行绘画OnPaint event:

procedure TForm1.PaintBox1Paint(Sender: TObject);
var
   g: TGPGraphics;
begin
   g := TGPGraphics.Create(PaintBox1.Canvas.Handle);
   try
      g.DrawImage(FSomeImage, 0, 0);
   finally
      g.Free;
   end;
end;

这种范式的问题在于,创建一个破坏一个Graphics每次对象都是浪费且性能不佳。此外,还有一些GDI+ 中可用的构造 http://msdn.microsoft.com/en-us/library/ms534425.aspx你可以only当你有执着的时候使用Graphics object.

问题当然是when我可以创建那个吗Graphics目的?我需要知道句柄何时可用,以及何时不再有效。我需要这些信息,以便我可以创建和销毁我的Graphics object.


解决方案尝试一号

我可以通过在真正需要时创建它来解决创建问题 - 第一次油漆周期叫做:

procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
   if FGraphics = nil then
      FGraphics := TGPGraphics.Create(PaintBox1.Canvas.Handle);

   FGraphics.DrawImage(FSomeImage, 0, 0);
end;

但我必须知道设备上下文何时不再有效,这样我就可以销毁我的F图形对象,以便下次需要时重新创建它。如果由于某种原因绘画盒的设备上下文被重新创建,下次我将在无效的设备上下文上绘制OnPaint叫做。

Delphi 中的预期机制是什么让我知道什么时候设备上下文句柄 of a 绘画盒是被创建、被破坏还是被重新创建?


您不能使用标准 TPaintBox,因为 TPaintBox 有一个 TControlCanvas 类型的 Canvas,与此问题相关的成员如下:

TControlCanvas = class(TCanvas)
private
  ...
  procedure SetControl(AControl: TControl);
protected
  procedure CreateHandle; override;
public
  procedure FreeHandle;
  ...
  property Control: TControl read FControl write SetControl;
end;

问题是 FreeHandle 和 SetControl 不是虚拟的。

但是:TControlCanvas 在这里创建并分配:

 constructor TGraphicControl.Create(AOwner: TComponent);
 begin
   inherited Create(AOwner);
   FCanvas := TControlCanvas.Create;
   TControlCanvas(FCanvas).Control := Self;
 end;

因此,您可以做的是创建一个具有虚拟方法的降序 TMyControlCanvas 和一个像这样分配 Canvas 的 TMyPaintBox:

 constructor TMyPaintBox.Create(AOwner: TComponent);
 begin
   inherited Create(AOwner);
   FCanvas.Free;
   FCanvas := TMyControlCanvas.Create;
   TMyControlCanvas(FCanvas).Control := Self;
 end;

然后您可以使用 TMyControlCanvas 中的方法动态创建和销毁您的 TGPGraphics。

这应该能让你继续前进。

--jeroen

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Delphi/GDI+:设备上下文何时创建/销毁? 的相关文章

  • Delphi 是否在构造对象之前分配变量?

    Delphi 是否在对象完全构造之前分配实例变量 换句话说 给定一个变量 var customer TCustomer nil 然后我们构造一个客户并将其分配给变量 customer TCustomer Create 有没有可能custom
  • 如何检查文件是否有备用数据流?

    Delphi 有没有办法检查文件是否有任何备用数据流 看一下 Win32 APIFindFirstStreamW https msdn microsoft com en us library windows desktop aa364424
  • 从不同的形式调用过程

    我正在使用 Lazarus 我有一个名为TForm1单元名称为 Unit 1 在这里我有一个名为mergeDATfile a shortint 这会产生一些东西 顺便说一句 我必须创建另一个名为TForm2里面有按钮 Button1 当它被
  • Firebird 或 NexusDB

    我知道有很多与 Delphi 数据库相关的问题 但我只考虑这两个数据库 我需要查询大约 100 000 条记录 根据您的经验 哪个更快 作为嵌入式 as C S Thanks 我还没用过 Nexus tbh 但我经常使用 Firebird
  • 什么是代码页 0?

    我正在使用Delphi函数 StringCodePage 我在 COM 函数 Acrobat Annotation getContents 请参阅我的其他帖子 返回的字符串上调用它 它返回 0 0是什么 安西 代码页 0 是 CP ACP
  • java绕中心旋转矩形

    我想围绕其中心点旋转一个矩形 它应该保留在应该绘制的位置并在该空间中旋转 这是我的代码 AffineTransform transform new AffineTransform transform rotate Math toRadian
  • Spyder 内联绘图

    设置 Anaconda 2 0 0 Win 64 Spyder Anaconda 附带的 2 3 0rc 我配置图形 工具 gt 首选项 gt iPython 控制台 gt 图形 gt 图形后端 gt 内联 但无论我做什么 图形总是在单独的
  • 为什么不提高EInvalidPointer?

    德尔福文档状态 http docwiki embarcadero com Libraries en System SysUtils EInvalidPointer 切勿提出E无效指针直接异常 E无效指针由内存管理器内部引发 我正在编写一个自
  • 使用 IdTCPClient 和 IdTCPServer 发送和接收 TMemoryStream

    我在 XE2 中找到了 Remy Lebeau 的 IdTCP 组件聊天演示 我想玩一下 可以发现 我想使用这些组件发送图片 最好的方法似乎是使用 TMemoryStream 如果我发送字符串 连接工作正常 字符串传输成功 但是当我将其更改
  • 使用 Inno Setup 中格式化(部分粗体)的文本制作安装程序?

    有人看过 GOG com 游戏安装程序吗 如何制作像这样的欢迎文本字符串 包括单个标题中的路径和需要大小 其中部分内容加粗 以下是修改安装路径后如何更改字符串换行的示例 您可以使用TRichEditViewer http www jrsof
  • 使用faceting()时如何连接geom_point()和geom_line?

    我有一个问题 但我在互联网上没有找到任何相关信息 我很高兴得到一些提示 我有一个数据集 其中 x 轴是离散的 但我想将这些点相互连接 我可以做到 我的问题是当我添加分面选项时 我无法再将这些点相互链接起来 我找到了一个替代方案 但看起来不太
  • 从命令行增加 Delphi XE 项目版本号

    我有一个 Delphi XE 项目 我试图在使用 MSBuild 构建它之前更改程序的版本号 版本号信息位于 DPROJ 文件中 但如果我更改这些值 版本号不会更改 我认为原因是当您在 IDE 中更改版本号时 Delphi 会将更改保存到
  • 为什么变量被声明为 TStrings 并被创建为 TStringList?

    为什么变量声明为TStrings并创建为TStringList 例如 varsl被声明为TStrings但创建为TStringList var sl TStrings begin sl TStringList Create add stri
  • 如何在显示表单之前强制将焦点集中在组件上

    我必须展示 与ShowModal 一个有很多的表格TEdit但我想把注意力集中在TEdit 但并不总是相同 具体取决于上下文 我不能使用SetFocus之前ShowModal 因为表单未激活 并使用该组件Name or Tag在我的应用程序
  • 使用 gmail 和 Indy 发送电子邮件

    我正在尝试使用 gmail 从 Delphi 发送电子邮件 我有 Indy 10 5 9 0 和 Delphi XE3 我从以下位置获得了示例代码 http www andrecelestino com delphi xe envio de
  • 以高效的方式将字符串转换为十六进制

    我开发了以下函数将字符串转换为十六进制值 function StrToHex const S String String const HexDigits array 0 15 of Char 0123456789ABCDEF var I I
  • Delphi - 如何将通用参数传递给接受 const 参数数组的函数

    我有一个 基类 其中包含一个 函数 该函数接受 const 数组 类型的参数 如下所示 type TBaseClass class TObject public procedure NotifyAll const AParams array
  • Delphi RTTI,已发布的属性出现两次

    我想对属性使用属性 但这些属性偶尔会在继承的类中发生更改 这是一个示例代码 非常简化 TBaseClass class TObject private FFoo string published BaseAttirib hello prop
  • Delphi 如何与 Active Directory 集成?

    我们需要使用 Delphi 7 验证 Microsoft Active Directory 上的用户 最好的方法是什么 我们可以有两种情况 用户输入其网络用户名和密码 其中用户名可能包括域 然后我们检查活动目录是否是有效的活动用户 或者我们
  • 获取包含位图支持的画布的 Android 视图上的点的像素颜色值

    我正在尝试找出获取给定点上像素颜色值的最佳方法View http developer android com reference android view View html 我可以通过三种方式写入视图 我设置了背景图像View setBa

随机推荐

  • 为什么 Replace() 在我的 Python 函数中不起作用? [复制]

    这个问题在这里已经有答案了 这是实际代码 def replace exception chars string exception chars dict Old New old new exception chars keys list e
  • 如何更改时间选择器对话框片段的默认配色方案?

    我正在尝试更改时间选择器对话框片段的默认颜色 现在我不知道我应该做什么 这就是我设法将我的主题设置为 没有actionBar but this is the dialog i get 这是我的 xml 样式文件
  • 睡眠或暂停 NSThread

    我正在创建一个新线程 它每隔一定时间就运行我的方法之一 现在我正在做的事情如下 NSThread thread NSThread alloc initWithTarget self selector selector setUpTimerT
  • 如何向 clang-cl 添加 std=c++11 标志?

    我尝试在Windows下使用clang cl编译C 11程序 Clang cl 是 clang 的包装器 以便与 cl Visual Studio 编译器 更加兼容 我尝试添加 std c 11 and std c 11并且都被拒绝了 这并
  • Ruby on Rails:我的实际目标是什么?

    我一直在 Ruby on Rails 3 中构建应用程序 并且开始担心性能优化 现在我希望我的问题对于这个网站来说不太主观 但我对事实感兴趣 而不是讨论 所以这里是 虽然我试图让视图渲染得更快 但有一件事我根本不知道 我的目标是什么 给定一
  • 在同一活动中将数据片段传递给片段

    我有一些问题想询问有关在活动中将数据从一个片段传递到另一个片段的问题 我不知道该怎么做 有人可以帮忙吗 这是我的代码 ShareFragment java package com example user8 myapplication im
  • C - 两个指针之间的转换行为

    2020年12月11日更新 感谢 一些程序员老兄 在评论中的建议 我的根本问题是我们的团队正在实现动态类型存储引擎 我们分配多个字符数组 PAGE SIZE 缓冲区16 对齐存储动态类型的数据 没有固定的结构 出于效率原因 我们无法执行字节
  • 在 Windows 8 Metro 风格应用程序中,如何在应用程序未运行时更新动态磁贴?

    在 Windows 8 Metro 风格应用程序中 如何在应用程序未运行时更新动态磁贴 当操作系统开始启动时 动态磁贴开始运行 http blogs msdn com b windowsappdev archive 2012 04 16 c
  • Selenium Python 最小化浏览器窗口

    我知道如何从驱动程序对象调用最大化窗口的方法 driver maximize window 但是当我需要最小化浏览器窗口 隐藏它 时应该使用什么方法呢 实际上 驱动程序对象没有最大化窗口属性 我的目标是在浏览器窗口中默默地工作 我不想在我的
  • 如何从 docker 镜像中删除图层?

    我通过增量提交构建了一个 docker 映像 这导致在我的 docker 镜像中创建了很多层 随后镜像的大小变得非常大 有没有办法去除图层并从而减小图像的大小 任何帮助 将不胜感激 您可以尝试导出图像 然后再次导入 通过这种方式 所有图层都
  • TortoiseMerge 可以用作 Windows Git Bash 的 difftool 吗?

    我刚刚开始使用 Git 我想使用 TortoiseMerge 作为 difftool 和 mergetool In my HOME gitconfig我有以下部分 我已经删除了这个问题的用户和颜色部分 merge tool tortoise
  • 如何在android中以编程方式将视频发送到电子邮件

    我想从我的 Android 应用程序将 30 秒的视频发送到电子邮件 我已发送带有图像附件的电子邮件 但它不适用于视频 请帮助我做到这一点 提前致谢 send setOnClickListener new OnClickListener O
  • 针对依赖扩展对象的任务的 Gradle 插件最佳实践

    我希望获得有关定义依赖于外部状态的插件任务的最佳实践的反馈 即在引用插件的 build gradle 中定义 我使用扩展对象和闭包来推迟访问这些设置 直到它们需要且可用为止 我也对任务之间共享状态感兴趣 例如将一个任务的输出配置为另一任务的
  • 标签中提取内容 C# RegEx

    我有一个代码 string tag div string pattern string Format lt 0 gt
  • 2 个具有相同名称的 iPhone 应用程序。这怎么可能?

    As per iTunes Connect 开发人员指南 https itunesconnect apple com docs iTunesConnect DeveloperGuide pdf 1 应用程序名称应清晰 2 应用程序名称不应通
  • 根据属性值更改 VisualState

    如何根据 WP7 上的属性值更改 VisualState 我尝试使用 MVVM 模式 当我的模型加载时 我希望我的视图进入特定的 VisualState 在 Silverlight 中 我们有属性更改的触发器 但在 WP7 中没有 PS 我
  • 为什么 getline() 函数不起作用,除非我在函数 chamodifier 中调用它两次[重复]

    这个问题在这里已经有答案了 怎么了如果我在字符修饰符函数中仅使用一次 get line 函数 编译器将忽略它 除非我调用该函数两次 为什么我不能只使用一次 我尝试使用其他方法 它有效 但我想了解这个 我现在只是随机编写一些内容 这样添加更多
  • Laravel 5.5 Eloquent WhenLoaded 关系

    On the Laravel 5 5 文档 https laravel com docs 5 5 eloquent resources under 条件关系 它说 whenLoaded 方法可用于有条件地加载关系 我在我的代码中尝试过 pu
  • UIView 与容器视图

    这就是我想要解决的问题 In each viewController我正在尝试插入广告和实际的控制元素 我在 raywenderlinch com 上完成了几个教程 以了解人们如何专业地将广告放入他们的应用程序中 他们使用 UIViews
  • Delphi/GDI+:设备上下文何时创建/销毁?

    通常在 Delphi 中使用 GDI 你可以使用绘画盒 并在期间进行绘画OnPaint event procedure TForm1 PaintBox1Paint Sender TObject var g TGPGraphics begin