リストビューの文字列取得

ActiveBasicでのプログラミングでわからないこと、困ったことなどがあったら、ここで質問してみましょう(質問を行う場合は、過去ログやWeb上であらかじめ問題を整理するようにしましょう☆)。
メッセージ
作成者
M.S.
記事: 212
登録日時: 2005年6月01日(水) 21:51
お住まい: 奈良県北西部

リストビューの文字列取得

#1 投稿記事 by M.S. »

リストビューに表示されたアイテムの文字列を、
アイテムがダブルクリックされたときに、
"ListView_GetItemText()" を使って取得するにはどうすれば良いのでしょうか?

自分でやってみて成功しなかったコードです。 "Dim buf1~"から下が、
リストビューの「ダブルクリックされたとき」のイベント内に書いてあります。
僕ではこれが限界です。
どなたか教えて下さい。

他のやり方があるのならそちらの方もお願いします。
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

Re: リストビューの文字列取得

#2 投稿記事 by 7 »

> リストビューに表示されたアイテムの文字列を、
> アイテムがダブルクリックされたときに、
> "ListView_GetItemText()" を使って取得するにはどうすれば良いのでしょうか?
>
> 自分でやってみて成功しなかったコードです。
> > "Dim buf1~"から下が、
> リストビューの「ダブルクリックされたとき」のイベント内に書いてあります。
> 僕ではこれが限界です。
> どなたか教えて下さい。
>
> 他のやり方があるのならそちらの方もお願いします。
自分が書いたコードとどこが違うんだ同じだから動くはずなのに...、と思ったらListView_GetItemText関数の第一引数がhMainWndになっています。
メインウィンドウじゃなくてリストビューのウィンドウハンドルを指定するとうまく取得できるのではないでしょうか。
M.S.
記事: 212
登録日時: 2005年6月01日(水) 21:51
お住まい: 奈良県北西部

Re: リストビューの文字列取得

#3 投稿記事 by M.S. »

> 自分が書いたコードとどこが違うんだ同じだから動くはずなのに...、と思ったらListView_GetItemText関数の第一引数がhMainWndになっています。
> メインウィンドウじゃなくてリストビューのウィンドウハンドルを指定するとうまく取得できるのではないでしょうか。

おっしゃる通り、リストビューのハンドルを指定していなかった為に、
文字列を取得出来なかっただけでした。
しかし、これだとどのアイテムをダブルクリックしても、
一番上のアイテムの文字列しか取得できません。
二番目移行のアイテムの文字列を取得するにはどうすれば良いのでしょうか?
また、「コントロール内でマウスの左ボタンがダブルクリックされたとき」のイベントで合っているのでしょうか?
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

Re: リストビューの文字列取得

#4 投稿記事 by 7 »

> しかし、これだとどのアイテムをダブルクリックしても、
> 一番上のアイテムの文字列しか取得できません。
ListView_GetItemText関数の第二引数には文字列を取得したい行を 0 から始まる数値で指定します。
ですから、さっきのコードでは 0 を指定しているのでそれが普通の動作になります。

> 二番目移行のアイテムの文字列を取得するにはどうすれば良いのでしょうか?
二番目の行の文字列を取得したい場合、1 を指定します。
ただ、M.S.さんは選択されている項目の文字列を取得したいようなので、ここで指定する値は静的なものではなく、「リストビューの選択されている項目の値」という動的なものを指定します。
リストビューの選択されている項目の位置を取得するには LVM_GETNEXTITEM というメッセージをリストビューに送信します。 > また、「コントロール内でマウスの左ボタンがダブルクリックされたとき」のイベントで合っているのでしょうか?
ユーザーがどういったイベントを起こしたら処理を開始するか、という違いだけなので、「左ボタン」が「ダブルクリック」されたときだろうが「右ボタン」が「クリック」されたときだろうが、あまり大したことではありません。
合っているか合ってないかはM.S.さんが判断することです。

M.S.さんが、マウスの左ボタンでコントロール内をダブルクリックしたときに選択されている項目の文字列を取得したいと思っているのであれば、「コントロール内でマウスの左ボタンがダブルクリックされたとき」にしていて構いません。
マウスの右ボタンでコントロール内をクリックしたときに選択されている項目の文字列を取得したいのであれば合ってないんですけどね。
Mario2
記事: 205
登録日時: 2005年5月31日(火) 13:31
お住まい: 大阪市
連絡する:

Re: リストビューの文字列取得

#5 投稿記事 by Mario2 »

