C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[5]: x64でPrintDlg


(過去ログ 97 を表示中)

[トピック内 6 記事 (1 - 6 表示)]  << 0 >>

■58038 / inTopicNo.1)  x64でPrintDlg
  
□投稿者/ 焦げ太 (25回)-(2011/03/24(Thu) 10:30:44)

分類:[C#] 

こんにちは。

PrintDlgを使用していて、x86では正常に動作していました。
今回、x64対応をすることとなりAnyCPUでコンパイルしたものを
64bitOSで動作確認していたのですが PrintDlg でダイアログが
表示されず、戻り値がfalseで返ってきます。
特にエラーなどのメッセージは表示されません。

64bitOSで PrintDlg は使用できないのでしょうか?
解決策を模索中です、情報をお持ちの方ご協力お願います。

以下ソースです。

const Int32 PD_RETURNDC = 0x100;

[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 = PD_RETURNDC;
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;
}

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

public static void test()
{
PRINTDLG pd = new PRINTDLG();
pd.lStructSize = Marshal.SizeOf(pd);
if (PrintDlg(pd) == false) return;
//以下省略
}

引用返信 編集キー/
■58041 / inTopicNo.2)  Re[1]: x64でPrintDlg
□投稿者/ todo (130回)-(2011/03/24(Thu) 10:57:24)
何故、System.Windows.Forms.PrintDialogクラスを使わないのですか?

PrintDialog.UseEXDialog プロパティ
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.printdialog.useexdialog(v=vs.90).aspx

>AMD64 マイクロプロセッサの場合、PrintDialog クラスは、UseEXDialog プロパティを true に設定しないと動作しない可能性があります。

APIで言うと PrintDialog(API)は動作しない可能性があるのでPrintDialogEx(API)を使うべし?

引用返信 編集キー/
■58043 / inTopicNo.3)  Re[2]: x64でPrintDlg
□投稿者/ 焦げ太 (27回)-(2011/03/24(Thu) 11:31:17)
No58041 (todo さん) に返信
> 何故、System.Windows.Forms.PrintDialogクラスを使わないのですか?

言葉足らずで失礼しました。
GetDeviceCapsを使用するため、PrintDlgでHDCを取得しています。
以前、質問させていただきました。
http://bbs.wankuma.com/index.cgi?mode=al2&namber=55332&KLOG=93

> PrintDialog.UseEXDialog プロパティ
> http://msdn.microsoft.com/ja-jp/library/system.windows.forms.printdialog.useexdialog(v=vs.90).aspx
>
> >AMD64 マイクロプロセッサの場合、PrintDialog クラスは、UseEXDialog プロパティを true に設定しないと動作しない可能性があります。
>
> APIで言うと PrintDialog(API)は動作しない可能性があるのでPrintDialogEx(API)を使うべし?

有力な情報ありがとうございます。
PrintDlgExにて試してみます。

引用返信 編集キー/
■58108 / inTopicNo.4)  Re[3]: x64でPrintDlg
□投稿者/ 焦げ太 (29回)-(2011/03/25(Fri) 16:01:38)
2011/03/25(Fri) 16:08:18 編集(投稿者)
PrintDlgExで確認中で、
とりあえず、32bitOS上でPrintDlgExが動作するところまで
いきましたが、64bitOS上ではどうにもうまくいきません。

以下のようにやっていますが、hResult に 80070057 が
返ってきます。エラー値を調べたのですが引数エラーの
ようです。

◆構造体メンバの型がおかしいのでしょうか?

◆それと、ググったサイトでPrintDlgExの宣言で
 [In(), Out()]と括弧付きで宣言しているのを見つけたのですが
 [In, Out]とどちらがあっているのでしょうか?
  ※そもそも違いがわかりませんorz

◆EXのほうは「PD_PRINTSETUP」がフラグにないのですね。。。
 ボタンを「印刷」→「OK」にしたいところですが、、、
 とりあえずはx64で動作させたいところです。

//プリンタダイアログEX
[DllImport("comdlg32.dll", CharSet = CharSet.Auto)]
private static extern int PrintDlgEx([In, Out] PRINTDLGEX lppd);

//Flags
private const Int32 PD_NOSELECTION = 0x4;           
private const Int32 PD_NOPAGENUMS = 0x8;            
private const Int32 PD_PRINTSETUP = 0x40;           
private const Int32 PD_RETURNDC = 0x100;            
private const Int32 PD_HIDEPRINTTOFILE = 0x100000;  
private const Int32 PD_NONETWORKBUTTON = 0x200000;
private const Int32 PD_NOCURRENTPAGE = 0x800000;    

//戻り値
private const int PD_RESULT_CANCEL = 0;
private const int PD_RESULT_PRINT = 1; 
private const int PD_RESULT_APPLY = 2; 

