none
WPF, C# , Open Printer Settings , does not work as expected RRS feed

  • Question

  • Hallo all , 

    I am using code what I found because I have to implement functionality that at beginning of application , user sets printer settings and then just using visual. print

    This is code which opens the dialog but does not keep the settings saved for next printing :
    Next printing is done without printing dialog ... 

    [DllImport("winspool.Drv", EntryPoint = "DocumentPropertiesW", SetLastError = true,
     ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
            static extern int DocumentProperties(IntPtr hwnd, IntPtr hPrinter,
            [MarshalAs(UnmanagedType.LPWStr)] string pDeviceName,
            IntPtr pDevModeOutput, IntPtr pDevModeInput, int fMode);
    
            [DllImport("winspool.drv")]
            private static extern int OpenPrinter(string pPrinterName, out IntPtr hPrinter, IntPtr pDefault);
            [DllImport("winspool.drv")]
            private static extern int ClosePrinter(IntPtr phPrinter);
    
            [DllImport("kernel32.dll")]
            static extern IntPtr GlobalLock(IntPtr hMem);
            [DllImport("kernel32.dll")]
            static extern bool GlobalUnlock(IntPtr hMem);
            [DllImport("kernel32.dll")]
            static extern bool GlobalFree(IntPtr hMem);
    
            private const int DM_PROMPT = 4;
            private const int DM_OUT_BUFFER = 2;
            private const int DM_IN_BUFFER = 8;
    
    
            private void printDialog()
            {
                System.Windows.Controls.PrintDialog pDialog = new System.Windows.Controls.PrintDialog();
                pDialog.PageRangeSelection = PageRangeSelection.AllPages;
                pDialog.UserPageRangeEnabled = true;
                string name = printerAvailable.SelectedValue.ToString();
    
                PrintTicketConverter ptc = new PrintTicketConverter(name.ToString(), pDialog.PrintQueue.ClientPrintSchemaVersion);
                IntPtr mainWindowPtr = new WindowInteropHelper(this).Handle;
                byte[] myDevMode = ptc.ConvertPrintTicketToDevMode(pDialog.PrintQueue.DefaultPrintTicket, BaseDevModeType.UserDefault);
                GCHandle pinnedDevMode = GCHandle.Alloc(myDevMode, GCHandleType.Pinned);
                IntPtr pDevMode = pinnedDevMode.AddrOfPinnedObject();
    
                DocumentProperties(mainWindowPtr, IntPtr.Zero, name.ToString(), pDevMode, pDevMode, 14);
                pDialog.PrintQueue.DefaultPrintTicket = ptc.ConvertDevModeToPrintTicket(myDevMode);
                pinnedDevMode.Free();
    
    
            }
    And printing apporach:

     if (main_ViewModel.SelectedImageStr != string.Empty)
                    {
                        PrintingCustomDialog_View pcd = new PrintingCustomDialog_View();
                        pcd.Closing += Pcd_Closing;
                        var res = pcd.ShowDialog();
    /// not needed                    double cmToUnits = 100 / 2.54;
                        if (res == true)
                        {
                            ///can get out this cond.
                            if (main_ViewModel.SelectedImageStr != string.Empty)
                            {
                                var bi = new BitmapImage();
                                bi.BeginInit();
                                bi.CacheOption = BitmapCacheOption.OnLoad;
                                bi.UriSource = new Uri(main_ViewModel.SelectedImageStr);
    
                                bi.EndInit();
    
                                var vis = new DrawingVisual();
                                using (var dc = vis.RenderOpen())
                                {
                                    dc.DrawImage(bi, new Rect { Width = bi.Width, Height = bi.Height });
                                }
    
                                var dlg = new System.Windows.Controls.PrintDialog();
                                //dlg.PrintQueue = "abc" ; // this will be your printer. any of these: new PrintServer().GetPrintQueues()
                                dlg.PrintTicket.CopyCount = TempCopies;
                                //dlg.ShowDialog();
    
                                dlg.PrintVisual(vis, Properties.Settings.Default.SelectedPrinter);
                            }
                        }
    
                        else
                        {
    
                        }
                    }





    I find a variations of solutions with similar code but different settings but none of them worked ... 
    For instance , one person has different DocumentProperties parameters , another one suggest last parameter fMode to zero (I found 14 in it and I have absolutely no idea what does it mean) 

    Also In one forum I found this line with dm promt, buffer ... I change that but with no success. 

    Can I please ask for short or longer explanation ? not to some another forums but someting else. I would like to understand it quite more ... 

    Also I would like to ask , if someone can test my code or suggest (test first) changes , it would be also helpful for other people searching this....


    • Moved by CoolDadTx Monday, June 29, 2020 9:55 PM WPF related
    Monday, June 29, 2020 8:28 PM

All replies

  • This forum is for questions specifically related to C#. Please post questions related to WPF framework in the WPF forums.

    Michael Taylor http://www.michaeltaylorp3.net

    Monday, June 29, 2020 9:55 PM