2016-12-08 16 views
8

私は「回転180度」チェックボックスの下のように含まれている複数のプリンタがあります。Controlまたはアクセスカスタムプリンタ設定(180度回転)

ここenter image description here

は別のものだが(「ねぇ」 「いいえ」)を意味します

enter image description here

プログラムでこの値を設定し、PrintTicketを変更する方法はありますか?そうでない場合は、どうすれば現在の値を取得できますか?私のソフトウェアでは、これが設定されているかどうかを知る必要があり、設定されている場合は、可能であれば変更する必要があります。私のソフトウェアでは、printdialogを開く必要がなければ最高です。ユーザーがボタンをクリックせずに直接印刷できるソフトウェアなので、プログラムで設定または取得するのが私の探しているものです。

ManagementObjectSearcherと通常のPrintDocument.DefaultPageSettingsのプロパティで検索しましたが、何も見つかりませんでした。

このオプションが設定されていない場合、私は自動的にユーザー用に一時的に設定します(そうしないと、特定のプリンタで上下逆に印刷されます)。私はユーザーのためにそれを設定しようとするのが面倒だが、私はそれを動作させる方法を把握することはできません。私はDEVMODE構造体を見ていて、実装しようとしましたが、 "180度回転オプション"などはありません。

注:私はランドスケープモードを設定しようとしていません。これはかなり簡単で、何か異なっています。

私は次のことをやってみました: pdialog.PrintQueue.CurrentJobSettings.CurrentPrintTicket.PageOrientation = PageOrientation.ReversePortrait;

しかし、これが唯一のページの向きではなく、コンテンツを(コンテンツが同様に回転する必要があります)を反転。

私が印刷しているビジュアルを回転させると、余白はもはや正しくないので、どちらも機能しません!誰かが助けることを願っています。

ありがとうございます。

EDIT

私は変更する値を把握するハンスメソッドを使用していました。彼の方法はあらゆる種類のプリンタに適用されることに注意してください。 devmodePrintDialogの値を変更します。これは私が何時間も時間をかけて解決しましたので、私が助けることができる人は、ここに私のコードがあり、私は共有したり、助けてうれしいです!最初にDefaultPrintTicketnew PrintServer()から変更しましたが、UserPrintTicketは実際にはWindows Control Panel if you don't switch back to the original one. *However*, this only seemed to work on just my pc (which was necessary), on a virtual machine for example theの値の変化を見ることができる正しい方法と思われました。これは実際の使用よりむしろ練習でした。

var pdialog = new PrintDialog(); 

pdialog.PrintQueue = new PrintQueue(new LocalPrintServer(), _printername, PrintSystemDesiredAccess.AdministratePrinter); // this will be your printer. any of these: new PrintServer().GetPrintQueues() 

pdialog.PrintTicket.PageMediaSize = size; 
pdialog.PrintTicket.CopyCount = _amount; 

if (CheckPrinterDriverName(_printername)) 
{ 
    int magic = 361; 
    var defaulttckt = pdialog.PrintQueue.UserPrintTicket; 
    pdialog.PrintQueue.UserPrintTicket = PrinterModifier.ChangeDevMode(pdialog, magic, vis); 
    pdialog.PrintQueue.Commit(); 
    pdialog.PrintVisual(vis, "Label"); 
    //Set back old settings so it's not permanently changed 
    pdialog.PrintQueue.UserPrintTicket = defaulttckt; 
    pdialog.PrintQueue.Commit(); 
} 

...

class PrinterModifier 
{ 
    public static PrintTicket ChangeDevMode(PrintDialog pdialog, int prpty, DrawingVisual vis) 
    { 
     var queue = pdialog.PrintQueue; 
     var cvt = new PrintTicketConverter(queue.Name, PrintTicketConverter.MaxPrintSchemaVersion); 
     // Display dialog, don't make changes 

     var devmode1 = cvt.ConvertPrintTicketToDevMode(pdialog.PrintTicket, BaseDevModeType.UserDefault); 
     // Consistency check 
     var dmSize = BitConverter.ToInt16(devmode1, 68); 
     var dmDriverExtra = BitConverter.ToInt16(devmode1, 70); 

     if (devmode1[361] == 0) 
     { 
      devmode1[361] = 1; 
     } 
     return cvt.ConvertDevModeToPrintTicket(devmode1, PrintTicketScope.PageScope); 
    } 
} 

プリントダイアログの変化の値が、それはまだ間違って印刷します。変更は適用されません。どんな助けも歓迎です!

+0

あなたは自動的にそれを180度描くことはできませんか? –

+0

@ DanielA.Whiteは私の更新をチェックしています。それがなぜ私がそれにアクセスする必要があるかをもう少し明確にすることを願っています! – Markinson

+0

はx-y問題のように聞こえます。 –

答えて

7

これはおそらく、このプロパティがどのように変わったで実現することが可能です。ジェミニ宇宙計画のためにNASAによって募集された宇宙飛行士であるピーター・コンラッド(Pete Conrad)の紹介としてのおかしい真実の話。どのくらい長期の宇宙飛行が人間に影響を与えるのかを実際に考えていないので、医師は基本的に何か考えることができた。頻繁に非常に侵入して不快なテスト。コンラッドは反抗し、1つの心理テストに失敗しました。医者は彼に空白のカードを渡して、「あなたは何を見ますか?」と尋ねました。彼は即座にそれを押し戻し、「それは逆さまです」と述べました。

