コンボボックスの変化に伴うリストボックス

ActiveBasicでのプログラミングでわからないこと、困ったことなどがあったら、ここで質問してみましょう(質問を行う場合は、過去ログやWeb上であらかじめ問題を整理するようにしましょう☆)。
返信する
メッセージ
作成者
雷電

コンボボックスの変化に伴うリストボックス

#1 投稿記事 by 雷電 »

題の通りです
コンボボックスが"test"の場合、リストボックスには"test"と表示し、
コンボボックスの内容が"test2"だった場合、リストボックスには"Error"と。

こういう風に表示を変えることで苦戦しています。
だれか教えていただけないでしょうか?
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

Re: コンボボックスの変化に伴うリストボックス

#2 投稿記事 by 7 »

雷電さん さんが書きました:コンボボックスが"test"の場合、リストボックスには"test"と表示し、
コンボボックスの内容が"test2"だった場合、リストボックスには"Error"と。
たしか前にlstrcmp()関数について書いたと思うんですけど、覚えてますか?
文字列同士を大文字/小文字の区別をして比較する関数なんですけど。
自分ならlstrcmp()関数で実装してしまいます。

随分と遠回りな提案ですけど、まず、日本語をコードに直すことを意識してはどうでしょう?

「コンボボックスに入力されている文字列が "test" だった場合」という文章をコードに直すとします。

コンボボックス = GetDlgItem(hMainWnd,ComboBox1)
入力されている文字列 = GetWindowText(コンボボックス,lpStr,length) ' 適当
"test"であるかどうか = If lstrcmp("test",lpStr)=0 Then
"test"だった場合 = SendMessage(リストボックス,LB_ADDSTRING,0,"test" As LPARAM)
※あぁ...分かりにくい表現かも...

といったような感じになると思います。

文字列を比較するにはlstrcmp, lstrcmpi, CompareStringなどがあります。
リストボックスに文字列を設定したいなら、LB_RESETCONTENTで項目をサクりファイスしてから、LB_ADDSTRINGで項目を追加してやることで可能です。

あ。リストボックスって、もしかしてコンボボックスの中にあるリストボックス(?)のことですか?
雷電

#3 投稿記事 by 雷電 »

lstrcmp()関数で実装可能だったんですね。
>あ。リストボックスって、もしかしてコンボボックスの中にあるリストボックス(?)のことですか?
いえいえ、そうではありませんよ。
同じウィンドウの中にあるだけです。
ただ比べるのはいいのですが、コンボボックスの選択されている内容が変わったとき、つまりはそのイベントコーディングの仕方がわからないんです。
前の場合ではコマンドボタンとか押されたときのイベントでしたが、今回は選択が変わったときです。

説明が悪かったようです。

7さん、変わったときに変更する(ifで分岐する)コードはもうすでにできています。
説明が悪いですね、私は・・・
淡幻星
記事: 183
登録日時: 2005年7月19日(火) 07:02
お住まい: 宮城県
連絡する:

#4 投稿記事 by 淡幻星 »

横槍失礼します。
> コンボボックスの選択されている内容が変わったとき、つまりはそのイベントコーディングの仕方がわからないんです。
それくらいはヘルプに載っているだろう、と思いましたが載ってませんね(汗)。
RADのイベントにも無し・・・。過去ログもすぐにはヒットせず。あれれ?

えっと。
コンボボックスの選択内容が変わったときにはメッセージ
CBN_SELCHANGE
がMainWndProc()に送られます。
あとはGetWindowText()なりなんなりで、煮るなり焼くなり好きにしてくださいw

以下、参考までに。
※リストボックスもエディットボックスも、それぞれ「コンボボックスの~」って意味です。
WisdomSoft様より転載 さんが書きました:CBN_CLOSEUP リストボックスが閉じられた
CBN_DBLCLK リストボックスの項目をダブルクリック
CBN_DROPDOWN リストボックスが表示されようとしている
CBN_EDITCHANGE エディットでテキストが変更された可能性がある
CBN_EDITUPDATE エディットのテキストが変更され
エディットを表示しようとしている
CBN_ERRSPACE 十分なメモリを割り当てられない
CBN_KILLFOCUS キーボードフォーカスを失った
CBN_SELCHANGE リストボックスの選択の変更
CBN_SELENDCANCEL アイテムを選択したが、その時に他のコントロールを選択
または、ダイアログボックスを閉じた
CBN_SELENDOK アイテムを選択し、リストを閉じる
CBN_SETFOCUS キーボードフォーカスを得た
雷電

#5 投稿記事 by 雷電 »

淡幻星さんの言うとおりにやってみましたが、うまくいきません。

コードを一応載せておきます。
Createとさっき言われていたCBN_SELCHANGEのメッセージです。

コード: 全て選択

Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
	Dim Combo As HWND
	Combo=GetDlgItem(hMainWnd,ComboBox1)

	SendMessage(Combo,CB_ADDSTRING,0,"test")
	SendMessage(Combo,CB_ADDSTRING,0,"test1")
	SendMessage(Combo,CB_ADDSTRING,0,"test2")
	SendMessage(Combo,CB_ADDSTRING,0,"test3")
End Sub

