Seite 38 von 43

Re: WinAPI Library (Snippets) (1.052)

Verfasst: 04.08.2015 11:13
von Falko
Hallo Ray,

prima Arbeit. :allright:

Kleine Anmerkung habe ich noch. Nachdem ich unter Windows10 in PB den alten
Codebaustein entfernt hatte um die neue hinzuzufügen, wurde das nicht eingefügt.
Purebasic ist dabei aktiv gewesen. Erst nach beenden von Purebasic und Codebausteine
hinzufügen, wurde deine WinAPI-Library übernommen. Vielleicht noch eine Funktion hinzufügen,
die das PB vorher beendet und nach dem Hinzufügen wieder startet. Der Path ist ja bekannt.

Wie gesagt, ich kann das jetzt nur noch unter Windows 10 ausprobieren, da ich alle Rechner darauf umgestellt hatte.

Gruß,
Falko

Re: WinAPI Library (Snippets) (1.052)

Verfasst: 05.08.2015 09:49
von RSBasic
Hi Falko,

die Abfrage, ob PB noch läuft, habe ich auf jeden Fall schon mal gebaut. Wahrscheinlich nur beim Updater. Ich werde diese Abfrage beim Einfügen der Codebausteine ebenfalls hinzufügen, damit der von dir gefundene Fehler nicht mehr auftritt. Danke fürs Melden :allright:

Re: WinAPI Library (Snippets) (1.052)

Verfasst: 08.08.2015 23:01
von RSBasic
WinAPI Library 1.4.1 wurde veröffentlicht (3 neue Sprachen)

Hallo ihr lieben,

es gibt einige Nutzer, die wollen gerne eine Multilanguage-Version haben. Außerdem fand ich vor einigen Monaten heraus, dass meine WinAPI Library im französischen Forum bekannt geworden ist und dass es Leute gibt, die die Codes aus meiner WinAPI Libraray mit Google übersetzt haben, damit diese Codes in dieser Sprache ebenfalls verfügbar sind.
Das finde ich echt toll, aber es ist für die fleißigen User zu aufwändig, die Codes nach jedem Update meiner Anwendung übersetzen zu müssen.
Damit sie das nicht jedes Mal machen müssen, habe ich jetzt selber eine Automatisierungsanwendung zum Übersetzen geschrieben und werde sie bei jedem Update ausführen.
Nicht nur französisch wird unterstützt, sondern auch andere Sprachen.

Meine WinAPI Library (inkl. Codes) gibt es ab jetzt in folgenden Sprachen:
  • Deutsch (das ist klar^^)
  • Englisch
  • Spanisch
  • Französisch
Die Sprache könnt ihr am Anfang beim ersten Start dieser Version oder später im Menü unter "Sprache" ändern.
Alle Texte (Kommentare und Strings in den PB-Dateien wurden nicht berücksichtigt) in englischer, französischer und spanischer Sprache wurden mit "Google Translate" maschinell übersetzt und es kann möglich sein, dass einige Texte grammatikalisch nicht korrekt sind, aber ich hoffe, man kann die einzelnen Code-Bezeichnungen trotzdem verstehen.
Wenn ihr zusätzlich eine weitere Sprache haben wollt, sagt Bescheid und ich füg sie hinzu.

Jetzt kann ich meine WinAPI Library auch im englischen und französischen Forum verbreiten und zukünftige Updates ankündigen.

Online: http://www.rsbasic.de/winapi-library
Offline: http://www.rsbasic.de/downloads/winapi_library.zip (aktuelle Version mit allen Codes)

PS: Ein Offline-Update von einer älteren Version auf diese neue Version ist leider nicht möglich. Bitte ladet die vollständige ZIP-Datei herunter.

@Falko
Erledigt

Re: WinAPI Library (Snippets) (1.052)

Verfasst: 09.08.2015 01:56
von Bisonte
Alle Achtung... :allright:

Ist dann ja nicht mehr weit bis zur Weltherrschaft :mrgreen:

Re: WinAPI Library (Snippets) (1.052)

