ウィザードを作成しているのですが、「戻る」「次へ」「完了」の各ボタンの設定がうまくいきません。
ただこれらのボタンを付けるだけならできたのですが、そのページ内全ての項目に入力されていないと「次へ」「完了」のボタンが無効の状態になるように、全ての項目に入力が完了すれば有効の状態になるようにしたかったので、WM_COMMANDでコントロールの状態を見てPropSheet_SetWizButtons()で設定していたのですが、これだとウィザードの最終ページで「完了」ではなく「次へ」ボタンになったままで、一旦前のページに戻るかこの「次へ」ボタンを押すと「完了」ボタンになります。WM_COMMANDへ追加したコントロールを調べてボタンの状態を設定しなおしている部分をコメントアウトすると正常になるので、ここがいけないのだとは思うのですが、どう修正すればよいのかわかりません。
WM_NOTIFYにPSN_SETACTIVEメッセージは届いているというのは確認できましたが、ここでPropSheet_SetWizButtons()を呼んでも無視されているような感じです。
どなたかアドバイスよろしくお願いします。
環境:Windosw2000,VC++6.0(SP5),SDK
ウィザードの部分です↓
http://www.geocities.co.jp/SiliconValley-Oakland/1272/code.htm
IDC_EDIT がどのプロシージャでも同じです。
最後は IDC_EDIT3 だと思いますが...。
返信ありがとうございます。
ダイアログエディタで作成すると、ダイアログ3つにそれぞれエディットボックス1つを配置した場合どれも「IDC_EDIT1」という名前になるので、「1」だけを取って「IDC_EDIT」としていたのですが、これがいけなかったということですよね。
アドバイスどおりに3ページそれぞれに配置してあるエディットボックスに別のIDをつけると問題はなくなりました。
しかし、ただウィザードを作っただけ(次へボタンの無効化などしない)だと修正する前の各ダイアログ間で同じコントロールIDを使った状態でも3ページ目できちんと「完了」ボタンになっています。それと、『猫でもわかるプログラミング』のhttp://www.kumei.ne.jp/c_lang/sdk3/sdk_212.htmでウィザードの作り方についてかかれているのですが、ここでは各ダイアログ間で同じコントロールIDを使用しているのです。
ウィザード作成について検索して調べてはみたのですが、検索の仕方が悪いのか他に詳しく解説してくれているところが見つからなかったので比較などができなかったのですが、http://www.kumei.ne.jp/c_lang/sdk3/sdk_212.htmもコントロールIDが重複しているという点では間違っているのでしょうか?
2番目で
case WM_NOTIFY:
lppshN = (LPPSHNOTIFY)lp;
switch (lppshN->hdr.code) {
case PSN_SETACTIVE:
PropSheet_SetWizButtons(GetParent(hDlgWnd), PSWIZB_BACK);
break;
}
break;
case PSN_WIZNEXT:
PropSheet_SetWizButtons(GetParent(hDlgWnd),PSWIZB_BACK|PSWIZB_FINISH);
でいきませんか?
返信ありがとうございます。
2番目に追加してみました。しかし、結果は同じで内容がかかれているかチェックして「次へ」などのボタンを有効/無効に切り替えてやる部分を入れたままだと異なったダイアログ間でも同じ「IDC_EDIT」があると正常なウィザードになりませんでした。
やはり、コントロールIDを変えてやるしかないのでしょうか。
すべての、
case PSN_SETACTIVE:
PropSheet_SetWizButtons(GetParent(hDlgWnd), PSWIZB_BACK);
break;
を
case PSN_SETACTIVE:
PropSheet_SetWizButtons(GetParent(hDlgWnd), PSWIZB_BACK);
return FALSE;
にして、いきませんか?
それか、それぞれのプロシージャの最後を
return true;
ではなく
return FALSE;
にしてみて下さい。
返信ありがとうございます。
どちらも試してみましたが、駄目でした。
それと、両方を実施した場合も試しましたが、結果は同じでした。
やはり「PropSheet_SetWizButtons」マクロをWM_COMMANDで使うのがいけないのでしょうか。
試しに
case WM_COMMAND:
switch (LOWORD(wp)) {
case IDC_EDIT:
char bufStr[256];
GetWindowText(GetDlgItem(hDlgWnd, IDC_EDIT), bufStr, sizeof(bufStr));
if(strcmp(bufStr,"")!=0) { SendMessage(hDlgWnd,PSM_SETWIZBUTTONS,0,(DWORD)PSWIZB_NEXT);}
else { SendMessage(hDlgWnd,PSM_SETWIZBUTTONS,0,(DWORD)NULL);}
break;
としてみましたがこれだと次へボタンすら有効にならなくなってしまいました。「SendMessage」の使い方とかも間違ってるのかもしれません。それともマクロ以外で直接メッセージを送ろうとしたのがいけなかったのでしょうか。
WM_NOTIFYのところを
case WM_NOTIFY:
switch (((NMHDR*)lp)->code) {
case PSN_SETACTIVE:
PropSheet_SetWizButtons(GetParent(hDlgWnd), PSWIZB_BACK|PSWIZB_FINISH);
break;
}
のようにしてみたらどうでしょうか。
やはり原因はWM_COMMANDの部分にありました。
「EN_CHANGE」を使おうとしたものの、使い方がいまいちわかっておらず「IDC_EDIT」のみでも「次へ」などのボタンを有効、無効に切り替えることが一応できていたので、大丈夫だろうなどと安易に考えてそのままにしていたのがわるかったようです。
SendMessageが実行されているのかどうか確かめるためにとりあえず、その直後にMessageBoxを入れて動かしてみたのですが、やたらとメッセージボックスが繰り返し出てきてしまうので、ここに原因があると改めて認識しました。そこでもう一度「EN_CHANGE」について調べて使ってみると、正常に有効/無効の切り替えができるようになりました。
ただし、「戻る」で戻ったときに「PSN_SETACTIVE」でボタンを無効にしていたためにこの部分も書き換えてエディットボックスに内容がかかれているかどうかチェックする必要がでてきました。
長くお付き合いくださってありがとうございました。
今後も質問させていただくことがあると思うので、そのときはまたよろしくお願いします。
実際に書き換えた後のコードです(一部)。
case WM_COMMAND:
switch (LOWORD(wp)) {
case IDC_EDIT:
if(HIWORD(wp)==EN_CHANGE){
char bufStr[256];
GetWindowText(GetDlgItem(hDlgWnd, IDC_EDIT), bufStr, sizeof(bufStr));
if(strcmp(bufStr,"")!=0) { PropSheet_SetWizButtons(GetParent(hDlgWnd), PSWIZB_NEXT); }
else { PropSheet_SetWizButtons(GetParent(hDlgWnd), NULL); }
}
break;
default:
return false;
}
break;
ツイート | ![]() |