Einsatz einer Manifest-Datei

Aus Wiki des Deutschsprachige Xbaseentwickler e. V.
Version vom 23. November 2021, 21:20 Uhr von Georg (Diskussion | Beiträge)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Zur Navigation springen Zur Suche springen


Bedeutung

Vereinfacht gesprochen ist eine Manifest-Datei eine Brücke zwischen einem Xbase++-Programm sowie verschiedenen Funktionalitäten des Betriebssystems, die anders nur sehr schwer abgreifbar sind.

Das volle Programm, das über die Einbindung einer Manifest-Datei genutzt werden kann, ist nicht unbedingt im ganzen Umfang über Xbase++ nutzbar, aber es gibt viele Aspekte, die im heutigen Umfeld beim Programmeinsatz zwingend nötig sind, um den erwarteten Komfort zu gewährleisten, den die Anwender vom Betriebssystem oder anderen Anwendungen kennen.

Alaska Software liefert zwei Beispiele für das Einbinden von Manifest-Dateien mit, diese Beispiele sind unter ..\source\samples\basic\manifest zu finden. Beide Beispiele sind ein guter Startpunkt, um sich an das Thema anzunähern.

Um mehr über die technischen Hintergründe zu erfahren, gibt es entsprechende Dokumentation von Microsoft, allerdings nur auf Englisch: Manifest Files Reference.


Beispiel einer Manifest-Datei

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
   <assemblyIdentity
      version="1.0.0.0"
      processorArchitecture="X86"
      name="YourCompanyName.YourDivision.YourApp"
      type="win32"
   />
   <description>Your app description here</description>
   <dependency>
      <dependentAssembly>
           <assemblyIdentity
               type="win32"
               name="Microsoft.Windows.Common-Controls"
               version="6.0.0.0"
               processorArchitecture="X86"
               publicKeyToken="6595b64144ccf1df"
               language="*"
          />
      </dependentAssembly>
   </dependency>
</assembly>

Diese Manifest-Datei ist aus dem oben genannten Beispiel von Alaska Software entnommen.


Einbinden von ActiveX-Controls

ActiveX-Controls müssen eigentlich auf dem entsprechenden PC, auf dem sie genutzt werden sollen, installiert sein.

Es gibt jedoch die Möglichkeit, sie über eine Manifest-Datei einzubinden, ohne dass eine zusätzliche Installation erforderlich ist.

   <file name="ctTray.ocx">
       <comClass description="ctTray ActiveX Control 4.0"
       clsid="{F64C15F5-713B-4A9F-AB48-04B10ABC1483}"
       progid="ctTRAY.ctTrayCtrl.4"
       threadingModel="apartment" />
   </file>


Quelle


Verbindung zwischen einer Manifest-Datei und dem Programm

als externe Datei

Wird eine externe Manifest-Datei verwendet, muss sie einer bestimmten Namenskonvention folgen. Sie muss den gleichen Namen wie das zugeordnete Programm haben, mit der zweiten Namenserweiterung .manifest. Heisst das Programm also krautsalat.exe, so muss die Manifest-Datei krautsalat.exe.manifest heissen, andernfalls wird sie ignoriert.


als Bestandteil der .exe-Datei

In diesem Fall muss die Manifest-Datei über eine .arc-Datei eingebunden werden.

In der .arc-Datei muss der Eintrag dann z.B. so aussehen:

#define MANIFEST_RESID 1
#define MANIFEST 24

USERDEF MANIFEST
 MANIFEST_RESID = FILE "extfile.exe.manifest"

Die .arc-Datei ist dann - wie üblich - für den Linker mit einzubinden.

In diesem Fall unterliegt übrigens der Namen der Manifest-Datei keinen Beschränkungen, da der Linker den Inhalt aus der .res-Datei übernimmt und die Namensübereinstimmung nicht für das Laden beim Programmbeginn erforderlich ist.


Beispiele für den Einsatz einer Manifest-Datei

Ermitteln der Skalierung des Monitors

Windows erlaubt es, abweichend von der "normalen" Skalierung von 100 % auch grössere Skalierungen einzustellen. Unter Windows 10 ist dies je Bildschirm möglich, d.h. man kann den einen Bildschirm mit 100 % und den zweiten mit 150 % Skalierung nutzen.

Wird eine höhere Skalierung verwendet, sollte ein Programm dies auch erkennen und seine Dialog-Elemente entsprechend anpassen können.

Um die Skalierung des Monitors ermitteln zu können, muss man unter Xbase++ mit einer Manifest-Datei arbeiten, die das Programm als "dpiAware" ausweist.

Hier zuerst ein Beispiel für eine solche Manifest-Datei:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
 <assemblyIdentity
   version="1.0.0.0"
   processorArchitecture="X86"
   name="demoprogramm"
   type="win32"
 />
 <description>Demo Programm</description>
 <dependency>
   <dependentAssembly>
     <assemblyIdentity
       type="win32"
       name="Microsoft.Windows.Common-Controls"
       version="6.0.0.0"
       processorArchitecture="X86"
       publicKeyToken="6595b64144ccf1df"
       language="*"
     />
   </dependentAssembly>
 </dependency>
 <asmv3:application  xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
   <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
     <dpiAware>true</dpiAware>
   </asmv3:windowsSettings>
 </asmv3:application>
</assembly>

Entscheidend für unser Beispiel ist der Eintrag <dpiAware>true</dpiAware>. Er besagt, dass die Anwendung unterschiedlich DPI-Werte erkennen soll.

Der Xbase++-Code für eine Erkennung der Skalierung sieht so aus:

#INCLUDE "Gra.ch"
...
FUNCTION GetTextDPI()
  LOCAL aTmp
  Local nRelation
  LOCAL oPS

  oPS := XbpPresSpace():New():Create( AppDesktop():WinDevice(), {100,100}, GRA_PU_LOENGLISH)
  aTmp:= oPS:SetViewport()
  oPS:Destroy()
  nRelation := aTmp[3]-aTmp[1]
RETURN (nRelation)

Es wird ein XbpPresSpace()-Objekt erzeugt, das die Ausgabeeinheit des Desktops verwendet. Der Bereich ist 100 * 100 Einheiten gross. Die Einheiten werden durch den Parameter GRA_PU_LOENGLISH definiert. In diesem Fall ist eine Einheit 0,01 Inch, entsprechend ist die Fläche des XbpPresSpace()-Objektes 1 Inch zum Quadrat. Die Methode :setViewPort() ruft die Koordinaten des XbpPresSpace()-Objektes ab. Die Differenz zwischen den entsprechenden Koordinaten-Paaren ergibt den DPI-Wert, wobei 96 der Standard-Wert für eine Skalierung von 100 % ist.