ようこそ 屋根裏部屋 mkII へ ログイン | 登録 | ヘルプ

Technological

ちょっとしたTIPSや私がはまったこと、調べたことなんかを書いていきます。

Winodws SDKヘルプの誤り(TaskDialog)

注意:これは2007/1/8現在のお話です。msdn2は時間とともに修正される可能性があります。

VistaにはTaskDialogというAPIが追加されました。

  • 補足事項が表示できる。
  • 新しいアイコン(盾)が表示できる。

くらいでしょうか。もっとカスタマイズしたければ、TaskDialogIndirect()もあります。msdn2とWindows SDK 6.0付属のヘルプには誤りがあります。

間違いはプロトタイプ宣言。ヘッダファイルは正しいので、ヘルプのみあてにしてコードを書くと、「引数が足りません」というエラーになります。正しくはこう。

1
2
3
4
5
6
7
8
9
HRESULT TaskDialog(
HWND hWndParent,
HINSTANCE hInstance,
PCWSTR pszWindowTitle,
PCWSTR pszMainInstruction,
PCWSTR pszContent,
TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons,
PCWSTR pszIcon,
int * pnButton)

アンダーラインのpszContentの部分が不足しています。このAPIを使って表示すると、こんな感じになります。上記の不足しているところは「補足」と表示されている部分です。

おまけとして、このダイアログをP/Invokeで呼び出すときの宣言部分を。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
   enum TaskDialog_Common_Button_Flags
{
TDCBF_OK_BUTTON = 0x0001,
TDCBF_YES_BUTTON = 0x0002,
TDCBF_NO_BUTTON = 0x0004,
TDCBF_CANCEL_BUTTON = 0x0008,
TDCBF_RETRY_BUTTON = 0x0010,
TDCBF_CLOSE_BUTTON = 0x0020
};

public enum TaskDialog_Result
{
FAILED = 0,
IDOK = 1,
IDCANCEL = 2,
IDRETRY = 4,
IDYES = 6,
IDNO = 7,
};

public enum TaskDialogIcon
{
Information = UInt16.MaxValue - 2,
Warning = UInt16.MaxValue,
Stop = UInt16.MaxValue - 1,
Question = 0,
SecurityWarning = UInt16.MaxValue - 5,
SecurityError = UInt16.MaxValue - 6,
SecuritySuccess = UInt16.MaxValue - 7,
SecurityShield = UInt16.MaxValue - 3,
SecurityShieldBlue = UInt16.MaxValue - 4,
SecurityShieldGray = UInt16.MaxValue - 8
}
[DllImport("comctl32.dll", CharSet = CharSet.Unicode, EntryPoint = "TaskDialog")]
public static extern int TaskDialog(
IntPtr hwndParent,
IntPtr hInstance,
String pszWindowTitle,
String pszMainInstruction,
String pszContent,
Int32 dwCommonButtons,
IntPtr pszIcon,
out int pnButton);

public void TaskDialogCallTest(IntPtr a_Handle)
{
IntPtr hwndPtr = a_Handle;
String msgTitle = "タイトル";
String msgMain = "主文";
String msgContent = "補足";
int idButtonMsg = (int)(TaskDialog_Common_Button_Flags.TDCBF_CANCEL_BUTTON | TaskDialog_Common_Button_Flags.TDCBF_OK_BUTTON);
int resultSelectButton;
IntPtr icon = new IntPtr((int)(TaskDialogIcon.SecurityShieldBlue));
int iRet = TaskDialog(hwndPtr, IntPtr.Zero, msgTitle, msgMain, msgContent, idButtonMsg, icon, out resultSelectButton);
}

変数iconはちょっと説明が必要になります。ここはC/C++ではMAKEINTRESOURCEW()マクロで定義された値を使用します。たとえばTD_SHIELD_ICONであれば、MAKEINTRESOURCEW(-4)と定義されています。そして、MAKEINTRESOURCEW()は

#define MAKEINTRESOURCEW(i) ((LPWSTR)((ULONG_PTR)((WORD)(i))))

と定義されているので、50行目のような記述になります。LPWSTRじゃないの?と思われるかもしれませんが、これはWindowsにおけるリソース扱いの伝統です。ID(数値)からWSTRへのポインタにしているだけです…が、ポインタの場合、サイズが合っていればかまわないので、LPWSTRにしなきゃいけない?とかおもわなくてもいいでしょう(かなり暴言)。

ここでは親ウィンドウのハンドルを渡してもらう形にしていますが、IntPtr.Zeroでもかまわないのかな。インスタンスもIntPtr.Zeroにしていますが、最初はリフレクションでMarShal.GetHINSTANCE()でとらなきゃだめかなぁとか思いましたよ(実際、やってみた)。GetHINSTANCE()がstaticなメソッドかと思ったら、そうじゃなくてやや意外。確かWin32の仕様ではstaticでも構わないと思うんですけどね…。

公開 2007年1月8日 0:50 投稿者 kkamegawa
タグ , , , ,

コメントの通知

この投稿にコメントが付いた場合にメールを受信するには、登録してください。ここ

また次のフィードから、お気に入りのRSSリーダーを使って最新の状態を知ることもできます。 コメントのRSSフィード

コメント

コメントはありません

どのような感想ですか?

(必須) 
必須 
(必須) 
Powered by Community Server, by Telligent Systems