Sub MainWnd_CBN_SELCHANGE()
	Dim Combo1 As String
	Dim List As HWND

	GetDlgItem(hMainWnd,ListBox1)
	GetDlgItemTextStr(hMainWnd,ComboBox1,Combo1)

	If lstrcmp("test",Combo1)= Then
		SendMessage(List,LB_RESETCONTENT,0,0)
		SendMessage(List,LB_ADDSTRING,0,"test")
	ElseIf lstrcmp("test1",Combo1) Then
		SendMessage(List,LB_RESETCONTENT,0,0)
		SendMessage(List,LB_ADDSTRING,0,"test1")
	ElseIf lstrcmp("test2",Combo1) Then
		SendMessage(List,LB_RESETCONTENT,0,0)
		SendMessage(List,LB_ADDSTRING,0,"test2")
	ElseIf lstrcmp("test3",Combo1) Then
		SendMessage(List,LB_RESETCONTENT,0,0)
		SendMessage(List,LB_ADDSTRING,0,"test3")
	Else
		SendMessage(List,LB_RESETCONTENT,0,0)
		SendMessage(List,LB_ADDSTRING,0,"error")
	End If
End Sub
何か間違っているのでしょうか?
淡幻星
記事: 183
登録日時: 2005年7月19日(火) 07:02
お住まい: 宮城県
連絡する:

#6 投稿記事 by 淡幻星 »

うまくいきません。
コンボボックスの選択の変更が検出できていない、と言う意味でよろしいのでしょうか?


その場合、念のため確認しますが、 はどうなっておりますでしょうか? もしなってない場合は、「追加が~」の部分を追記してください。
(すみませんが、今回は理由と説明は省かせていただきます)


それから、Sub MainWnd_CBN_SELCHANGE()の中の

コード: 全て選択

GetDlgItem(hMainWnd,ListBox1)
は、

コード: 全て選択

List = GetDlgItem(hMainWnd,ListBox1)
のタイプミスですよね?
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

#7 投稿記事 by 7 »

雷電さん さんが書きました:何か間違っているのでしょうか?
選択されている項目が変わった時(CBN_SELCHANGEですね)、コンボボックスにCB_GETLBTEXTを送信して選択されている項目の文字列を取得すればいいのではないでしょうか。
GetWindowText()関数で取得できる文字列はコンボボックスのエディットコントロールに入力されている文字列なので...。
雷電

#8 投稿記事 by 雷電 »

GetWindowText()関数ではできないみたいですが、実践コードモジュールの方にあったイグトランスさんが作っていたファンクションを使えば文字列取得可能です。やってみてください。

何回やってもできません。コンボボックスの選択が変わってもリストボックスには指定した文字列は挿入されません。
コード自体が間違っている(?)のでしょうか。
自分では見た限りあっていると思うのですが・・・
もう一度やってみます。
淡幻星
記事: 183
登録日時: 2005年7月19日(火) 07:02
お住まい: 宮城県
連絡する:

#9 投稿記事 by 淡幻星 »

≫雷電さん
すいません。質問の意味が分かりません・・・m(_ _)m

しかし、どうも私が思いっきり勘違いしていた可能性が出てきたので(汗)。
えっと、
CBN_SELCHANGE を全部 CBN_EDITCHANGE って書き換えてみてください。
これで上手くいったとしたら、大変申し訳ないですm(_ _)m

それでもだめな場合は、一つ一つ確認していきましょう。
闇雲にデバック実行を繰り返しても意味は無いです。

1、コンボボックスの選択が変化したことは検出できていますか?

2、リストボックスへSendMessageで文字列を挿入する際、
  返り値はどうなっていますか?成功していますか?

この2点を順に調べてください。



≫7さん
コンボボックスで、
リストボックス内のアイテムを選択すれば、
エディットボックスにそのアイテムがセットされるので、
GetWindowText()でも問題ないのではないでしょうか?

・・・これが私が勘違いしていたっぽい場所でして。
雷電さんの求めているものは
選択が決定された状態の検出であって、
選択中の変更(決定前)の検出ではないように思いました。
だとすると、私が混乱を助長してしまったことになりますね_| ̄|○
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

#10 投稿記事 by 7 »

雷電さん さんが書きました:GetWindowText()関数ではできないみたいですが、実践コードモジュールの方にあったイグトランスさんが作っていたファンクションを使えば文字列取得可能です。やってみてください。
別にGetWindowText()関数でもできるんですけど、たしか取得できない時があったんですよ。
こうなってると取得できないっていう条件は忘れてしまったんですけど...。
CB_GETCURSELの戻り値がCB_ERRじゃない場合、CB_GETLBTEXTで項目の文字列を取得、戻り値がCB_ERRだった場合、GetWindowText()関数で取得していたんです。
淡幻星さん さんが書きました:コンボボックスで、
リストボックス内のアイテムを選択すれば、
エディットボックスにそのアイテムがセットされるので、
GetWindowText()でも問題ないのではないでしょうか?
ちょっと取得できない条件ってのを探しました...。
淡幻星
記事: 183
登録日時: 2005年7月19日(火) 07:02
お住まい: 宮城県
連絡する:

#11 投稿記事 by 淡幻星 »

7さん さんが書きました:> ちょっと取得できない条件ってのを探しました...。
なるほど。確かに。
というか、ここも勘違いでした私の(爆)。
なぜか途中で「セル変更時→エディット変更時」って読み替えてました。
大変失礼いたしましたm(_ _)m


なお、ゼロフリーはしちゃいけませんよ~。
(正確にはABのfreeは内部でHeapFreeかGlobalFreeを呼んでいた筈なので、
 そいつがNULLポインタを放り込むとアクセス違反を返します。・・・たしか。)
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

#12 投稿記事 by 7 »

> なお、ゼロフリーはしちゃいけませんよ~。
> (正確にはABのfreeは内部でHeapFreeかGlobalFreeを呼んでいた筈なので、
>  そいつがNULLポインタを放り込むとアクセス違反を返します。・・・たしか。)
やっぱりダメなんですね...覚えておきます。
今回のゼロフリーみたいに「よく分からない」っていう状況がよく有るんですよねぇ...。
雷電

#13 投稿記事 by 雷電 »

できました。
なんとか・・・
淡幻星さん、7さん、ありがとうございました。
返信する