おせわになります。
早速ですが、コンボボックスのソートを切った状態で
CCC
AAAA
BBDD
AA
BBBB
というデータを4つセットしたとします。
・コンボボックスのストリングメンバにAA
・SetWindowText(AA)
・SetCurSel(3):
としてなんとかリストの選択をAAにしようとしているのですが
ドロップダウンリストリストを表示すると、
どうしてもAAAAが選択された状態になってしまいます。
どうもリストがぺろんと表示される時AAAAになってしまうように思うのですが
リストでAAを選択させるにはどうすればよいでしょう?
ちなみにコンボボックスのエディット部にはAAが表示されています。
よろしくお願いします。
OS:WinXP64bit
VC6
書かれている内容だけでは判断できないです。
SetCurSel等のコントロールのメンバー関数でコントロールしようとしていますが、
実際のコーディング上の処理をどのように組み立てているのかがわからないので。
コンボボックスコントロールに対してCComboBoxのインスタンスを結び付けているのか?
それともintとかを結び付けているのか?
もし、コントロールとintの変数を結び付けていて
それとは別に直接コンボボックスコントロールのポインタで操作しようとしているなら
両方の状態がぴったり合った状態で無いとうまく行かないような気がします。
intの変数には0が入っていて、でもSetCurSelで無理やり3を設定しているとしたら
二つの状態が食い違った状態になっていないでしょうか。
コンボボックスを弄った時にintの変数の方の内容が反映されて
インデックスが0に戻っているのかもしれません。
すべて想像で書いていますから当たっているかどうかは定かではありませんけれど。
ありがとうございます。
どこかでセットしてしまわないように
プログラムで操作するのを止めて
素のソートなしのコンボボックス(メンバとか無し)で
リストに以下のようにデータを入れただけの状態で
CCC
AAAA
BBDD
AA
BBBB
普通にマウス操作でリストからAAを選び
コンボボックスのエディット部にAAが表示され
リストの表示は一度消えますが
次にリストがドロップダウンした時
AAAAが選択されているのです。
本当ならAAが選択されているのではないでしょうか?
AAを選択するにはどうすればよいのでしょう?
デバッグで確認した所CBN_DROPDOWNまでは
GetCurSelで見るとAAになっているのですが・・・
まず、前提として
1.コンボボックス(ドロップダウン)では、選択されたアイテムのテキストが
表示欄(上部のEdit)に自動的に表示されます。
2.従って、SetWindowText()、又は相当のコードは無用のはずです。
3.SetWindowText()、又は相当のコードを行っても、選択されたアイテムの
番号は変化しません。
ですね。従って、ご質問の範囲の条件で常にアイテムの0番が選択されるという
症状がでる可能性があるとしたら、
4.コンボボックスのSetCursel()が呼ばれていない。
4.1 他のコントロールのSetCursel()と勘違いしている可能性。
4.2 対象コードが実行されていない可能性。
5.別のコードが、常にコンボのSetCursel( 0);又はSetCursel(無効値)
を実行している。
6.対象コードが無効
6.1 CComboboxのHWNDを設定していない(DDX)。
などが考えられます。
まず、まったく別のコードを用意してその中で
::SendMessage( コンボのHWND, CB_SETCURSEL, ( WPARAM)3, ( LPARAM)0);
を実行し、インデックス=3(4番目)のアイテムが選択されることを
確認してみましょう。
追加 orz.
5.別のコードが、常にコンボのSetCursel( 0);又はSetCursel(無効値)
を実行している。
についてですが、CBN_SELCHANGE をはじめとして、コンボボックスに応答
しているコードが実装されていたら注意深く見てみましょう。
当然ですがWM_COMMANDも対象になります。
仕様みたい。 VS2005 でも同等の動きをしているので。
ソートなし CComboBox に対してテキスト列
AAAA
BBDDAA
AA
BBDD
を与えたとき AA を一度選んでもう一度クリックすると AAAA が選択済み、
BBDD を選んでもう一度クリックすると BBDDAA が選択済み、となる。
ああ、たぶんこれだ。
CComboBox::FindString -> CB_FINDSTRING -> 「この文字列で始まるアイテムを探す」
が使われていて FindStringExact ぢゃないから、だと思う。
(それ以上追いかける時間は無いので以下略)
仲澤@失業者さん
tetrapodさん
ありがとうございます。
リソースエディタでダイアログのテストをするだけでも
同じ動作なのでプログラムは関係なかったみたいです。(^^;
>CComboBox::FindString -> CB_FINDSTRING -> 「この文字列で始まるアイテムを探す」
>が使われていて FindStringExact ぢゃないから、だと思う。
なるほど、この辺ですね。
この辺を何とかできれば理想の動作になりそうですね。
調べてみます。
やっと状況が理解できました。orz.
FindStringがメッセージ経由で呼ばれているなら、
CComboboxを継承したクラスで、LB_FINDSTRINGメッセージの処理を
オーバーライドすると何とかなるかもしれませんねぇ。
皆様ありがとうございました。
頂いた情報を自分なりに調べてみましたが
LB_FINDSTRINGメッセージのオーバーライドまでは至らず
現象に対応しただけで根本はそのままですが(汗
以下のソースでなんとか見た目は希望の動作に。
CComboBoxNSは自前コンボボックスクラスです。
void CComboBoxNS::OnLButtonUp(UINT nFlags, CPoint point)
{
ListSel();
CComboBox::OnLButtonUp(nFlags, point);
}
void CComboBoxNS::OnDropdown()
{
ListSel();
}
void CComboBoxNS::ListSel()
{
CString strEd,strList;
int max,pos;
if(GetDroppedState()==TRUE)
{
GetWindowText(strEd);
max=GetCount();
for(pos=0;pos<max;pos++)
{
GetLBText(pos,strList);
if(strEd == strList)
{
PostMessage(CB_SETCURSEL,pos);
break;
}
}
}
}