//PRINTDLGEX CLASS
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)]
[ComVisible(false)]
private class PRINTDLGEX
{
    public Int32 lStructSize;
    public IntPtr hwndOwner;
    public IntPtr hDevMode;
    public IntPtr hDevNames;
    public IntPtr hDC = IntPtr.Zero;
    public Int32 Flags = PD_RETURNDC;
    public Int32 Flags2 = 0;
    public Int32 ExclusionFlags = 0;
    public Int32 nPageRanges = 0;
    public Int32 nMaxPageRanges = 0;
    public IntPtr lpPageRanges = IntPtr.Zero;
    public Int32 nMinPage = 0;
    public Int32 nMaxPage = 0;
    public Int32 Copies = 1;
    public IntPtr hInstance = IntPtr.Zero;
    public IntPtr lpPrintTemplateName;
    public IntPtr lpCallback = IntPtr.Zero;
    public Int32 nPropertyPages = 0;
    public IntPtr lphPropertyPages = IntPtr.Zero;
    public Int32 nStartPage = -1;
    public Int32 dwResultAction = 0;
}

void test()
{
        PrintDocument pd = new PrintDocument(); //<--実際はデフォルトプリンタではないです
        IntPtr hDevMode = pd.PrinterSettings.GetHdevmode();
        IntPtr hDevNames = pd.PrinterSettings.GetHdevnames();

        PRINTDLGEX pdlg = new PRINTDLGEX();
        pdlg.lStructSize = Marshal.SizeOf(pdlg);
        pdlg.hwndOwner = owner.Handle;
        pdlg.hDevMode = hDevMode;
        pdlg.hDevNames = hDevNames;
        pdlg.Flags = PD_HIDEPRINTTOFILE | PD_NOSELECTION | PD_NOCURRENTPAGE | PD_NOPAGENUMS | PD_RETURNDC;
        int hResult = PrintDlgEx(pdlg);
        if ((hResult != 0) || (pdlg.dwResultAction == PD_RESULT_CANCEL))
        {
            return DialogResult.Cancel;
        }
}

引用返信 編集キー/
■58126 / inTopicNo.5)  Re[4]: x64でPrintDlg
□投稿者/ Hongliang (763回)-(2011/03/25(Fri) 22:26:59)
Win32API では基本的に PackSize は 8 じゃなかったでしたっけ。

> ◆それと、ググったサイトでPrintDlgExの宣言で
>  [In(), Out()]と括弧付きで宣言しているのを見つけたのですが
>  [In, Out]とどちらがあっているのでしょうか?
> ※そもそも違いがわかりませんorz
属性を定義するクラスは HogeAttribute というように Attribute をサフィックスとすることが推奨されており、
属性宣言においてサフィックスの Attribute は省略できます。
つまり、これらは実際には InAttribute クラスおよび OutAttribute クラスを指しています。
で、属性を宣言するに当たって引数を指定することができます。
ComVisible 属性なら COM に見せるかどうかを bool 型の引数で表現しています。
() は引数無しですが、属性宣言において引数無しの場合は括弧を省略することが認められています。
つまりは、[In] は [InAttribute()] の省略記述であり、この二つは同一の意味を表現します。
引用返信 編集キー/
■58153 / inTopicNo.6)  Re[5]: x64でPrintDlg
□投稿者/ 焦げ太 (30回)-(2011/03/28(Mon) 10:22:45)
No58126 (Hongliang さん) に返信
> Win32API では基本的に PackSize は 8 じゃなかったでしたっけ。

ご返信ありがとうございます。
PackSize = 8でPrintDlgEx、PrintDlgの両方とも動作しました。
ちなみに確認した環境はADM64でWindows2008 Serverです。
他環境での確認も行って行く予定です。

>>◆それと、ググったサイトでPrintDlgExの宣言で
>> [In(), Out()]と括弧付きで宣言しているのを見つけたのですが
>> [In, Out]とどちらがあっているのでしょうか?
>> ※そもそも違いがわかりませんorz
> 属性を定義するクラスは HogeAttribute というように Attribute をサフィックスとすることが推奨されており、
> 属性宣言においてサフィックスの Attribute は省略できます。
> つまり、これらは実際には InAttribute クラスおよび OutAttribute クラスを指しています。
> で、属性を宣言するに当たって引数を指定することができます。
> ComVisible 属性なら COM に見せるかどうかを bool 型の引数で表現しています。
> () は引数無しですが、属性宣言において引数無しの場合は括弧を省略することが認められています。
> つまりは、[In] は [InAttribute()] の省略記述であり、この二つは同一の意味を表現します。

大変わかりやすい説明をしていただきありがとうございます。

ググって見つけたソースなどを参考にすることは多々あり、できれば
その全てを理解したいところですが、知識不足のためなかなか難しい
ところです。
ですが、理解しないまま使用することは問題が発生したときの対応も
難しくなりますので、なるべく理解できるよう学習に励んでいきたい
と思います。

ご協力していただいた皆様に感謝します。
ありがとうございました。<(_ _)>

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -