「一気に最後まで読んだ」本、教えて下さい!

メインループでメッセージを拾ってモードレスで表示した画面のTabキー制御を行いたいのですが、以下のプログラムでTabキーはコントロール間を移動しますが、移動の順番がタブオーダーと全く違います。

-------------------------------------------------
// メイン ウィンドウを作成して、実行します
Form1^m_form = gcnew Form1();
m_form->Show();

msg.message = WM_CREATE;
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (!IsDialogMessage( (HWND)m_form->Handle.ToPointer(), &msg ))
{
// メッセージが未処理の場合は処理を行う
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
-------------------------------------------------

m_form->ShowDialog();
にしたり、上記ループを
Application::Run(gcnew Form1());
に変更するとちゃんとタブオーダーの順番で移動します。

訳有りで、ループ処理を変えたくはありません。
ネットで調べる限りタブ移動について「IsDialogMessage」を
入れるという疑問はあったのですが、それ以降の動作については
何も書かれていないようです。
上記ループの書き方でタブ移動がうまく行えない場合が
あるのでしょうか?
どなたかご存知でしたら教えてください

A 回答 (3件)

何で開発してますか? たぶん VC2005以降のCLRだと思いますが



メインフォーム(Form1)の中のコントロールのタブ移動制御ってことでしょうか

メッセージループ自体は『.NET Freamework』に任せてしまえば良いように思います
タブオーダーの指定はどのようになさったのでしょう

タブオーダーの指定を変更すると form1.hのInitializeComponentの中の各コントロールを定義している部分で
this->button1->TabIndex = 1;
などでタブオーダー順が変更されていると思います
この順序でタブキーでの移動をするはずなんですが …

現象を再現できる最低限の手順を投稿してみましょう
    • good
    • 0
この回答へのお礼

早速の回答ありがとうございます。
開発環境はVC2005のCLRです。

テスト画面でコントロールの数を減らしてやっています。

画面には3つのボタンを貼り付けました。
ソース内でのタブオーダーは
this->button1->TabIndex = 0;
this->button2->TabIndex = 1;
this->button3->TabIndex = 2;
となっていますが、
実行すると
button1 -> button3 -> button2
の順に移動します。

お礼日時:2008/01/09 16:26

コントロールの登録順が関連しているようです



button1,button2,button3の順序で登録した場合
InitComponentの最後のほうで
this->Controls->Add(this->button3);
this->Controls->Add(this->button2);
this->Controls->Add(this->button1);
といった具合に並ぶかと思います

この状態で起動されたフォームを SPY++などで確認してみると
button1の次のウィンドウは無しになっています前のウィンドウはbutton2を指しています
同様に button2は前がbutton3で次がbutton1
button3の場合前が無し次がbutton2
となっています
つまり button1にフォーカスがある場合に『TAB』が押されると
次のウィンドウを探しますがこれがありません
したがってこの親であるForm1は 自分の子ウィンドウのリストにある最初の子にフォーカスを与えます
この最初の子が InitCompornentで最初に追加されたコントロールになります
したがってbutton3がフォーカスを受け取ることになります
同様に button3にフォーカスがあるとき『TAB』を押すと
次のコントロールであるbutton2がフォーカスを受け取ります

this->Controls->Add(this->button1);
this->Controls->Add(this->button2);
this->Controls->Add(this->button3);
といった順に登録するとご希望通りのTAB順になります

.NET freameworkでは TabIndexを参照して次のコントロールを取得しているのであろうと思います

お示しのメッセージループではフォームを閉じた際に例外が発生してしまうと思います
Form1がDisposedされてしまっているのに Handleプロパティにアクセスするためです
    • good
    • 0
この回答へのお礼

ありがとうございました。
Addの順番を見たら確かにばらばらでした。
順番を昇順に並び替えたら、きちんと動作しました。
タブオーダーがきかなかったのはショックですが。。。

お礼日時:2008/01/09 18:46

> タブオーダーがきかなかったのはショックですが。

。。
タブオーダーが利かなかったのではありません
ちゃんと処理されております
ただ、処理方法が.NET FrameworkとWinAPIとで違うから今回のような現象になってしまうのです

扱う環境を適切に使用する場合起きない現象だと思います

現に Application::Run経由の場合きちんとデザイナーで指示したタブオーダーになりますし、コントロールの登録順を希望するとおりに配置すればWinAPIでも処理されます

無理やり WinAPIで行う際に 新たなフォームを追加するとアプリケーションクラスから使えないようです
# 詳細の調査はしておりません
    • good
    • 0
この回答へのお礼

理解不足で申し訳ありません。
本当に助かりましたm(__)m
これで、締め切らせていただきます。

お礼日時:2008/01/10 10:11

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!