2009-07-08 14 views
2

Nach der folgenden Seite:C# kundenspezifische Printdialog PInvoke DevMode Frage

http://msdn.microsoft.com/en-us/library/ms646964(VS.85).aspx

unterhalb der ersten Grafik: „Wenn der Benutzer auf die Schaltfläche OK klickt, PrintDlg liefert TRUE und die PRINTDLG Struktur informmation über die zurück Benutzerauswahl ".

In diesem Fall funktioniert mein benutzerdefinierter Druckdialog fast, aber ich versuche, Informationen über den Druckernamen, die Ausrichtung usw. zu extrahieren. Mein Verständnis ist, dass ich den Druckernamen abrufen muss Untersuchen Sie den hDevMode-Wert aus der Struktur PRINTDLG, um den Druckernamen anzuzeigen. Gibt es eine Funktion, mit der ich diese Informationen extrahieren kann?

Mein Code ist wie (wo PDLG meine definierte Instanz der Struktur PRINTDLG ist):

 bool f = false; 
     try 
     { 
      f = PrintDlg(ref pdlg); 
      DEVMODE dm = pdlg.hDevMode; 
      int k = 0; 
     } catch (Exception ex) 
     { 
      // hopefully it doesn't fail 
     } 

Wenn jemand jede pearlsof Weisheit hat da draußen, würde ich sicher, irgendwelche Tipps zu schätzen wissen.

Antwort

2

Im Folgenden wird gezeigt, wie der Name und der Treiber des Druckers extrahiert werden. Der Schlüssel ist, eine GlobalLock auf hDevNames, Marshal.PtrToStructure es in die CLR-Version der struct zu machen, und dann auf seinen Inhalt zugreifen. Denken Sie daran, GlobalUnlock wenn getan.

Sie könnten etwas Ähnliches mit hDevMode tun, das Ihnen Informationen über die Druckermetriken und -einstellungen liefert. Sie finden eine C# -Deklaration der DEVMODE Struktur here.

using System; 
using System.Runtime.InteropServices; 

namespace ConsoleApplication3 { 
    class Program { 

     // Win32 struct declarations 
     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)] 
     [System.Runtime.InteropServices.ComVisible(false)] 
     internal class PRINTDLG { 
      public Int32 lStructSize; 
      public IntPtr hwndOwner; 
      public IntPtr hDevMode; 
      public IntPtr hDevNames; 
      public IntPtr hDC = IntPtr.Zero; 
      public Int32 Flags; 
      public Int16 FromPage = 0; 
      public Int16 ToPage = 0; 
      public Int16 MinPage = 0; 
      public Int16 MaxPage = 0; 
      public Int16 Copies = 0; 
      public IntPtr hInstance = IntPtr.Zero; 
      public IntPtr lCustData = IntPtr.Zero; 
      public IntPtr lpfnPrintHook; 
      public IntPtr lpfnSetupHook = IntPtr.Zero; 
      public IntPtr lpPrintTemplateName = IntPtr.Zero; 
      public IntPtr lpSetupTemplateName = IntPtr.Zero; 
      public IntPtr hPrintTemplate = IntPtr.Zero; 
      public IntPtr hSetupTemplate = IntPtr.Zero; 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     public class DEVNAMES { 
      public short wDriverOffset; 
      public short wDeviceOffset; 
      public short wOutputOffset; 
      public short wDefault; 
     } 

     // import PrintDlg, GlobalLock and GlobalUnlock 
     [DllImport("comdlg32.dll", CharSet = CharSet.Auto)] 
     private static extern bool PrintDlg([In, Out] PRINTDLG lppd); 

     [DllImport("kernel32.dll")] 
     private static extern IntPtr GlobalLock(IntPtr hMem); 

     [DllImport("kernel32.dll")] 
     private static extern bool GlobalUnlock(IntPtr hMem); 

     static void Main(string[] args) { 
      // show the printer dialog box 
      PRINTDLG pd = new PRINTDLG(); 
      pd.lStructSize = Marshal.SizeOf(pd); 
      PrintDlg(pd); 

      // here's the meat -- extract the printer information 
      // out of pd.hDevNames... 
      DEVNAMES devNames = new DEVNAMES(); 

      // lock hDevNames into memory and get a pointer to it 
      IntPtr pDevNames = GlobalLock(pd.hDevNames); 

      // marshal into a DEVNAME struct 
      Marshal.PtrToStructure(pDevNames, devNames); 

      // pull out the device and driver strings; hopefully not much of 
      // that in DEVMODE 
      string sDevice = Marshal.PtrToStringUni((IntPtr) (
       pDevNames.ToInt32() + 
        devNames.wDeviceOffset * Marshal.SystemDefaultCharSize)); 
      string sDriver = Marshal.PtrToStringUni((IntPtr) (
       pDevNames.ToInt32() + 
        devNames.wDriverOffset * Marshal.SystemDefaultCharSize)); 
      string sOutput = Marshal.PtrToStringUni((IntPtr) (
       pDevNames.ToInt32() + 
        devNames.wOutputOffset * Marshal.SystemDefaultCharSize)); 

      // done -- release the global memory handle 
      GlobalUnlock(pd.hDevNames); 
     } 
    } 
} 
+0

Vielen Dank. Es gibt ein Problem, DEVMODE.devName zu öffnen, wenn der betreffende Drucker länger als 32 Zeichen ist. Ich konnte zusätzliche Informationen herausholen, aber dieses Feld konnte letztendlich nicht benutzt werden, also ging ich damit fort – coson

Verwandte Themen