Verfasst: 09.08.2015 21:45
von Vera
Hi Ray,
auch an dieser Stelle nochmal ein "w0w das ist toll" und vielen Dank für dieses hilfreiche Tool Bild

Lieber Gruß ~ Vera

Re: WinAPI Library (Snippets) (1.052)

Verfasst: 10.08.2015 18:21
von Falko
@Ray,
danke, und super Arbeit. :allright: :allright: :allright:

Re: WinAPI Library (Snippets) (1.052)

Verfasst: 02.01.2016 15:48
von Sicro

Re: WinAPI Library (Snippets) (1.052)

Verfasst: 02.01.2016 15:57
von RSBasic
Ist das eigentlich so schlimm, wenn das eine Integer-Variable ist?

Re: WinAPI Library (Snippets) (1.052)

Verfasst: 02.01.2016 16:38
von Sicro

Code: Alles auswählen

Define.l a = 129
Define.q b

CopyMemory(@a, @b, SizeOf(Long))

;ShowMemoryViewer(@b, SizeOf(Quad)) 000000000064788C
b = 129
;ShowMemoryViewer(@b, SizeOf(Quad)) 000000000064788C
Ok, hast recht, macht kein Unterschied.

Re: WinAPI Library (Snippets) (1.052)

Verfasst: 02.01.2016 17:01
von Sicro

Code: Alles auswählen

EnableExplicit

DeclareModule FileInfo
  EnableExplicit
  
  Declare.s GetFixedProductVersion(File.s)
  Declare.s GetFixedFileVersion(File.s)
  Declare.s GetFixedFileType(File.s)
  Declare.s GetProductVersion(File.s)
  Declare.s GetFileVersion(File.s)
  Declare.s GetProductName(File.s)
  Declare.s GetFileDescription(File.s)
  Declare.s GetFileComments(File.s)
  Declare.s GetFileCompanyName(File.s)
  Declare.s GetFileInternalName(File.s)
  Declare.s GetFileLegalCopyright(File.s)
  Declare.s GetFileLegalTrademarks(File.s)
  Declare.s GetFileOriginalFilename(File.s)
EndDeclareModule

