Ich versuche, die EnumDisplaySettings zu verwenden, die die DEVMODE-Struktur als Ergebnisstruktur verwendet. Die DEVMODE Struktur verwendet intern einige Unionen, was die Verwendung in C# etwas komplizierter macht. Die Vereinigungen werden entweder zum Aufzählen von Anzeigen oder Druckern verwendet. FieldOffsets in einem StructLayout.Explicity sollten den Trick, Gewerkschaften zu verwenden, tun.Ausrichtungsfehler mit C# StructLayout.Explicit in DEVMODE-Struktur
Unten ist die Struktur, die von pinvoke.net kopiert wurde. Offensichtlich hatten einige andere auch Probleme mit dieser Struktur und lösten die Verbindungen, indem sie einfach StructLayout.Sequential erstellten und zwei Strukturen erstellten, eine für Anzeigen und eine für Drucker.
Die Ausnahme, die ausgelöst wird, ist Feld Offset 70, die besagt, dass das Feld nicht ausgerichtet oder durch ein anderes Feld überlappt ist. Und das ist, was ich nicht verstehe, natürlich können Felder mit expliziten Layout verwendet werden überlagert und auch das Feld vor dem Feld Offset 68 ist kurz, die nicht in Fieldoffset 70 überlappen kann. So funktioniert die Struktur wie von Microsoft definiert. Beim Verschieben des Fieldoffset von 70 auf 72 funktioniert es.
So bin ich wirklich nicht in der Reparatur meines Problems im Allgemeinen, aber ich interessiere mich für den Hintergrund dessen, was hier passiert.
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
public struct DEVMODE3
{
public const int CCHDEVICENAME = 32;
public const int CCHFORMNAME = 32;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHDEVICENAME)]
[System.Runtime.InteropServices.FieldOffset(0)]
public string dmDeviceName;
[System.Runtime.InteropServices.FieldOffset(32)]
public Int16 dmSpecVersion;
[System.Runtime.InteropServices.FieldOffset(34)]
public Int16 dmDriverVersion;
[System.Runtime.InteropServices.FieldOffset(36)]
public Int16 dmSize;
[System.Runtime.InteropServices.FieldOffset(38)]
public Int16 dmDriverExtra;
[System.Runtime.InteropServices.FieldOffset(40)]
public uint dmFields;
[System.Runtime.InteropServices.FieldOffset(44)]
Int16 dmOrientation;
[System.Runtime.InteropServices.FieldOffset(46)]
Int16 dmPaperSize;
[System.Runtime.InteropServices.FieldOffset(48)]
Int16 dmPaperLength;
[System.Runtime.InteropServices.FieldOffset(50)]
Int16 dmPaperWidth;
[System.Runtime.InteropServices.FieldOffset(52)]
Int16 dmScale;
[System.Runtime.InteropServices.FieldOffset(54)]
Int16 dmCopies;
[System.Runtime.InteropServices.FieldOffset(56)]
Int16 dmDefaultSource;
[System.Runtime.InteropServices.FieldOffset(58)]
Int16 dmPrintQuality;
[System.Runtime.InteropServices.FieldOffset(44)]
public POINTL dmPosition;
[System.Runtime.InteropServices.FieldOffset(52)]
public Int32 dmDisplayOrientation;
[System.Runtime.InteropServices.FieldOffset(56)]
public Int32 dmDisplayFixedOutput;
[System.Runtime.InteropServices.FieldOffset(60)]
public short dmColor; // See note below!
[System.Runtime.InteropServices.FieldOffset(62)]
public short dmDuplex; // See note below!
[System.Runtime.InteropServices.FieldOffset(64)]
public short dmYResolution;
[System.Runtime.InteropServices.FieldOffset(66)]
public short dmTTOption;
[System.Runtime.InteropServices.FieldOffset(68)]
public short dmCollate; // See note below!
[System.Runtime.InteropServices.FieldOffset(70)]
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHFORMNAME)]
public string dmFormName;
[System.Runtime.InteropServices.FieldOffset(102)]
public Int16 dmLogPixels;
[System.Runtime.InteropServices.FieldOffset(104)]
public Int32 dmBitsPerPel;
[System.Runtime.InteropServices.FieldOffset(108)]
public Int32 dmPelsWidth;
[System.Runtime.InteropServices.FieldOffset(112)]
public Int32 dmPelsHeight;
[System.Runtime.InteropServices.FieldOffset(116)]
public Int32 dmDisplayFlags;
[System.Runtime.InteropServices.FieldOffset(116)]
public Int32 dmNup;
[System.Runtime.InteropServices.FieldOffset(120)]
public Int32 dmDisplayFrequency;
}
Danke für die Rückmeldung und den Link. Es ist immer traurig, dass die Methoden verfügbar sind, aber auf intern gesetzt sind. Die Struktur enthält nur die Aufzählung für die Anzeige, nicht für Drucker. Wie würdest du die Gewerkschaften dann lösen -> 2 verschiedene Strukturen? Was ist, wenn ich über alle Elemente aufzählen möchte? – msedi
Es ist eine hässliche Mutter. Die Gewerkschaften versuchen, die Unterschiede zwischen dem Devmode für einen Drucker und einem für eine Anzeige zu dokumentieren. Der eine, mit dem ich verlinkt bin, stimmt mit dem Union-Flavor für eine Anzeige überein, was Sie versuchen zu verwenden. Wenn Sie eine für einen Drucker benötigen, fügen Sie einfach eine weitere Deklaration hinzu, Windows interessiert sich nicht für den C# -Strukturnamen. –
In Ordnung. Ich hatte gehofft, mehr "generische" Lösung zu haben, aber das bedeutet, dass ich zweimal mit verschiedenen Strukturen aufzählen muss und dann entscheiden muss, was ich bekommen habe. Das ist für mich in Ordnung, zeigt aber auch, dass einige Strukturen in Windows nicht sehr gut (oder lang anhaltend) definiert wurden. – msedi