>「コントロール内でマウスの左ボタンがダブルクリックされたとき」のイベント
が"MainWnd_ListView1_DblClick"であれば、(hListにリストビューのハンドル(?)が入っているとします)
ListView_GetItemText(hList,0,0,buf1,MaxPath_LV)

ListView_GetItemText(hList,nmListView.iItem,0,buf1,MaxPath_LV)
とすれば取得できたと思います。
横の2列目以降は
ListView_GetItemText(hList,nmListView.iItem,nmListView.iSubItem,buf1,MaxPath_LV)
とすれば動きそうな感じがしますが、試していないので上手くいかないかもしれません。
M.S.
記事: 212
登録日時: 2005年6月01日(水) 21:51
お住まい: 奈良県北西部

Re: リストビューの文字列取得

#6 投稿記事 by M.S. »

返信が1ヶ月も遅れてしまって、申し訳ありません。

7 さんと、Mario2 さんのコードを両方試しましたが、思うようにできません…orz

一応試したコードを載せておきます。

コード: 全て選択

dim hList as HWND

Function ListView_GetNextItem(ByVal hWnd As HWND,ByVal iStart As Long,ByVal flags As DWord) As Long
    Return SendMessage(hWnd,LVM_GETNEXTITEM,iStart As WPARAM,flags As LPARAM) As Long
End Function

	hList=GetDlgItem(hMainWnd,ListView1) 'Createイベント内

Sub MainWnd_ListView1_DblClick(ByRef nmListView As NMLISTVIEW)
	dim buf1[MaxPath_LV] as Byte
	dim buf2[MaxPath_LV] as Byte
	dim buf[255] as Byte

	' 選択されている項目の位置を持つ
	Dim nSelect As Long

	' 項目が選択されていない場合、-1が返ります
	nSelect=ListView_GetNextItem(GetDlgItem(hMainWnd,ListView1),-1,LVNI_ALL Or LVNI_SELECTED)

	if nSelect<>-1 then
		ListView_GetItemText(hList,0,0,buf1,MaxPath_LV)
		ListView_GetItemText(hList,0,1,buf2,MaxPath_LV)
	Elseif nSelect=-1 then
		ListView_GetItemText(hList,lvItem.iItem,0,buf1,MaxPath_LV)
		ListView_GetItemText(hList,lvItem.iItem,1,buf2,MaxPath_LV)
	End If

	wsprintf(buf,"%s%s",buf2,buf1)
	MessageBox(hMainWnd,buf,0,MB_OK)
End Sub
もう僕はお手上げです…
trio

#7 投稿記事 by trio »

サンプルを挙げます
これを改造すればMS様が望まれている動作も可能だと思われますがどうでしょうか
呼び出しがボタンからになっているのは
リストビューでダブルクリックしていたら選択が反転してしまって面倒だったためです
Mario2
記事: 205
登録日時: 2005年5月31日(火) 13:31
お住まい: 大阪市
連絡する:

Re: リストビューの文字列取得

#8 投稿記事 by Mario2 »

何か違ってるような感じがして、修正を加えてみました。こちらで試してみてはどうでしょう。これでも動かなかったらすいません。
trio

#9 投稿記事 by trio »

違ってますね
アイテムとサブアイテムの文字列の取得でしたか

失礼しました
ゲスト

#10 投稿記事 by ゲスト »

少しMS様にお聞きしたいことが

このコードって選択項目があればその項目のアイテムとサブアイテムを表示して
選択項目がなければインデックス0のアイテムとサブアイテムを表示するって事でしょうか?

それとも選択項目があればインデックス0のアイテムとサブアイテムを表示して
選択項目がなければカーソル位置のアイテムとサブアイテムを表示するって事でしょうか?
trio

#11 投稿記事 by trio »

元のコードを見ていて気づいたことが一つ

NMLISTVIEW構造体のiSubItemメンバは常にマウスカーソルがある位置のサブアイテムインデックスを格納しているんですが
iItemメンバはアイテムの選択可能範囲(選択した時に青くなる所)外だと-1が格納されています

この辺は大丈夫でしょうか
M.S.
記事: 212
登録日時: 2005年6月01日(水) 21:51
お住まい: 奈良県北西部

#12 投稿記事 by M.S. »