Module FileInfo
  Procedure.s GetFixedProductVersion(File.s)
    Protected.i NeededBufferSize, PointerLen
    Protected   *Buffer, *Pointer.VS_FIXEDFILEINFO
    Protected.s RetVal
  
    NeededBufferSize = GetFileVersionInfoSize_(@File,0)
    If NeededBufferSize < 1: ProcedureReturn "": EndIf
  
    *Buffer = AllocateMemory(NeededBufferSize)
    
    GetFileVersionInfo_(@File,0,NeededBufferSize,*Buffer)
    VerQueryValue_(*Buffer,"\",@*Pointer,@PointerLen)
    If *Pointer
      RetVal = Str(*Pointer\dwProductVersionMS >> 16 & $FFFF) + "." +
               Str(*Pointer\dwProductVersionMS & $FFFF) + "." +
               Str(*Pointer\dwProductVersionLS >> 16 & $FFFF) + "." +
               Str(*Pointer\dwProductVersionLS & $FFFF)
    EndIf
    FreeMemory(*Buffer)
    
    ProcedureReturn RetVal
  EndProcedure
  
  Procedure.s GetFixedFileVersion(File.s)
    Protected.i NeededBufferSize, PointerLen
    Protected   *Buffer, *Pointer.VS_FIXEDFILEINFO
    Protected.s RetVal
  
    NeededBufferSize = GetFileVersionInfoSize_(@File,0)
    If NeededBufferSize < 1: ProcedureReturn "": EndIf
  
    *Buffer = AllocateMemory(NeededBufferSize)
    
    GetFileVersionInfo_(@File,0,NeededBufferSize,*Buffer)
    VerQueryValue_(*Buffer,"\",@*Pointer,@PointerLen)
    If *Pointer
      RetVal = Str(*Pointer\dwFileVersionMS >> 16 & $FFFF) + "." +
               Str(*Pointer\dwFileVersionMS & $FFFF) + "." +
               Str(*Pointer\dwFileVersionLS >> 16 & $FFFF) + "." +
               Str(*Pointer\dwFileVersionLS & $FFFF)
    EndIf
    FreeMemory(*Buffer)
    
    ProcedureReturn RetVal
  EndProcedure
  
  Procedure.s GetFixedFileType(File.s)
    Protected.i NeededBufferSize, PointerLen
    Protected   *Buffer, *Pointer.VS_FIXEDFILEINFO
    Protected.s RetVal
  
    NeededBufferSize = GetFileVersionInfoSize_(@File,0)
    If NeededBufferSize < 1: ProcedureReturn "": EndIf
  
    *Buffer = AllocateMemory(NeededBufferSize)
    
    GetFileVersionInfo_(@File,0,NeededBufferSize,*Buffer)
    VerQueryValue_(*Buffer,"\",@*Pointer,@PointerLen)
    If *Pointer
      Select *Pointer\dwFileType
        Case #VFT_APP
          RetVal = "Application"
        Case #VFT_DLL
          RetVal = "DLL"
        Case #VFT_DRV
          Select *Pointer\dwFileSubtype
            Case #VFT2_DRV_COMM
              RetVal = "Communications Driver"
            Case #VFT2_DRV_DISPLAY
              RetVal = "Display Driver"
            Case #VFT2_DRV_INSTALLABLE
              RetVal = "Installable Driver"
            Case #VFT2_DRV_KEYBOARD
              RetVal = "Keyboard Driver"
            Case #VFT2_DRV_LANGUAGE
              RetVal = "Language Driver"
            Case #VFT2_DRV_MOUSE
              RetVal = "Mouse Driver"
            Case #VFT2_DRV_NETWORK
              RetVal = "Network Driver"
            Case #VFT2_DRV_PRINTER
              RetVal = "Printer Driver"
            Case #VFT2_DRV_SOUND
              RetVal = "Sound Driver"
            Case #VFT2_DRV_SYSTEM
              RetVal = "System Driver"
            ;Case #VFT2_DRV_VERSIONED_PRINTER
             ; RetVal = "Versioned Printer Driver"
            Case #VFT2_UNKNOWN
              RetVal = "Unkown by the system"
          EndSelect
        Case #VFT_FONT
          Select *Pointer\dwFileSubtype
            Case #VFT2_FONT_RASTER
              RetVal = "Raster Font"
            Case #VFT2_FONT_TRUETYPE
              RetVal = "TrueType Font"
            Case #VFT2_FONT_VECTOR
              RetVal = "Vector Font"
            Case #VFT2_UNKNOWN
              RetVal = "Unkown by the system"
          EndSelect
        Case #VFT_STATIC_LIB
          RetVal = "Static-link Library"
        Case #VFT_UNKNOWN
          RetVal = "Unkown by the system"
        Case #VFT_VXD
          RetVal = "Virtual Device"
      EndSelect
    EndIf
    FreeMemory(*Buffer)
    
    ProcedureReturn RetVal
  EndProcedure
  
  Procedure.s GetProductVersion(File.s)
    Protected.i NeededBufferSize, PointerLen
    Protected   *Buffer, *Pointer
    Protected.s TranslationCode, RetVal
  
    NeededBufferSize = GetFileVersionInfoSize_(@File,0)
    If NeededBufferSize < 1: ProcedureReturn "": EndIf
  
    *Buffer = AllocateMemory(NeededBufferSize)
    
    GetFileVersionInfo_(@File,0,NeededBufferSize,*Buffer)
    VerQueryValue_(*Buffer,"\\VarFileInfo\\Translation",@*Pointer,@PointerLen)
    If *Pointer
      TranslationCode = RSet(Hex(PeekW(*Pointer)),4,"0") + RSet(Hex(PeekW(*Pointer + 2)),4,"0")
      If VerQueryValue_(*Buffer,"\\StringFileInfo\\" + TranslationCode + "\\ProductVersion",@*Pointer,@PointerLen)
        RetVal = Trim(PeekS(*Pointer))
      Else
        ; Manche Programme haben einen falschen TranslationCode, zu dem es kein Informationen-Block gibt.
        ; Ich habe die Erfahrung gemacht, dass in diesem Fall immer ein Block mit diesem TranslationCode vorhanden ist:
        If VerQueryValue_(*Buffer,"\\StringFileInfo\\040904E4\\ProductVersion",@*Pointer,@PointerLen)
          RetVal = Trim(PeekS(*Pointer))
        EndIf
      EndIf
    EndIf
    FreeMemory(*Buffer)
  
    ProcedureReturn Trim(RetVal)
  EndProcedure
  
  Procedure.s GetFileVersion(File.s)
    Protected.i NeededBufferSize, PointerLen
    Protected   *Buffer, *Pointer
    Protected.s TranslationCode, RetVal
  
    NeededBufferSize = GetFileVersionInfoSize_(@File,0)
    If NeededBufferSize < 1: ProcedureReturn "": EndIf
  
    *Buffer = AllocateMemory(NeededBufferSize)
    
    GetFileVersionInfo_(@File,0,NeededBufferSize,*Buffer)
    VerQueryValue_(*Buffer,"\\VarFileInfo\\Translation",@*Pointer,@PointerLen)
    If *Pointer
      TranslationCode = RSet(Hex(PeekW(*Pointer)),4,"0") + RSet(Hex(PeekW(*Pointer + 2)),4,"0")
      If VerQueryValue_(*Buffer,"\\StringFileInfo\\" + TranslationCode + "\\FileVersion",@*Pointer,@PointerLen)
        RetVal = Trim(PeekS(*Pointer))
      Else
        ; Manche Programme haben einen falschen TranslationCode, zu dem es kein Informationen-Block gibt.
        ; Ich habe die Erfahrung gemacht, dass in diesem Fall immer ein Block mit diesem TranslationCode vorhanden ist:
        If VerQueryValue_(*Buffer,"\\StringFileInfo\\040904E4\\FileVersion",@*Pointer,@PointerLen)
          RetVal = Trim(PeekS(*Pointer))
        EndIf
      EndIf
    EndIf
    FreeMemory(*Buffer)
  
    ProcedureReturn Trim(RetVal)
  EndProcedure
  
  Procedure.s GetProductName(File.s)
    Protected.i NeededBufferSize, PointerLen
    Protected   *Buffer, *Pointer
    Protected.s TranslationCode, RetVal
  
    NeededBufferSize = GetFileVersionInfoSize_(@File,0)
    If NeededBufferSize < 1: ProcedureReturn "": EndIf
  
    *Buffer = AllocateMemory(NeededBufferSize)
    
    GetFileVersionInfo_(@File,0,NeededBufferSize,*Buffer)
    VerQueryValue_(*Buffer,"\\VarFileInfo\\Translation",@*Pointer,@PointerLen)
    If *Pointer
      TranslationCode = RSet(Hex(PeekW(*Pointer)),4,"0") + RSet(Hex(PeekW(*Pointer + 2)),4,"0")
      If VerQueryValue_(*Buffer,"\\StringFileInfo\\" + TranslationCode + "\\ProductName",@*Pointer,@PointerLen)
        RetVal = Trim(PeekS(*Pointer))
      Else
        ; Manche Programme haben einen falschen TranslationCode, zu dem es kein Informationen-Block gibt.
        ; Ich habe die Erfahrung gemacht, dass in diesem Fall immer ein Block mit diesem TranslationCode vorhanden ist:
        If VerQueryValue_(*Buffer,"\\StringFileInfo\\040904E4\\ProductName",@*Pointer,@PointerLen)
          RetVal = Trim(PeekS(*Pointer))
        EndIf
      EndIf
    EndIf
    FreeMemory(*Buffer)
  
    ProcedureReturn Trim(RetVal)
  EndProcedure
  
  Procedure.s GetFileDescription(File.s)
    Protected.i NeededBufferSize, PointerLen
    Protected   *Buffer, *Pointer
    Protected.s TranslationCode, RetVal
  
    NeededBufferSize = GetFileVersionInfoSize_(@File,0)
    If NeededBufferSize < 1: ProcedureReturn "": EndIf
  
    *Buffer = AllocateMemory(NeededBufferSize)
    
    GetFileVersionInfo_(@File,0,NeededBufferSize,*Buffer)
    VerQueryValue_(*Buffer,"\\VarFileInfo\\Translation",@*Pointer,@PointerLen)
    If *Pointer
      TranslationCode = RSet(Hex(PeekW(*Pointer)),4,"0") + RSet(Hex(PeekW(*Pointer + 2)),4,"0")
      If VerQueryValue_(*Buffer,"\\StringFileInfo\\" + TranslationCode + "\\FileDescription",@*Pointer,@PointerLen)
        RetVal = Trim(PeekS(*Pointer))
      Else
        ; Manche Programme haben einen falschen TranslationCode, zu dem es kein Informationen-Block gibt.
        ; Ich habe die Erfahrung gemacht, dass in diesem Fall immer ein Block mit diesem TranslationCode vorhanden ist:
        If VerQueryValue_(*Buffer,"\\StringFileInfo\\040904E4\\FileDescription",@*Pointer,@PointerLen)
          RetVal = Trim(PeekS(*Pointer))
        EndIf
      EndIf
    EndIf
    FreeMemory(*Buffer)
  
    ProcedureReturn Trim(RetVal)
  EndProcedure
  
  Procedure.s GetFileComments(File.s)
    Protected.i NeededBufferSize, PointerLen
    Protected   *Buffer, *Pointer
    Protected.s TranslationCode, RetVal
  
    NeededBufferSize = GetFileVersionInfoSize_(@File,0)
    If NeededBufferSize < 1: ProcedureReturn "": EndIf
  
    *Buffer = AllocateMemory(NeededBufferSize)
    
    GetFileVersionInfo_(@File,0,NeededBufferSize,*Buffer)
    VerQueryValue_(*Buffer,"\\VarFileInfo\\Translation",@*Pointer,@PointerLen)
    If *Pointer
      TranslationCode = RSet(Hex(PeekW(*Pointer)),4,"0") + RSet(Hex(PeekW(*Pointer + 2)),4,"0")
      If VerQueryValue_(*Buffer,"\\StringFileInfo\\" + TranslationCode + "\\Comments",@*Pointer,@PointerLen)
        RetVal = Trim(PeekS(*Pointer))
      Else
        ; Manche Programme haben einen falschen TranslationCode, zu dem es kein Informationen-Block gibt.
        ; Ich habe die Erfahrung gemacht, dass in diesem Fall immer ein Block mit diesem TranslationCode vorhanden ist:
        If VerQueryValue_(*Buffer,"\\StringFileInfo\\040904E4\\Comments",@*Pointer,@PointerLen)
          RetVal = Trim(PeekS(*Pointer))
        EndIf
      EndIf
    EndIf
    FreeMemory(*Buffer)
  
    ProcedureReturn Trim(RetVal)
  EndProcedure
  
  Procedure.s GetFileCompanyName(File.s)
    Protected.i NeededBufferSize, PointerLen
    Protected   *Buffer, *Pointer
    Protected.s TranslationCode, RetVal
  
    NeededBufferSize = GetFileVersionInfoSize_(@File,0)
    If NeededBufferSize < 1: ProcedureReturn "": EndIf
  
    *Buffer = AllocateMemory(NeededBufferSize)
    
    GetFileVersionInfo_(@File,0,NeededBufferSize,*Buffer)
    VerQueryValue_(*Buffer,"\\VarFileInfo\\Translation",@*Pointer,@PointerLen)
    If *Pointer
      TranslationCode = RSet(Hex(PeekW(*Pointer)),4,"0") + RSet(Hex(PeekW(*Pointer + 2)),4,"0")
      If VerQueryValue_(*Buffer,"\\StringFileInfo\\" + TranslationCode + "\\CompanyName",@*Pointer,@PointerLen)
        RetVal = Trim(PeekS(*Pointer))
      Else
        ; Manche Programme haben einen falschen TranslationCode, zu dem es kein Informationen-Block gibt.
        ; Ich habe die Erfahrung gemacht, dass in diesem Fall immer ein Block mit diesem TranslationCode vorhanden ist:
        If VerQueryValue_(*Buffer,"\\StringFileInfo\\040904E4\\CompanyName",@*Pointer,@PointerLen)
          RetVal = Trim(PeekS(*Pointer))
        EndIf
      EndIf
    EndIf
    FreeMemory(*Buffer)
  
    ProcedureReturn Trim(RetVal)
  EndProcedure
  
  Procedure.s GetFileInternalName(File.s)
    Protected.i NeededBufferSize, PointerLen
    Protected   *Buffer, *Pointer
    Protected.s TranslationCode, RetVal
  
    NeededBufferSize = GetFileVersionInfoSize_(@File,0)
    If NeededBufferSize < 1: ProcedureReturn "": EndIf
  
    *Buffer = AllocateMemory(NeededBufferSize)
    
    GetFileVersionInfo_(@File,0,NeededBufferSize,*Buffer)
    VerQueryValue_(*Buffer,"\\VarFileInfo\\Translation",@*Pointer,@PointerLen)
    If *Pointer
      TranslationCode = RSet(Hex(PeekW(*Pointer)),4,"0") + RSet(Hex(PeekW(*Pointer + 2)),4,"0")
      If VerQueryValue_(*Buffer,"\\StringFileInfo\\" + TranslationCode + "\\InternalName",@*Pointer,@PointerLen)
        RetVal = Trim(PeekS(*Pointer))
      Else
        ; Manche Programme haben einen falschen TranslationCode, zu dem es kein Informationen-Block gibt.
        ; Ich habe die Erfahrung gemacht, dass in diesem Fall immer ein Block mit diesem TranslationCode vorhanden ist:
        If VerQueryValue_(*Buffer,"\\StringFileInfo\\040904E4\\InternalName",@*Pointer,@PointerLen)
          RetVal = Trim(PeekS(*Pointer))
        EndIf
      EndIf
    EndIf
    FreeMemory(*Buffer)
  
    ProcedureReturn Trim(RetVal)
  EndProcedure
  
  Procedure.s GetFileLegalCopyright(File.s)
    Protected.i NeededBufferSize, PointerLen
    Protected   *Buffer, *Pointer
    Protected.s TranslationCode, RetVal
  
    NeededBufferSize = GetFileVersionInfoSize_(@File,0)
    If NeededBufferSize < 1: ProcedureReturn "": EndIf
  
    *Buffer = AllocateMemory(NeededBufferSize)
    
    GetFileVersionInfo_(@File,0,NeededBufferSize,*Buffer)
    VerQueryValue_(*Buffer,"\\VarFileInfo\\Translation",@*Pointer,@PointerLen)
    If *Pointer
      TranslationCode = RSet(Hex(PeekW(*Pointer)),4,"0") + RSet(Hex(PeekW(*Pointer + 2)),4,"0")
      If VerQueryValue_(*Buffer,"\\StringFileInfo\\" + TranslationCode + "\\LegalCopyright",@*Pointer,@PointerLen)
        RetVal = Trim(PeekS(*Pointer))
      Else
        ; Manche Programme haben einen falschen TranslationCode, zu dem es kein Informationen-Block gibt.
        ; Ich habe die Erfahrung gemacht, dass in diesem Fall immer ein Block mit diesem TranslationCode vorhanden ist:
        If VerQueryValue_(*Buffer,"\\StringFileInfo\\040904E4\\LegalCopyright",@*Pointer,@PointerLen)
          RetVal = Trim(PeekS(*Pointer))
        EndIf
      EndIf
    EndIf
    FreeMemory(*Buffer)
  
    ProcedureReturn Trim(RetVal)
  EndProcedure
  
  Procedure.s GetFileLegalTrademarks(File.s)
    Protected.i NeededBufferSize, PointerLen
    Protected   *Buffer, *Pointer
    Protected.s TranslationCode, RetVal
  
    NeededBufferSize = GetFileVersionInfoSize_(@File,0)
    If NeededBufferSize < 1: ProcedureReturn "": EndIf
  
    *Buffer = AllocateMemory(NeededBufferSize)
    
    GetFileVersionInfo_(@File,0,NeededBufferSize,*Buffer)
    VerQueryValue_(*Buffer,"\\VarFileInfo\\Translation",@*Pointer,@PointerLen)
    If *Pointer
      TranslationCode = RSet(Hex(PeekW(*Pointer)),4,"0") + RSet(Hex(PeekW(*Pointer + 2)),4,"0")
      If VerQueryValue_(*Buffer,"\\StringFileInfo\\" + TranslationCode + "\\LegalTrademarks",@*Pointer,@PointerLen)
        RetVal = Trim(PeekS(*Pointer))
      Else
        ; Manche Programme haben einen falschen TranslationCode, zu dem es kein Informationen-Block gibt.
        ; Ich habe die Erfahrung gemacht, dass in diesem Fall immer ein Block mit diesem TranslationCode vorhanden ist:
        If VerQueryValue_(*Buffer,"\\StringFileInfo\\040904E4\\LegalTrademarks",@*Pointer,@PointerLen)
          RetVal = Trim(PeekS(*Pointer))
        EndIf
      EndIf
    EndIf
    FreeMemory(*Buffer)
  
    ProcedureReturn Trim(RetVal)
  EndProcedure
  
  Procedure.s GetFileOriginalFilename(File.s)
    Protected.i NeededBufferSize, PointerLen
    Protected   *Buffer, *Pointer
    Protected.s TranslationCode, RetVal
  
    NeededBufferSize = GetFileVersionInfoSize_(@File,0)
    If NeededBufferSize < 1: ProcedureReturn "": EndIf
  
    *Buffer = AllocateMemory(NeededBufferSize)
    
    GetFileVersionInfo_(@File,0,NeededBufferSize,*Buffer)
    VerQueryValue_(*Buffer,"\\VarFileInfo\\Translation",@*Pointer,@PointerLen)
    If *Pointer
      TranslationCode = RSet(Hex(PeekW(*Pointer)),4,"0") + RSet(Hex(PeekW(*Pointer + 2)),4,"0")
      If VerQueryValue_(*Buffer,"\\StringFileInfo\\" + TranslationCode + "\\OriginalFilename",@*Pointer,@PointerLen)
        RetVal = Trim(PeekS(*Pointer))
      Else
        ; Manche Programme haben einen falschen TranslationCode, zu dem es kein Informationen-Block gibt.
        ; Ich habe die Erfahrung gemacht, dass in diesem Fall immer ein Block mit diesem TranslationCode vorhanden ist:
        If VerQueryValue_(*Buffer,"\\StringFileInfo\\040904E4\\OriginalFilename",@*Pointer,@PointerLen)
          RetVal = Trim(PeekS(*Pointer))
        EndIf
      EndIf
    EndIf
    FreeMemory(*Buffer)
  
    ProcedureReturn Trim(RetVal)
  EndProcedure
EndModule

Define File.s = "notepad.exe"

Debug "FileComments:         " + FileInfo::GetFileComments(File)
Debug "FileCompanyName:      " + FileInfo::GetFileCompanyName(File)
Debug "FileDescription:      " + FileInfo::GetFileDescription(File)
Debug "FileInternalName:     " + FileInfo::GetFileInternalName(File)
Debug "FileLegalCopyright:   " + FileInfo::GetFileLegalCopyright(File)
Debug "FileLegalTrademarks:  " + FileInfo::GetFileLegalTrademarks(File)
Debug "FileOriginalFilename: " + FileInfo::GetFileOriginalFilename(File)
Debug "FileVersion:          " + FileInfo::GetFileVersion(File)
Debug "FixedFileType:        " + FileInfo::GetFixedFileType(File)
Debug "FixedFileVersion:     " + FileInfo::GetFixedFileVersion(File)
Debug "FixedProductVersion:  " + FileInfo::GetFixedProductVersion(File)
Debug "ProductName:          " + FileInfo::GetProductName(File)
Debug "ProductVersion:       " + FileInfo::GetProductVersion(File)