dcsimg
Results 1 to 39 of 39

Thread: [RESOLVED] Structure of FRX files

  1. #1

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,446

    Resolved [RESOLVED] Structure of FRX files

    This is certainly a long-term project, but I'm now interested in the structure of FRX files. Here's what I know about them (or what I think I know).

    • Any property that's non-ANSI will be placed in the FRX file.
    • Any property that might actually be ANSI but is quite large, will be placed in the FRX file. I don't know the size limit.
    • Pictures, icons, and the like will be placed in these FRX files.
    • We can put our own information into them via a UserControl by defining the property as a Variant.
    • Even arrays placed into Variants will work, and be placed into these FRX files.
    • The FRM file gets the information out with a "SomeForm.frx":0000 where the 0000 is an offset into the FRX file.
    • There doesn't seem to be any header within these FRX files.


    Now, here's what I don't know:

    • How is all the information placed into these FRX files?
    • Is it the same as it's placed into a RES file?
    • Is it the same as if we were to write the information into a file opened Binary?
    • Is each piece of information followed by some terminator?
    • Sometimes, the FRX references in the FRM file look like: $"SomeForm.frx":0000. Does the dollar-sign indicate we're looking for a string?
    • If we're looking for a string, are they Unicode?
    • If we're looking for a string, they must be terminated. Are they null terminated?


    Specifically, I'm considering writing an FRX string editor. This editor would allow one to edit the strings in an FRX file and then save them, possibly saving a longer string than the original string. I'd need to reliably find the strings, know how to re-save them, and also know how to reliably patch up the offsets in the FRM file.

    Any insights would be greatly appreciated.

    Elroy
    Any software I post in these forums written by me is provided AS IS without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that Ive been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a VB6 random code folder that is overflowing. Ive been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  2. #2
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: Structure of FRX files

    Are FRX's similar to property bags?

  3. #3

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,446

    Re: Structure of FRX files

    Hi Dex,

    Well, I think of FRX files as an extension of the property bags. Property bags are a memory thing, whereas FRM and FRX files are on disk. I'd say that the non-code part of a FRM file, combined with the FRX file, makes up the property bag.

    Best Regards,
    Elroy

    Also, any FRM/FRX pair will typically have many property bags of information.
    Any software I post in these forums written by me is provided AS IS without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that Ive been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a VB6 random code folder that is overflowing. Ive been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  4. #4
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,000

    Re: Structure of FRX files

    Do some searches.

    There are a number of threads on this topic where people have tried to decipher what the format of these private propertybag structures is. You might get a few answers there, or better yet (since I doubt it has been fully cracked) the benefit of some of the guesses. They are propertybags of propertybags.

    PropertyBags are all about serialization, for either transmission or persistence to disk. They are not a "memory thing."

  5. #5
    Hyperactive Member
    Join Date
    Apr 2017
    Posts
    415

    Re: Structure of FRX files

    Here's what little I know

    I have a Form with two picture boxes, Picture1 and Picture2. Picture1 was loaded with a .bmp and Picture2 was loaded with a .gif.

    Now, I looked at the Form.frm file and I found this:

    Code:
       Begin VB.PictureBox Picture2 
          Height          =   1335
          Left            =   3165
          Picture         =   "Form1.frx":0000
          ScaleHeight     =   1275
          ScaleWidth      =   1395
          TabIndex        =   2
          Top             =   1755
          Width           =   1455
       End
       Begin VB.PictureBox Picture1 
          Height          =   915
          Left            =   1650
          Picture         =   "Form1.frx":08CA
          ScaleHeight     =   855
          ScaleWidth      =   1215
          TabIndex        =   1
          Top             =   1335
          Width           =   1275
       End
    Those numbers in red are the offsets in the .FRX file for those two images.

    So, I open Form1.frx and I find this:

    At offset 0000:
    C6 08 00 00 6C 74 00 00 BE 08 00 00 GIF8

    At offset 08CA:
    26 27 04 00 6C 74 00 00 1E 27 04 00 BM

    The header appears to be 12-bytes followed by the actual image data

    Ok, so what does this header info mean?

    Well, knowing a little about computer numbers I knew something about number being in
    some sort of reverse order (I think it's called Little Indian or Big Indian, IDK which is which)
    and I also knew that somewhere in this string of mumble jumbo hex there had to be the size of the
    image data. So I right mouse clicked on the two image files on the disk at looked at their
    properties to get the data size.

    The .gif file has a sise of 2,738 and the .bmp has a size of 272,158

    So I converted these sizes to hex and I get this:

    2,738 = &H08BE and 272,158 = &H04271E

    If you reverse the digits in the header on every 4-bytes you get this:

    C6 08 00 00 | 6C 74 00 00 | BE 08 00 00 | GIF8

  6. #6

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,446

    Re: Structure of FRX files

    Nice work CD.

    I think you're right about a 12 byte header to each entry (but no overall header).

    Just to clear a bit up too. It's Endian, not Indian. Also, Endian typically refers to bits, but it's also sometimes used to refer to bytes. And basically, Little-Endian = smaller parts of a number are lower in memory (and vice-versa). Big-Endian = larger parts of the number are lower in memory (and vice-versa), i.e., reversed. VB6 handles pretty much everything as Little-Endian. (One exception is the Decimal type, which is a Mixed-Endian.)

    Hmmm, upon further inspection, it appears that you sometimes only get a four-byte header, that's only the size. Also, it appears that the offsets are HEX.

    Here's a screenshot of an FRX with two RTF strings in it. The two offsets from the FRM are 0000 and 0120.

    Name:  Hexfrx.jpg
Views: 1658
Size:  94.7 KB

    EDIT1: Also, clearly, strings are not null terminated. If all I want to edit is strings, this might be all I need to know, but not sure.
    Any software I post in these forums written by me is provided AS IS without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that Ive been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a VB6 random code folder that is overflowing. Ive been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  7. #7
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: Structure of FRX files

    are there 284 ASCII Chars in that rtf string?

    also endian refers to how bytes line up MSB to LSB.

  8. #8
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,026

    Re: Structure of FRX files

    @Elroy. In the code bank, I have a project to extract images from frx, ctx, etc. There are some notes/comments in the code that may help regarding extraction of other stuff. Do note that lots of stuff can be in those files: list/combo items, byte arrays, large string values and more.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  9. #9

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,446

    Re: Structure of FRX files

    Ahhh, LaVolpe, precisely what I was looking for.

    Do we know that, if I make a string longer and just shift everything out, and then patch up the offsets in the FRX, are we good to go? Do we have to do any kind of alignment (four byte, etc.)?

    I'll definitely look at your project. It looks like a fast-running start on what I'm trying to do.

    Thanks,
    Elroy
    Any software I post in these forums written by me is provided AS IS without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that Ive been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a VB6 random code folder that is overflowing. Ive been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  10. #10

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,446

    Re: Structure of FRX files

    Arghhh. LaVolpe, you are specifically looking for images. That's definitely cool, but I'm more interested in the strings.

    Also, the http://btmtz.mvps.org/gfxfromfrx/ site you mention in your code is gone.

    It's still a good start. I've cut out the RES stuff so I can focus exclusively on FRX files.

    You basically scan every byte for the double-word of &H0000746C. I believe I've got to take a different approach of bouncing from item to item to also find the strings.

    I'm hoping to just enhance your tree structure to also include a Strings section.

    Best Regards,
    Elroy
    Any software I post in these forums written by me is provided AS IS without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that Ive been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a VB6 random code folder that is overflowing. Ive been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  11. #11

  12. #12
    Fanatic Member
    Join Date
    Aug 2013
    Posts
    805

    Re: Structure of FRX files

    There are several PSC projects that claim to parse strings out of FRX files:

    http://planet-source-code.com/vb/scr...58907&lngWId=1
    http://planet-source-code.com/vb/scr...62437&lngWId=1

    (Use at your own risk, etc)
    Check out PhotoDemon, a pro-grade photo editor written completely in VB6. (Full source available at GitHub.)

  13. #13

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,446

    Re: Structure of FRX files

    Thanks Dex. However, it turns out, that code is only focusing on pics as well. I sort of suspected that though.

    I think I'm getting these FRX files sorted though. Each frx-item just has a four-byte header, and it's the size. If it's a picture, there's an additional header, and LaVolpe's code handles all of that.

    But I need to back up and focus on that initial header (i.e., size), and that's how I'll find the strings. For these FRX files, it seems that, if it's not a pic, it's a string, no other alternative. I say this because there is no additional header on the strings.
    Any software I post in these forums written by me is provided AS IS without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that Ive been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a VB6 random code folder that is overflowing. Ive been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  14. #14

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,446

    Re: Structure of FRX files

    Nice Tanner. I've grabbed them.

    Thanks,
    Elroy
    Any software I post in these forums written by me is provided AS IS without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that Ive been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a VB6 random code folder that is overflowing. Ive been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  15. #15
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,026

    Re: Structure of FRX files

    Quote Originally Posted by Elroy View Post
    For these FRX files, it seems that, if it's not a pic, it's a string, no other alternative. I say this because there is no additional header on the strings.
    Wouldn't bet on it. Fonts (stdFont objects) and byte arrays can exist in there along with List & ItemData properties of combo/listboxes. I'm sure there are other things that can be saved there too.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  16. #16
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,026

    Re: Structure of FRX files

    Elroy, gotta ask. Where do you see this project going?

    Typically, someone wants to edit a string, they'd open their project and edit the property and save. I'd think building a project that attempts to read another project's frm/frx files for outside editing wouldn't be in high demand. Maybe there's a niche somewhere? Even in that project I created that extracts image content, the only niche I foresaw were scenarios where a project could not be loaded, i.e., corrupted frm file for example, with assumption the frx isn't corrupted.

    Simply extracting a string, for example, editing it and updating the frx correctly will likely not be enough. What if the string is for a label, button or some other control's caption property? Couldn't that negatively affect the appearance of that control (clipping, wordwrap, etc)? If so, the user would likely need to load the project in VB anyway to adjust appearance.

    No reply necessary. Just pointing out that I think real-world usage of such a project is likely low. However, I enjoy puzzles and if the main reason for this was self-education, then I completely understand.

    Edited: This link may be helpful? It's in PowerBasic though
    https://forum.powerbasic.com/forum/u...resource-files
    Last edited by LaVolpe; Aug 22nd, 2017 at 03:39 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  17. #17
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: Structure of FRX files

    @LaVolpe: nice google-fu.

    The PB Code doesn't actually walk the frx, it walks the frm.
    Last edited by DEXWERX; Aug 22nd, 2017 at 04:00 PM.

  18. #18
    PowerPoster
    Join Date
    Jun 2013
    Posts
    4,189

    Re: Structure of FRX files

    I've implemented such a thing quite recently and also already published it here embedded in the Zip in post #22 in the following thread:
    http://www.vbforums.com/showthread.p...=1#post5168415

    To the best of my knowledge, this is the most sophisticated one of the whole bunch...
    (have looked at quite a few other frx-Parsers - found them all lacking, and finally wrote one)

    I think it is currently the only parser, which does not need any "hints" from the
    accompanying *.frm or *.ctl Files (about the Control- or Property-Type, or at which Offset an entry starts).

    One can feed it a standalone *.frx, or a *.ctx, let it do its work -
    and after it is through with the Parsing, one can enumerate and query the Parser-Class
    about the content and content-types it has found.


    The Content-Retrieval-Function will always hand out a ByteArray (no matter whether the
    entry-type was an Image, or a Text, or RTFText or a List or Binary.

    The different entry-types can also be queried (identify themselves over an Enum).
    Public Enum eEntryType
    frxBinary
    frxImage
    frxTextA
    frxTextW
    frxTextRTF
    frxList
    End Enum


    In case an entry is of type frxImage, one can query additional info about the ImageType over:
    Property Get ImageExtensionByIndex(ByVal IndexZeroBased As Long) As String

    Below I'm posting the code of the cFRX-Class again (it currently depends on the cStream-Class
    from vbRichClient, but this can be replaced by ones own Stream-Implementation, or by
    "ByteArrayBased-StreamLike-Functions" in a *.bas module or something.

    Code:
    Option Explicit 'Parser for *.frx- and *.ctx-Files (Olaf Schmidt, 2017)
    
    Public Enum eEntryType
      frxBinary
      frxImage
      frxTextA
      frxTextW
      frxTextRTF
      frxList
    End Enum
    
    Private Type tFrxEntry
      EntryType As eEntryType
      Offset As Long
      Length As Long
      Content() As Byte
      ImageExtension As String
    End Type
    
    Private mFileName As String, mShortFileName As String, EntriesCount As Long, Entries() As tFrxEntry, Strm As cStream
    
    Public Sub Parse(FileName As String)
      mFileName = FileName
      mShortFileName = New_c.FSO.GetFileNameFromFullPath(FileName)
      EntriesCount = 0: Erase Entries
      Set Strm = New_c.FSO.OpenFileStream(FileName, STRM_READ Or STRM_SHARE_DENY_NONE)
        Do While ReadNextEntry: Loop
      Set Strm = Nothing
    End Sub
    
    Public Property Get FileName() As String
      FileName = mFileName
    End Property
    
    Public Property Get ShortFileName() As String
      ShortFileName = mShortFileName
    End Property
    
    Public Property Get Count() As Long
      Count = EntriesCount
    End Property
    
    Public Property Get EntryTypeByIndex(ByVal IndexZeroBased As Long) As eEntryType
      EntryTypeByIndex = Entries(IndexZeroBased).EntryType
    End Property
    Public Property Get EntryTypeStringByIndex(ByVal IndexZeroBased As Long) As String
      Select Case Entries(IndexZeroBased).EntryType
        Case frxBinary:  EntryTypeStringByIndex = "Binary"
        Case frxImage:   EntryTypeStringByIndex = "Image"
        Case frxTextA:   EntryTypeStringByIndex = "TextA"
        Case frxTextW:   EntryTypeStringByIndex = "TextW"
        Case frxTextRTF: EntryTypeStringByIndex = "TextRTF"
        Case frxList:    EntryTypeStringByIndex = "List"
      End Select
    End Property
    Public Property Get OffsetByIndex(ByVal IndexZeroBased As Long) As Long
      OffsetByIndex = Entries(IndexZeroBased).Offset
    End Property
    Public Property Get LengthByIndex(ByVal IndexZeroBased As Long) As Long
      LengthByIndex = Entries(IndexZeroBased).Length
    End Property
    Public Property Get ContentByIndex(ByVal IndexZeroBased As Long) As Byte()
      ContentByIndex = Entries(IndexZeroBased).Content
    End Property
    Public Property Get ImageExtensionByIndex(ByVal IndexZeroBased As Long) As String
      ImageExtensionByIndex = Entries(IndexZeroBased).ImageExtension
    End Property
    
    Public Property Get EntryTypeByOffset(ByVal Offset As Long) As eEntryType
      EntryTypeByOffset = Entries(FindIndexFor(Offset)).EntryType
    End Property
    Public Property Get EntryTypeStringByOffset(ByVal Offset As Long) As String
      EntryTypeStringByOffset = EntryTypeStringByIndex(FindIndexFor(Offset))
    End Property
    Public Property Get LengthByOffset(ByVal Offset As Long) As Long
      LengthByOffset = Entries(FindIndexFor(Offset)).Length
    End Property
    Public Property Get ContentByOffset(ByVal Offset As Long) As Byte()
      ContentByOffset = Entries(FindIndexFor(Offset)).Content
    End Property
    Public Property Get ImageExtensionByOffset(ByVal Offset As Long) As String
      ImageExtensionByOffset = Entries(FindIndexFor(Offset)).ImageExtension
    End Property
    
    Private Function FindIndexFor(ByVal Offset As Long) As Long
      Dim i As Long
      If Offset < 0 Then Offset = 65536 + Offset
      For i = 0 To EntriesCount - 1
        If Entries(i).Offset = Offset Then FindIndexFor = i: Exit Function
      Next
      Err.Raise vbObjectError, , "No such Offset found"
    End Function
    
    Private Function ReadNextEntry() As Boolean
    Dim P As Long, L As Long, B() As Byte, i As Long, J As Long, K As Long
        P = Strm.GetPosition
      ReDim Preserve Entries(EntriesCount)
      Entries(EntriesCount).Offset = P
      Entries(EntriesCount).Content = ""
      Entries(EntriesCount).EntryType = frxBinary
      
      Strm.ReadToPtr VarPtr(L), 1
      Strm.ReadToByteArr B, L
      If L <> UBound(B) + 1 Then Exit Function
      
      If L Then
        For i = 0 To UBound(B)
          If B(i) = 0 Then Exit For
        Next
        If i > UBound(B) Then
          Entries(EntriesCount).EntryType = frxTextA
          Strm.SetPosition P + 1
          If L = 255 Then Strm.ReadToPtr VarPtr(L), 2
        Else
          Strm.SetPosition P
          Strm.ReadToByteArr B, 4
          If B(1) = 0 And B(2) = 3 And B(3) = 0 Then
            Entries(EntriesCount).EntryType = frxList
          Else
            Strm.SetPosition P
            Strm.ReadToLong L
          End If
        End If
      Else
        Strm.SetPosition P
        Strm.ReadToLong L
      End If
      If Strm.GetPosition = Strm.GetSize Then Exit Function
      
      P = Strm.GetPosition 'the stream is now placed after the Length-Info
      
      If Entries(EntriesCount).EntryType = frxTextA Then
        Strm.ReadToByteArr B, L
        Entries(EntriesCount).Content = StrConv(B, vbUnicode)
      ElseIf Entries(EntriesCount).EntryType = frxList Then
        With New_c.StringBuilder
          For i = 1 To L
            Strm.ReadToPtr VarPtr(K), 2
            Strm.ReadToByteArr B, K
            .AppendNL StrConv(B, vbUnicode), IIf(i = L, "", vbNullChar)
          Next
          Entries(EntriesCount).Content = .ToString
          
          .Clear
          EntriesCount = EntriesCount + 1: ReDim Preserve Entries(0 To EntriesCount)
          Entries(EntriesCount).Offset = Strm.GetPosition
          Entries(EntriesCount).EntryType = frxList
          Strm.ReadToByteArr B, 4
          If UBound(B) <> 3 Then Exit Function
          If B(1) <> 0 Or B(2) <> 3 Or B(3) <> 0 Then Exit Function
          For i = 1 To B(0)
            Strm.ReadToPtr VarPtr(K), 2
            Strm.ReadToByteArr B, K
            .AppendNL StrConv(B, vbUnicode), IIf(i = L, "", vbNullChar)
          Next
          Entries(EntriesCount).Content = .ToString
        End With
        
      Else 'it's still at frxBinary, let's see if we can determine more
        Strm.ReadToByteArr B, 1
        Strm.SetPosition P + 4:  Strm.ReadToLong K
        Strm.SetPosition P + 20: Strm.ReadToLong J
        
        If B(0) = 123 Then ' { detected
          Strm.SetPosition P
          Entries(EntriesCount).EntryType = frxTextRTF
          Strm.ReadToByteArr B, L
          Entries(EntriesCount).Content = StrConv(B, vbUnicode)
          
        ElseIf L = J + 24 Then 'it's apparently an image-header
          Entries(EntriesCount).EntryType = frxImage
          Strm.SetPosition P + 24
          Strm.ReadToByteArr Entries(EntriesCount).Content, J
        ElseIf L = K + 8 Then 'it's apparently an image-header
          Entries(EntriesCount).EntryType = frxImage
          Strm.SetPosition P + 8
          Strm.ReadToByteArr Entries(EntriesCount).Content, K
          
        Else 'what now remains is, to check whether we have some text here
          Strm.SetPosition P
          Strm.ReadToByteArr B, L
          For i = 0 To UBound(B) 'ANSI-Text-check first
            If B(i) = 0 Then Exit For
          Next
          If i > UBound(B) Then 'we have ANSI-Text
            Entries(EntriesCount).EntryType = frxTextA
            Entries(EntriesCount).Content = StrConv(B, vbUnicode)
          Else 'we either remain at T=frxBinary or we detect UniCode-Text
            Strm.SetPosition P
            Do
              Strm.ReadToLong K
            Loop Until K = 0 Or Strm.GetPosition = Strm.GetSize
            If Strm.GetPosition = Strm.GetSize Then 'indicator not found (so we remain at non-specific binary-mode)
              Strm.SetPosition P + L
              Entries(EntriesCount).Content = B
            Else 'the K = 0 case
              Strm.SetPosition -8, STRM_SeekFromCurPos
              Strm.ReadToLong L
              Strm.ReadToLong K
              If K = 0 And UBound(B) + 1 - L = Strm.GetPosition - P Then
                Entries(EntriesCount).EntryType = frxTextW
                Strm.ReadToByteArr Entries(EntriesCount).Content, L
                If L > 0 Then If Entries(EntriesCount).Content(0) = 123 Then Entries(EntriesCount).EntryType = frxTextRTF
              Else
                L = UBound(B) + 1
                Strm.SetPosition P + L
                Entries(EntriesCount).Content = B
              End If
            End If
          End If
        End If
      End If
      
      On Error Resume Next
        Entries(EntriesCount).Length = 0
        Entries(EntriesCount).Length = UBound(Entries(EntriesCount).Content) + 1
        If Entries(EntriesCount).EntryType = frxImage Then
          Select Case Entries(EntriesCount).Content(0)
            Case 1:    Entries(EntriesCount).ImageExtension = "emf"
            Case 215:  Entries(EntriesCount).ImageExtension = "wmf"
            Case 66:   Entries(EntriesCount).ImageExtension = "bmp"
            Case 71:   Entries(EntriesCount).ImageExtension = "gif"
            Case 255:  Entries(EntriesCount).ImageExtension = "jpg"
            Case Else: Entries(EntriesCount).ImageExtension = "ico"
          End Select
        End If
      If Err Then Err.Clear
      EntriesCount = EntriesCount + 1
      ReadNextEntry = True
    End Function
    HTH

    Olaf

  19. #19
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,026

    Re: Structure of FRX files

    Quote Originally Posted by DEXWERX View Post
    @LaVolpe: nice google-fu.
    lol, this old fart (me) had no idea what google-fu was. Had to look it up. The only thing I recognize was "google" and "fu". Of course, I didn't think "fu" meant the same to you as it did to me ("f" & "u" two 'words'). Glad I looked it up, was starting to wonder how I offended you
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  20. #20

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,446

    Re: Structure of FRX files

    Hi LaVolpe,

    Well, it all has to do with the MS Sans Serif substitution, and it'll very likely only be for my own use, but that's okay. As mentioned in another thread, I've got two UserControls that I make extensive use of: RtfLabel and RtfButton. When these controls are used on a form, the RTF text winds up in the FRX file.

    Now, the actual RTF text will have the "MS Sans Serif" sub-string within it. From another thread, I'm "fixing" this with the following (just a code stub)...

    Code:
    
                If TypeName(ctl) = "RtfButton" Or TypeName(ctl) = "RtfLabel" Then
                    If InStr(ctl.RTFCode, "MS Sans Serif") Then
                        ctl.RTFCode = Replace$(ctl.RTFCode, "MS Sans Serif", "Microsoft Sans Serif")
                    End If
                End If
    
    Everything is working fine as far as I can tell. However, I'm still taking you to heart, thinking that a source-code fix is better than a run-time fix. Therefore, with 100s of forms, I'm looking at an "automated" source code fix. And that's where this thread comes in.

    And, I've got your little codebank project coming to life. However, I'm not sure how to filter for other things (beyond strings and pictures). If I hit one of those, it'll probably make my work upchuck. I'll continue to work on that.

    Here's where I am so far with it. Just run it and point at some existing FRX (or CTX, etc) file, and it'll read it. At the present time, it's read-only, so no fear of messing up an existing project.

    I'm about done for the day, but I'll continue working on it, posting my progress.

    Also, as always, I'm open to suggestions.

    EDIT1: Here's a screenshot of what it looks like so far:

    Name:  FrxRead.png
Views: 1666
Size:  7.8 KB

    EDIT2: Here's a better shot that shows some RTF text with the "MS Sans Serif" in it. And, as you will see if you squint, I've got Spanish on some of my forms.

    Name:  FrxRead2.png
Views: 1726
Size:  11.4 KB
    Attached Files Attached Files
    Last edited by Elroy; Aug 22nd, 2017 at 04:12 PM.
    Any software I post in these forums written by me is provided AS IS without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that Ive been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a VB6 random code folder that is overflowing. Ive been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  21. #21

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,446

    Re: Structure of FRX files

    Say Olaf,

    I haven't taken a detailed look at your project because I don't have the RichClient. However, upon looking at your eEntryType constant enumeration, it doesn't appear that you have all the possible basis covered.

    For instance, I know that you can put a Byte array into a Variant and then stuff it into the property bag. And, as such, it's going to save into the FRX file. I haven't studied this situation with a hex editor, but I know that I'll eventually need to. I'm not sure, but I believe you can stuff many other things into a Variant that becomes part of the property bag of some UserControl.

    But anyway, I'll continue working out how these appear in these FRX files, probably ignoring many of them (but appropriately jumping over them).

    Best Regards,
    Elroy
    Any software I post in these forums written by me is provided AS IS without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that Ive been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a VB6 random code folder that is overflowing. Ive been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  22. #22
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,026

    Re: Structure of FRX files

    @Elroy. FYI: You don't have to stuff a byte array into a variant.
    Propbag.WriteProperty "BinaryStuff", bData() works just fine if bData() declared as Byte

    I use the above quite often to store binary information: image formats not supported by VB, unicode, custom formats, etc.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  23. #23
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,026

    Re: Structure of FRX files

    Elroy. Just played for about 30 mins or so. The FRX structure isn't easy to decipher because of all the undocumented entries that exist which define the type of 'resource' within the file. However, there does appear some consistencies...

    1. DWord/Word alignment is not in play, no buffering between resources
    2. The 1st 4 bytes describe the size of the resource, size of resource (including flags)
    3. The next 4 bytes appear to be some flag as to type of resource and if not in some internal list, then text most likely
    4. The rest of the block contains undocumented flags, if applicable, and eventually content

    For example, byte arrays are written to frx from UC: 4 byte block size, then 4 unknown longs (GUID maybe?), value of vbByte (Integer), then dimension count (Integer), then one long for each L/UBound value, then the byte data.

    I think if you pursue this, you will need to cross-reference offsets from the frm to the frx files. The frm file allows you to search for specific property names and the offset identifies where in the frx, the resource block starts which identifies size of block. Standard text begins after the 4 byte block size. Knowing all this, you could rewrite the frx on demand if standard text is the only thing you are editing. The pain would be keeping track of all the frm offsets so you can adjust them as needed, after updating the frx.

    Trying to parse the frx without the frm file to reference does you little good since your goal is not to extract only, but to extract then modify then rewrite. And that means rewriting the frm file also with updated offsets. Have fun buddy.

    Edited: Important. The entry for the block size is NOT included in the total block size. So for a frx text entry of 45 chars: the block size would be entered in the frx as 45 (text starts after that entry). But total block size would actually be 49 bytes: 4 bytes for the size entry and 45 bytes for the text. Understand? Theoretically there could be a resource of zero bytes where the block size entry would be zero. Don't know if VB would ever write a zero byte resource?
    Last edited by LaVolpe; Aug 22nd, 2017 at 09:16 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  24. #24
    Fanatic Member Spooman's Avatar
    Join Date
    Mar 2017
    Posts
    869

    Re: Structure of FRX files

    Quote Originally Posted by LaVolpe View Post
    lol, this old fart (me) had no idea what google-fu was. Had to look it up.
    I suppose that the Korean version would be google-do

  25. #25

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,446

    Re: Structure of FRX files

    @LaVolpe: Good morning. Yeah, I had most of what you mentioned in post #23 already sorted. However, let me go ahead and do a run-down.

    Quote Originally Posted by LaVolpe View Post
    1. DWord/Word alignment is not in play, no buffering between resources
    Correct. That's what I'm also seeing.


    Quote Originally Posted by LaVolpe View Post
    2. The 1st 4 bytes describe the size of the resource, size of resource (including flags)
    Correct. And yeah, this size does not include these 4 bytes, so they must be added when bouncing from item to item.


    Quote Originally Posted by LaVolpe View Post
    3. The next 4 bytes appear to be some flag as to type of resource and if not in some internal list, then text most likely
    Not so sure about this one. If it's an image, there does seem to be a secondary header that's immediately seen. However, if it's a string, it seems that the string immediately follows. Here's a screenshot of an FRX (in a hex editor) with nothing but two strings in it. And, in the FRM, the offsets point directly at that initial 4 byte size value. The two offsets in the FRM are 0000 and 0120.
    Name:  frx2.png
Views: 1536
Size:  23.0 KB
    Only the 4 byte header/size, nothing else.


    Quote Originally Posted by LaVolpe View Post
    4. The rest of the block contains undocumented flags, if applicable, and eventually content
    Unless it's a string. And, in that case, there is no "rest of the block".

    Now, what confuses me is, "how does it reliably differentiate a string from other item type (i.e., images, etc)?" This question leads me to believe that we must go back to the FRM and use the offsets to reliably read these things. Because, here's my thinking. In a byte of an ansi string, we can have any value we like. Therefore, a string could quite easily "spoof" itself to be the header of an image (for purposes of these FRX files). Therefore, to be bullet-proof, we need something that unquestionably tells us that we're dealing with a string.

    And, as I mentioned in my OP, that's in the FRM file:

    Quote Originally Posted by Elroy View Post
    Sometimes, the FRX references in the FRM file look like: $"SomeForm.frx":0000. Does the dollar-sign indicate we're looking for a string?
    So ... back to the drawing board, with the thinking that the FRM files truly are needed to reliably read these FRX files (as you also stated).

    Best Regards,
    Elroy
    Any software I post in these forums written by me is provided AS IS without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that Ive been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a VB6 random code folder that is overflowing. Ive been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  26. #26
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,026

    Re: Structure of FRX files

    This question leads me to believe that we must go back to the FRM and use the offsets to reliably read these things. Because, here's my thinking. In a byte of an ansi string, we can have any value we like. Therefore, a string could quite easily "spoof" itself to be the header of an image (for purposes of these FRX files). Therefore, to be bullet-proof, we need something that unquestionably tells us that we're dealing with a string.
    For 100% confidence I agree. I doubt VB reads the frx file without the frm file. Unless we know every possible header that can exist in the frx, then not sure how'd you process/read the frx with full confidence. For example, images have a 4-byte flag that appears 8 bytes after block size entry. But I had an image saved from a UC that resulted in that flag 20-ish bytes (don't recall right now) after the size block, not 8.

    Sometimes, the FRX references in the FRM file look like: $"SomeForm.frx":0000. Does the dollar-sign indicate we're looking for a string?
    Don't know about that $ symbol equating to text/unicode. I know I've seen strings referenced without the $ symbol. Don't immediately see any examples in my frx file with such a format. Without testing this (not on a VB6 machine right now), could special formatting have anything to do with renaming a form, i.e., Save Form1 As?
    Last edited by LaVolpe; Aug 23rd, 2017 at 01:33 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  27. #27

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,446

    Re: Structure of FRX files

    Since, at least for this endeavor, I'm only interested in strings, I've cut the project down even further.

    I'd attach the project, but I'm still working out the Write/Save aspects of it (after a string is changed).

    Here are two procedures that are working perfectly though ...

    Code:
    
    Private Sub ReadAndEnumFrxFile()
        Dim hFileFrx As Long, hFileFrm As Long
        Dim sLineFrm As String
        Dim sNeedle As String
        Dim lOffset As Long
        Dim lDataSize As Long
        Dim tNode As Node
        '
        hFileFrm = FreeFile: Open msFileFrm For Input As hFileFrm
        hFileFrx = FreeFile: Open msFileFrx For Binary As hFileFrx
        '
        ' Example: $"Form1.frx"
        sNeedle = LCase$("$""" & Mid$(msFileFrx, InStrRev(msFileFrx, "\") + 1) & """")      ' Allows us to find the FRX strings.
        '
        Do While Not EOF(hFileFrm)                                                          ' Loop through entire FRM file.
            Line Input #hFileFrm, sLineFrm
            If InStr(LCase$(sLineFrm), sNeedle) <> 0 Then                                   ' Does line contain FRX string?
                lOffset = Val("&H" & Mid$(sLineFrm, InStrRev(sLineFrm, ":") + 1))           ' Parse out the FRX offset.
                Get hFileFrx, lOffset + 1, lDataSize                                        ' Get length out of FRX file.
                If lDataSize < 1& Then Error 1234
                Set tNode = tvRez.Nodes("frxStr")                                           ' List in our TreeView.
                With tvRez.Nodes.Add(tNode, tvwChild, , "String " & tNode.Children + 1&)
                    .Tag = lOffset + 4& & "," & lDataSize
                End With
                Set tNode = Nothing
            End If
        Loop
        '
        Close hFileFrm
        Close hFileFrx
    End Sub
    
    
    ... and ...

    Code:
    
    Private Sub ShowString(tNode As Node)
        Dim b() As Byte, hFileFrx As Long
        '
        mlOffset = Val(Split(tNode.Tag, ",")(0))
        mlSize = Val(Split(tNode.Tag, ",")(1))
        '
        hFileFrx = FreeFile
        Open msFileFrx For Binary As hFileFrx
        '
        txtString.Text = vbNullString
        '
        ReDim b(0 To mlSize - 1&)
        Get hFileFrx, mlOffset + 1&, b
        Close hFileFrx
        '
        txtString.Text = StrConv(b, vbUnicode)
        cmdReplace.Enabled = True
        cmdSave.Enabled = False
    End Sub
    
    At least in my case, the $"Form1.frx" (including the $) seem to be reliably there when it's a string. And then, the FRX has a four-byte item length, and no further header.

    I'm not sure when I'll get it done, but I'll post the write/modify version when I get it done. Here's a screen-shot of where I'm going:
    Name:  Frx4.jpg
Views: 1628
Size:  25.3 KB
    Any software I post in these forums written by me is provided AS IS without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that Ive been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a VB6 random code folder that is overflowing. Ive been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  28. #28

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,446

    Re: Structure of FRX files

    Alrighty, I think I'm gonna call this thread done.

    I've attached a program that can extract strings out of an FRX file, edit them, and then re-write them, patching up all offsets (in the FRM file). This is what I needed.

    I'm not sure this will be of any use to anyone but me, but my (relatively) completed project is attached. I do have a high degree of confidence that it's correctly managing the FRM & FRX files.

    I will be doing more work on it to further automate it. I plan on making it automated if a Command$ is supplied to it. That way, I can create a batch file, and then go through and do a search-and-replace in all of my FRX files (of which I've got many).

    Maybe someone else will make some use of these ideas. Who knows.

    Enjoy,
    Elroy
    Attached Files Attached Files
    Any software I post in these forums written by me is provided AS IS without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that Ive been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a VB6 random code folder that is overflowing. Ive been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  29. #29
    Frenzied Member
    Join Date
    Feb 2015
    Posts
    1,288

    Re: [RESOLVED] Structure of FRX files

    Just small research. A FRX file contains numerous streams with very simple format: DWORD - size of stream followed by data. You can extract only binary data, if you want to extract data in the certain format you should use a FRM/CTL/etc file too.
    You basically scan every byte for the double-word of &H0000746C.
    746C is added by OLE not by VB, it's the OLE stream signature. VB6 passes the stream that points to that byte into OleLoadPictureEx function, ie that is external data in relation to VB.
    You can check my statements by changing an FRX file. Just add random data between streams and fix FRM file, project will work, ie VB6 uses a FRM file as the pointer to a FRX stream.

  30. #30

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,446

    Re: [RESOLVED] Structure of FRX files

    Hi Trick,

    However, from everything I see, if the FRM reference is something like $"SomeForm.frx":0123 rather than just "SomeForm.frx":0123 then there seems to be no 746C constant. (Notice the $ sign.) In those cases, there's only a length header in the FRX, immediately followed by the string. No null termination either. If there's nothing but strings in the FRX, they're basically length, string, length, string, etc. And no padding and no 746C.

    Best Regards,
    Elroy
    Last edited by Elroy; Aug 23rd, 2017 at 04:48 PM.
    Any software I post in these forums written by me is provided AS IS without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that Ive been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a VB6 random code folder that is overflowing. Ive been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  31. #31

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,446

    Re: [RESOLVED] Structure of FRX files

    Hmmm, the more I stare at these things, the more confused I get.

    Just as a test, I created a multi-line textbox with lots of text in it, and then saved. The project is attached for those interested.

    Here's all the code in the FRM:

    Code:
    
    VERSION 5.00
    Begin VB.Form Form1
       Caption         =   "Form1"
       ClientHeight    =   5370
       ClientLeft      =   3360
       ClientTop       =   3975
       ClientWidth     =   6585
       LinkTopic       =   "Form1"
       ScaleHeight     =   5370
       ScaleWidth      =   6585
       Begin VB.TextBox Text1
          Height          =   2415
          Left            =   1560
          MultiLine       =   -1  'True
          ScrollBars      =   3  'Both
          TabIndex        =   0
          Text            =   "Form1.frx":0000
          Top             =   1080
          Width           =   3195
       End
    End
    Attribute VB_Name = "Form1"
    Attribute VB_GlobalNameSpace = False
    Attribute VB_Creatable = False
    Attribute VB_PredeclaredId = True
    Attribute VB_Exposed = False
    Option Explicit
    
    And here's a screenshot of a piece of the FRX in a hex editor.

    Name:  Frx5.png
Views: 1611
Size:  12.8 KB

    Now this time, I don't even get my four-byte item length. It appears to be only a three-byte length. The first word in the textbox is "This".

    Also, there's no $ notation along with the FRX offset in the FRM file.

    So, your guess is as good as mine. That's it for me today.

    Y'all Take Care,
    Elroy
    Attached Files Attached Files
    Any software I post in these forums written by me is provided AS IS without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that Ive been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a VB6 random code folder that is overflowing. Ive been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  32. #32
    Frenzied Member
    Join Date
    Feb 2015
    Posts
    1,288

    Re: [RESOLVED] Structure of FRX files

    Hi Elroy.
    Quote Originally Posted by Elroy View Post
    then there seems to be no 746C structure.
    Yes, the structure always: DWORD_Length, Data; as i mentioned.
    I meant 746C doesn't refer to FRX format. It's stream data that produced by OLE. You can check it make inverse operation:
    Code:
    Private Sub Form_Load()
        Dim p As IPersistStream
        Dim s As IStream
        Dim i As Integer
        
        Set s = CreateStreamOnHGlobal(0, True)
        Set p = LoadPicture("D:\\ \ \ButtonUpDown\Down.bmp")
    
        p.Save s, True
        
        s.Seek 0, STREAM_SEEK_SET
        s.Read i, Len(i)
        
        Debug.Print Hex(i)
        
    End Sub
    Generally you can't parse FRX without FRM. As i said you can add arbitrary data to FRX and it'll work.

  33. #33
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,026

    Re: [RESOLVED] Structure of FRX files

    Quote Originally Posted by Elroy View Post
    Hmmm, the more I stare at these things, the more confused I get.

    Now this time, I don't even get my four-byte item length. It appears to be only a three-byte length. The first word in the textbox is "This".

    Also, there's no $ notation along with the FRX offset in the FRM file.

    So, your guess is as good as mine. That's it for me today.
    Elroy, I don't know what version of vb began to use frx files. Maybe what you are seeing are two versions of storing text? Don't know.

    Anyway, that format is easy enough to decipher. Though I am surprised there is no 4-byte block size. The 1st 3 bytes are:
    byte 1: 255 = some flag, some other meaning?
    bytes 2 & 3: = 1697 which is size of the string, entire block is 1697 + 3

    Kinda throws the idea out that every block starts with a 4-byte block size, huh?
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  34. #34
    Hyperactive Member
    Join Date
    Aug 2016
    Posts
    334

    Re: Structure of FRX files

    in my chinese system in the code
    ReDim b(0 To mlSize - 1&) error Array overflow

  35. #35

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,446

    Re: [RESOLVED] Structure of FRX files

    @LaVolpe: Just as an FYI, everything I've posted in this thread was created with VB6-SP6. The project I posted in post #31 was created from scratch yesterday.

    Also, I think I've got what I want, so I'll leave the rest of the sorting out of FRX files to others. To fully understand these things, I think I'd need to develop a much better understanding of a comment made by Trick...

    Quote Originally Posted by The trick View Post
    It's stream data that produced by OLE.
    I strongly suspect all the answers are in a deep understanding of that statement.

    Best Regards,
    Elroy
    Any software I post in these forums written by me is provided AS IS without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that Ive been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a VB6 random code folder that is overflowing. Ive been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  36. #36

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,446

    Re: [RESOLVED] Structure of FRX files

    Well, I'm actively using my little FrxStringEditor, and continuing to find improvements (and fix a couple of bugs).

    I found a border condition that wasn't being correctly handled, and fixed it.
    Also, it wasn't correctly handling offsets larger than FFFF, and that's fixed as well.

    It also has a better search-and-replace function in it.

    Who knows if any of this will be of help to anyone else, but here it is (attached).
    Attached Files Attached Files
    Any software I post in these forums written by me is provided AS IS without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that Ive been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a VB6 random code folder that is overflowing. Ive been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  37. #37
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,000

    Re: [RESOLVED] Structure of FRX files

    Probably written by the IPersistStream.Save or IPersistStreamInit.Save implementation of each object. The actual contents can be anything in theory, even XML. Only the object itself needs to know the format because nothing else needs to read it.

  38. #38

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,446

    Re: [RESOLVED] Structure of FRX files

    dilettante, I suspect you're correct. And that's almost certainly why there's no apparent rhyme-or-reason as to what we see in these FRX files. The property of the control knows what kind of data it is, and OLE will know how to deal with streaming/serializing that kind of data, and that's all that needs to be known. And that's true because the only thing re-reading that data will be the same property that wrote it out.

    Therefore, to make a reliable parser/reader of these FRX files, we'd need a complete list of every type of item that could be placed into them (and also be able to determine that type by reading the FRM file). And that becomes particularly problematic when we realize that, through UserControls, we can put virtually anything into them.

    Again, I'm successfully finding the strings that I'm after. I'm not sure it's worth pursuing this much further, given those facts.

    Best Regards,
    Elroy
    Any software I post in these forums written by me is provided AS IS without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that Ive been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a VB6 random code folder that is overflowing. Ive been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  39. #39
    Hyperactive Member
    Join Date
    Aug 2016
    Posts
    334

    Re: [RESOLVED] Structure of FRX files

    Name:  QQ截图20170825100102.png
Views: 1527
Size:  30.3 KBName:  QQ截图20170825100358.png
Views: 1461
Size:  24.5 KB

    have different size .

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width