このプリンタは珍しいですが、いつも心配することはありません。おそらく、ある種の自動紙製本作業を含む生産ラインで動作するように設計されています。プリンタドライバはプロパティを任意に追加して動作をカスタマイズできますが、これはそのようなプロパティの1つです。あなたが見ているプロパティシートも同様に非標準で、プリンタドライバから来ています。

この設定を変更する方法を理解するには、まずthe DEVMODE structureを理解する必要があります。 winapiで使用される最も醜い構造について。これは可変サイズの構造体で、MSDNページに表示される宣言は標準プロパティのみをカバーします。プリンタドライバは任意に拡張することができ、dmDriverExtraフィールドは追加された余分なバイト数を追跡​​します。 dmSizeフィールドは、構造体の可変でない部分のサイズを報告します。これは、Windowsバージョン6(Vista以上)では220です。何かを点検する必要があります。

Winformsは、DEVMODEをPrinterSettings.GetHdevmode()メソッドで直接公開します。 WPFはそれをPrintTicketクラスを通して抽象化します。 PrintTicketをDEVMODEに変換して戻すには、PrintTicketConverter classを使用する必要があります。

リバースエンジニアリングする必要があるのは、この設定を格納するプライベートドライバデータの正確なフィールドです。プリンタの製造元だけがこの詳細を知っています、彼らはあなたの電話に答えるつもりはありません。いくつかのサンプルコードは、ちょうどメイン・ウィンドウコンストラクタで、何も行わないWPFのアプリでそれを試してみて、あなたは発見するのに役立ち、そのフィールドを確認します

using System.Printing;   // Add reference to System.Printing 
using System.Printing.Interop; // Add reference to ReachFramework 
using System.Diagnostics; 
.... 

    public MainWindow() { 
     InitializeComponent(); 
     // Assume default printer 
     var queue = new LocalPrintServer().DefaultPrintQueue; 
     var cvt = new PrintTicketConverter(queue.Name, PrintTicketConverter.MaxPrintSchemaVersion); 
     // Display dialog, don't make changes 
     var dlg = new PrintDialog(); 
     dlg.ShowDialog(); 
     var devmode1 = cvt.ConvertPrintTicketToDevMode(dlg.PrintTicket, BaseDevModeType.UserDefault); 
     // Consistency check 
     var dmSize = BitConverter.ToInt16(devmode1, 68); 
     var dmDriverExtra = BitConverter.ToInt16(devmode1, 70); 
     Debug.Assert(dmSize == 220); 
     Debug.Assert(dmDriverExtra > 0); 
     Debug.Assert(dmSize + dmDriverExtra == devmode1.Length); 
     // Display dialog again, do make the change 
     dlg.ShowDialog(); 
     var devmode2 = cvt.ConvertPrintTicketToDevMode(dlg.PrintTicket, BaseDevModeType.UserDefault); 
     var len = Math.Min(devmode1.Length, devmode2.Length); 
     for (int ix = 0; ix < len; ++ix) { 
      if (devmode1[ix] != devmode2[ix]) { 
       Debug.Print("Change at {0} from {1} to {2}", ix, devmode1[ix], devmode2[ix]); 
      } 
     } 
     // Tinker with the DEVMODE... 
     var magic = dmSize + 0; // Change this 
     Debug.Assert(magic < dmSize + dmDriverExtra); 
     devmode1[magic] = devmode2[magic]; 
     dlg.PrintTicket = cvt.ConvertDevModeToPrintTicket(devmode1); 
     // Verify that the setting changed! 
     dlg.ShowDialog(); 
    } 
} 

は、あなたが何バイトの変更が表示される場合がありますので注意してください。デバッグ> Windows>メモリ> Memory1ウィンドウは、文字列によって生成されたノイズをフィルタリングし、「アドレス」フィールドに「devmode2」を入れておくと便利なことがあります。

PrintTicketをカスタマイズする方法を知っていることが期待されます。そのプリンタに固有のものであり、ドライバの更新で変更できることに注意してください。だから、これを最も論理的なやり方として考えてみて、LayoutTransform propertyで印刷するビジュアルを回転させてみてください。

+0

あなたの670kの評判は、確かに理由がないわけではありません...コードの素晴らしい部分!まだ私が得ないものが1つあります。チェックボックスをクリックすると、361の出力が「0から1に変更されました」と出力されます(これは必ずそうでなければならないと思います!!)。しかし、 'var magic = dmSize + 361'に変更すると、何も変わりません。しかし、あなたのコードを 'devmode1 = devmode2'に変更すると、私は期待される結果を得ます。 'var magic = dmSize + 0'で何をするのですか?私はその行が間違っているか何かを理解していると思います。 – Markinson

+0

申し訳ありませんが、それはもっと明らかでした。 'var magic = 361;'を使用してください –

+0

あなたの助けと説明のために仕事に感謝しました。 – Markinson

関連する問題