如何从图形单元获取所有支持的文件格式?
当任何 TGraphic 后代使用类过程 TPicture.RegisterFileFormat() 注册其自己的图形文件格式时,它们都存储在 Graphics.FileFormats 全局变量中。
可惜 FileFormats 变量不在“Graphics.pas”的“界面”部分中,所以我无法访问它。我需要读取这个变量来为我的文件列表控件实现一个特殊的过滤器。
我可以在不手动修复 Graphics.pas 源代码的情况下获得该列表吗?
When any TGraphic descendant registering its own graphic file format with a class procedure TPicture.RegisterFileFormat(), they're all stored in Graphics.FileFormats global variable.
Too bad that FileFormats variable is not in the "interface" section of "Graphics.pas", so I can't access it. I need to read this variable to implement a special filter for my file-list control.
Can I get that list without manual fixing the Graphics.pas's source code?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您正在使用文件列表控件,因此可能是文件名列表。如果您不需要知道已注册的实际
TGraphic
类类型,只需知道给定的文件扩展名是否已注册(例如检查稍后是否调用TPicture.LoadFromFile ()
很可能会成功),您可以使用公共GraphicFileMask()
函数来获取已注册文件扩展名的列表,然后将您的文件名与该列表进行比较。例如:或者,您可以简单地加载文件并查看会发生什么:
更新:如果您想提取扩展名和描述,可以使用
TStringList.DelimitedText
来解析GraphicFilter()
函数的结果:更新 2: 如果您只对注册的图形文件扩展名列表感兴趣,则假设
List
是一个已经创建的TStrings
后代,使用这个:You are working with a file-list control, and presumably thus a list of filenames. If you don't need to know the actual
TGraphic
class types that are registered, only whether a given file extension is registered or not (such as to check if a later call toTPicture.LoadFromFile()
is likely to succeed), you can use the publicGraphicFileMask()
function to get a list of registered file extensions and then compare your filenames to that list. For example:Or, you could simply load the file and see what happens:
Update: if you want to extract the extensions and descriptions, you can use
TStringList.DelimitedText
to parse the result of theGraphicFilter()
function:Update 2: if you are just interested in a list of registered graphic file extensions, then, assuming
List
is an already createdTStrings
descendant, use this:GlScene 项目有一个单元 PictureRegisteredFormats.pas 实现了这一点。
The GlScene project has a unit PictureRegisteredFormats.pas that implements a hack for that.
这是一种替代方法,它可能比
GLScene
解决方案更安全。 这仍然是一个黑客,因为所需的结构是全局的,但在Graphics.pas
单元的实现部分中,但我的方法使用了少得多的“maigc常量”(很难-编码到代码中的偏移量)并使用两种不同的方法来检测Graphics.pas
中的GetFileFormats
函数。我的代码利用了
TPicture.RegisterFileFormat
和TPicture.RegisterFileFormatRes
都需要立即调用Graphics.GetFileFormats
函数这一事实。该代码检测相对偏移CALL
操作码并注册两者的目标地址。仅当两个结果相同时才继续前进,这增加了安全系数。另一个安全因素是检测方法本身:即使编译器生成的序言发生变化,只要调用的第一个函数是GetFileFormats
,该代码就会找到它。我不会将
“警告:当使用“使用调试 DCU”选项编译 Graphics.pas 时,这将崩溃。”
位于单元顶部(如>GLScene
代码),因为我已经使用调试 dcu 和无调试 dcu 进行了测试,并且它有效。还用包进行了测试,它仍然有效。此代码仅适用于 32 位目标,因此广泛使用
Integer
进行指针操作。一旦我安装了 Delphi XE2 编译器,我将尝试使其适用于 64 位目标。更新:支持 64 位的版本可以在这里找到:https://stackoverflow.com/a/35817804 /505088
Here's an alternative hack that might be safer then the
GLScene
solution. It's still a hack, because the desired structure is global but in the implementation section of theGraphics.pas
unit, but my method uses a lot less "maigc constants" (hard-coded offsets into the code) and uses two distinct methods to detect theGetFileFormats
function inGraphics.pas
.My code exploits the fact that both
TPicture.RegisterFileFormat
andTPicture.RegisterFileFormatRes
need to call theGraphics.GetFileFormats
function immediately. The code detects the relative-offsetCALL
opcode and registers the destination address for both. Only moves forward if both results are the same, and this adds a safety-factor. The other safety-factor is the detection method itself: even if the prologue generated by the compiler would change, as long as the first function called isGetFileFormats
, this code finds it.I'm not going to put the
"Warning: This will crash when Graphics.pas is compiled with the 'Use Debug DCUs' option."
at the top of the unit (as found in theGLScene
code), because I've tested with both debug dcu's and no debug dcu's and it worked. Also tested with packages and it still worked.This code only works for 32bit targets, hence the extensive use of
Integer
for pointer operations. I will attempt making this work for 64bit targets as soon as I'll get my Delphi XE2 compiler installed.Update: A version supporting 64 bit can be found here: https://stackoverflow.com/a/35817804/505088