一ヶ月も放置してしまって申し訳ありません!m(__)m
> 少しMS様にお聞きしたいことが
>
> このコードって選択項目があればその項目のアイテムとサブアイテムを表示して
> 選択項目がなければインデックス0のアイテムとサブアイテムを表示するって事でしょうか?
>
> それとも選択項目があればインデックス0のアイテムとサブアイテムを表示して
> 選択項目がなければカーソル位置のアイテムとサブアイテムを表示するって事でしょうか?
聞かれてる内容がよくわからないのですが、
兎に角ダブルクリックしたときにカーソル位置のアイテムとサブアイテムを取得したいのです。
> 元のコードを見ていて気づいたことが一つ
>
> NMLISTVIEW構造体のiSubItemメンバは常にマウスカーソルがある位置のサブアイテムインデックスを格納しているんですが
> iItemメンバはアイテムの選択可能範囲(選択した時に青くなる所)外だと-1が格納されています
>
> この辺は大丈夫でしょうか
いえ、大丈夫じゃありません…
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

Re: リストビューの文字列取得

#13 投稿記事 by 7 »

> 一応試したコードを載せておきます。
>
>

コード: 全て選択

dim hList as HWND
> 
> Function ListView_GetNextItem(ByVal hWnd As HWND,ByVal iStart As Long,ByVal flags As DWord) As Long
>     Return SendMessage(hWnd,LVM_GETNEXTITEM,iStart As WPARAM,flags As LPARAM) As Long
> End Function
> 
> 	hList=GetDlgItem(hMainWnd,ListView1) 'Createイベント内
> 
> Sub MainWnd_ListView1_DblClick(ByRef nmListView As NMLISTVIEW)
> 	dim buf1[MaxPath_LV] as Byte
> 	dim buf2[MaxPath_LV] as Byte
> 	dim buf[255] as Byte
> 
> 	' 選択されている項目の位置を持つ
> 	Dim nSelect As Long
> 
> 	' 項目が選択されていない場合、-1が返ります
> 	nSelect=ListView_GetNextItem(GetDlgItem(hMainWnd,ListView1),-1,LVNI_ALL Or LVNI_SELECTED)
> 
> 	if nSelect<>-1 then
> 		ListView_GetItemText(hList,0,0,buf1,MaxPath_LV)
> 		ListView_GetItemText(hList,0,1,buf2,MaxPath_LV)
> 	Elseif nSelect=-1 then
> 		ListView_GetItemText(hList,lvItem.iItem,0,buf1,MaxPath_LV)
> 		ListView_GetItemText(hList,lvItem.iItem,1,buf2,MaxPath_LV)
> 	End If
> 
> 	wsprintf(buf,"%s%s",buf2,buf1)
> 	MessageBox(hMainWnd,buf,0,MB_OK)
> End Sub
項目が選択されているなら 0 の項目を取得、項目が選択されていないなら選択されている項目を取得になってます...。
If文が逆なんではないかと思います。
※lvItem.iItem に値が格納されていないのでインデックスは必ず 0 になります

項目が選択されていない場合、メッセージボックスで注意するだけにしました。勝手に。 単純に選択されている項目のデータを取得したいなら選択されている項目のインデックスをListView_GetItemText関数の第二引数に指定します。

LVITEM構造体の iItem メンバを指定したい場合、iItem にインデックスを格納してからでないといけません。 戻り値の意味や扱い方、指定すべきデータなど覚えるのに苦労しますよねぇ...。
yata

初心者の質問ですが

#14 投稿記事 by yata »

大分前に7さんから頂いたこのコードでファイルを開くプログラムを作ったのですが、
Function内のReturnを取って使っていますが、取ってはいけませんか?
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

Re: 初心者の質問ですが

#15 投稿記事 by 7 »

> 大分前に7さんから頂いたこのコードでファイルを開くプログラムを作ったのですが、
> Function内のReturnを取って使っていますが、取ってはいけませんか?
「このコード」とはListView_GetNextItem関数のことでしょうか?

コード: 全て選択

Function ListView_GetNextItem(ByVal hWnd As HWND,ByVal iStart As Long,ByVal flags As DWord) As Long
    Return SendMessage(hWnd,LVM_GETNEXTITEM,iStart As WPARAM,flags As LPARAM) As Long
End Function
この関数は特定の項目のインデックス値を返す関数なので戻り値に代入しなければ使い物になりません。
だからReturnを取って使っては意味がないです...。

Returnが使えない環境なら以下のように修正してください。

コード: 全て選択

Function ListView_GetNextItem(ByVal hWnd As HWND,ByVal iStart As Long,ByVal flags As DWord) As Long
    ListView_GetNextItem=SendMessage(hWnd,LVM_GETNEXTITEM,iStart As WPARAM,flags As LPARAM) As Long
End Function
返信する