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?
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: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
The GlScene project has a unit PictureRegisteredFormats.pas that implements a hack for that.