2016-05-12 9 views
2

Aus Interoperabilitätsgründen muss ich mit der ANSI und der Unicode-Version der Windows-API-Struktur arbeiten (DEVMODE).Einfache Möglichkeit zur Arbeit mit der Ansi und der Unicode-Version einer Windows-API-Struktur in C#/VB

Gibt es eine Möglichkeit, das zu tun, ohne alles zu deklarieren zweimal? Derzeit sind meine structs wie folgt definiert:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
struct DevModeAnsi 
{ 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] 
    public string dmDeviceName; 
    public Int16 dmSpecVersion; 
    // ... lots of other fields ... 
    public Int16 dmOrientation; 
    // ... lots of other fields ... 
} 

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
struct DevModeUnicode 
{ 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] 
    public string dmDeviceName; 
    public Int16 dmSpecVersion; 
    // ... lots of other fields ... 
    public Int16 dmOrientation; 
    // ... lots of other fields ... 
} 

und, schlimmer noch, muss ich meinen Code alle auch duplizieren:

bool IsLandscapeOrientation(DevModeAnsi d) { return d.dmOrientation == DMORIENT_LANDSCAPE; } 
bool IsLandscapeOrientation(DevModeUnicode d) { return d.dmOrientation == DMORIENT_LANDSCAPE; } 

Ich habe folgende Lösungen in Betracht gezogen:

  • Eine gemeinsame Basisstruktur erstellen: Funktioniert nicht, da Strukturen keine Vererbung unterstützen.

  • Verwenden Sie eine gemeinsame Schnittstelle: Funktioniert nicht, da Schnittstellen keine Felder, nur Eigenschaften enthalten können. Also würde ich eine Eigenschaft für jedes einzelne Feld erstellen müssen Ich möchte zugreifen, Vervierfachung die Liste der Felder statt einfach zu verdoppeln.

  • T4: Letzter Ausweg, aber ich würde lieber vermeiden, dass diese zusätzliche Schicht der Komplexität, wenn möglich.

Gibt es eine elegante Lösung, die ich verpasst habe?

+1

* Gibt es eine Möglichkeit, dies zu tun, ohne alles doppelt zu deklarieren? * Nein. * Gibt es eine elegante Lösung, die ich verpasst habe? * Nein. –

+0

Nun, sicher, es gibt keinen erdenklichen Grund, CharSet.Ansi zu verwenden .Das Diskettenlaufwerk auf der letzten Windows ME Maschine ist vor 5 Jahren gescheitert, es lebt nur noch in Schande weiter. Vermeiden Sie bitte eine XY-Frage. –

+0

@HansPassant: Sagen Sie das zu Microsoft: Das Serialisieren eines MS Access 2007-Berichts in eine Textdatei mit 'SaveAsText' speichert die Druckereinstellungen als ANSI (!) DEVMODE-Struktur. Mit anderen Worten: Ja, ich habe ein tatsächliches Altsystem, das eine ANSI DEVMODE-Struktur zurückgibt. – Heinzi

Antwort

3

Gibt es Ein Weg, das zu tun, ohne alles doppelt zu deklarieren?

Nr

Gibt es eine elegante Lösung, die ich verpasst habe?

Nr

Sie könnten Ihren eigenen Rangier-Code schreiben solche Strukturen mit der zusätzlichen Flexibilität serialisiert die Sie wünschen. Aber der Aufwand würde den Nutzen bei weitem übersteigen.

0

Ich würde eine Vorlage erstellen, die den Strukturnamen erhalten würde und die Felddeklarationen enthalten würde. Ein Ordner würde der Vorlage zugeordnet werden. Wann immer eine bestimmte ausführbare Datei, die dieser Funktion zugeordnet ist, ausgeführt würde, würde sie die Dateien als Ausgabe erzeugen. Der Ordner würde zu einem Autoloader hinzugefügt werden und die ausführbare Datei würde die folgenden Befehle unterstützen:

  • addField
  • mofidyfield
  • RemoveField
  • addstructure
  • removestructure