|
|
2015/1/1(Thu) 19:27:26|NO.66784
|
|
2015/1/1(Thu) 21:36:45|NO.66792
catsさんありがとうございます。
これは私の予想なのですが、、、
欄が選択されたら、input命令等で一時的に入力ボックスをリストビューの欄の上に作成、
フォーカスが外れたら入力ボックスを削除、という仕組みなのでしょうか?
英語が苦手な者で、catsさんに頼ってばかりで申し訳ないです。
|
|
2015/1/1(Thu) 21:56:25|NO.66793
mod=0
onclick gosub *click
onkey gosub *key
pos 0,0 :mes "この画面をクリックして、テキストを追加してください。"
stop
//----クリックの場
*click
if mod=0{
mod=1
sdim moz
posx=mousex
posy=mousey
pos posx,posy :input moz,120,20 :ID_ipt=stat
objsel ID_ipt
return
}
if mod=1{
if mousex<posx | mousey<posy | mousex>posx+120 | mousey>posy+20{ ;違う場所が選択されたら
pos posx,posy :mes moz
clrobj ID_ipt,ID_ipt
mod=0
return
}
}
return
//----キーの場合
*key
if mod=0{
mod=1
sdim moz
posx=mousex
posy=mousey
pos posx,posy :input moz,120,20 :ID_ipt=stat
objsel ID_ipt
return
}
if mod=1{
if wparam=13{
pos posx,posy :mes moz
clrobj ID_ipt,ID_ipt
mod=0
return
}
}
return
私が思っているイメージはこんな感じです。
|
|
2015/1/1(Thu) 22:15:26|NO.66795
はい、リストビューの上にインプットボックスを作成しています。
ただし、アイテムの位置、カラムの幅やフォントサイズなどに合わせて入力ボックスを作成する必要があります。
カラムの幅と行のサイズはSendMessageで取得できます。
ただ、マウスカーソル上にあるアイテムを取得できるかという問題があります。
GetWindowRect等で計算するのも考えましたが、リストビューなので上下左右にスクロールする可能性もあります。
リンク先がC++と慣れない言語なので読むのに時間がかかります。
イメージとしては a さんの考えているもので合っていますが、問題はそれをどう実装するかですね。
|
|
2015/1/2(Fri) 09:29:07|NO.66798
少しばかり結果報告です。
現在、マウス下にあるアイテムは取得できていませんが、
リストビューの上の欄の部分だけにオブジェクトを配置できました。
#include "gdi32.as"
#include "llmod3/llmod3.hsp"
#include "llmod3/listview.hsp"
#include "llmod3/img.hsp"
//----マクロ
#const WM_NOTIFY 0x004E ;メッセージ用
#const LVS_EDITLABELS 0x0200 ;編集を可能にする(値を調べるのにかなり苦労した。)
#const LVN_BEGINLABELEDIT $FFFFFF97 ;メッセージ用
//----
#uselib "user32.dll"
#func CreateWindowExA "CreateWindowExA" int, sptr, sptr, int, int, int, int, int, int, int, int, int
#cfunc CreateWindowExW "CreateWindowExW" int, wptr, wptr, int, int, int, int, int, int, int, int, int
#const LVM_GETHEADER $0000101F
#const HDM_GETITEMCOUNT $00001200
//----リストビューの幅を変更するためのもの
#const HDN_FIRST -300
#const HDN_DIVIDERDBLCLICKW -300 ;ダブルクリック取得
#const HDN_ITEMCLICK -302
#const HDN_DIVIDERDBLCLICK -305
#const HDN_BEGINTRACK -306
#const HDN_ENDTRACK -307
#const HDN_TRACK -308
#const HDN_GETDISPINFO -309
#const HDN_BEGINDRAG -310
#const HDN_ENDDRAG -311
oncmd gosub *NOTIFY,WM_NOTIFY ;割り込み
//----リストビュー作成
pos 100,100
listview 400,200,$310009 | LVS_EDITLABELS
id=stat :hwd=objinfo_hwnd(id)
listaddcl 0,"test1",100,2
listaddcl 1,"test2",100
listaddcl 2,"test3",100
repeat 5
listadd 0,"あいうえお",0
listadd 1,"かきくけこ",0
listadd 0,"さしすせそ",1
listadd 1,"たちつてと",1
listadd 0,"なにぬねの",2
listadd 1,"はひふへほ",2
loop
//----インプットボックス?
sendmsg hwd,LVM_GETHEADER,0,0
_hwnd=stat
CreateWindowExA 1,"Edit","コメント",$50000000,300,0,60,22,_hwnd
hwd2=stat
GetStockObject 17
sendmsg hwd2, $30, stat
stop
//----WM_NOTIFYメッセージ
*NOTIFY
dupptr nmhdr,lparam,12 ; NMHDR 構造体の割り当て
;if nmhdr.0!=hwd :return
//----編適用
if nmhdr.2=-106{
dupptr a,lparam,64
sendmsg hwd,0x1006/*LVM_SETITEMA*/,0,varptr(a)+12
}
//----編集開始時に呼び出される
if LVN_BEGINLABELEDIT=nmhdr.2 {
dupptr nmhdr,lparam,64
}
//----幅の変更を無効化
switch nmhdr.2
case HDN_BEGINTRACK
case HDN_TRACK
case HDN_ITEMCLICK
case HDN_DIVIDERDBLCLICKW
;dupptr nmhdr,lparam,20 ;構造体割り当て nmhdr.3=選択されているカラムNo
return -1 ;無視する
swbreak
swend
return 0
更に応用して、リストの部分にもインプットボックスを配置。みたいな事が出来そうな感じがします。
しかしいくらオブジェクトを配置できたとしても、選択されている項目が見つからなければ意味無いですね。
もう少し勉強してみます。

| |
|
2015/1/2(Fri) 21:22:58|NO.66814
マウス下にあるセル(アイテム)を取得するには、sendmsg でリストビューに LVM_SUBITEMHITTEST を送ってあげれば良いそうです。
指定した座標がリストビューのどのセル内にいるかが帰ってきます。
参考にしたページ
http://wtpage.info/program/section012.html
以下は、リストビューがダブルクリックされたとき、どのセルが選択されたかを取得するサンプルです。
(前の質問の「編集可能なリストビュー」からスクリプトを引用させて頂きました。)
#include "llmod3/llmod3.hsp"
#include "llmod3/listview.hsp"
#include "llmod3/img.hsp"
// 追加
#uselib "user32.dll"
#func global GetCursorPos "GetCursorPos" sptr
#func global ScreenToClient "ScreenToClient" sptr,sptr
//----マクロ
#const WM_NOTIFY 0x004E ;メッセージ用
#const LVS_EDITLABELS 0x0200 ;編集を可能にする(値を調べるのにかなり苦労した。)
oncmd gosub *NOTIFY,WM_NOTIFY ;割り込み
// 追加
#define ListView_SubItemHitTest(%1,%2) sendmsg %1,0x1039/*LVM_SUBITEMHITTEST*/,0,varptr(%2)
//----リストビュー作成
listview 400,200,$110009 | LVS_EDITLABELS
id=stat :hwd=objinfo_hwnd(id)
listaddcl 0,"test1",100,2
listaddcl 1,"test2",100
listaddcl 2,"test3",500 // 変更
listadd 0,"あいうえお",0
listadd 1,"かきくけこ",0
listadd 0,"さしすせそ",1
listadd 1,"たちつてと",1
listadd 0,"なにぬねの",2
listadd 1,"はひふへほ",2
// 追加
mes "セルをダブルクリック!"
stop
//----WM_NOTIFYメッセージ
*NOTIFY
dupptr nmhdr,lparam,12 ; NMHDR 構造体の割り当て
if nmhdr.0!=hwd :return
if nmhdr.2=-106{
dupptr a,lparam,64
sendmsg hwd,0x1006/*LVM_SETITEMA*/,0,varptr(a)+12
dialog a
}
// 追加
if nmhdr.2=-3/*NM_DBLCLK*/ {
dim pt,2
GetCursorPos varptr(pt) // ← カーソルの位置を取得
gcp=pt(0),pt(1)
ScreenToClient hwd, varptr(pt) // ← カーソル位置をリストビューの座標位置に変換
stc=pt(0),pt(1)
dim lvHitInfo,6
lvHitInfo(0)=pt(0),pt(1)
ListView_SubItemHitTest hwd, lvHitInfo // ← リストビューの座標位置が、どのセル内のものかを取得(マクロ)
dialog strf("GetCursorPos(%d,%d), ScreenToClient(%d,%d)\n\n → ListViewCell(%d,%d)", gcp(0), gcp(1), stc(0), stc(1), lvHitInfo(3), lvHitInfo(4) )
}
return 0
試してみた限りですと、スクロールバーがある場合はスクロール量を加味してどのセル内にいるかを返してくれるみたいです。

| |
|
2015/1/2(Fri) 21:35:33|NO.66815
>MIZUSHIKI さん
スレ主ではないですが、こんな定数があったとは驚きました。
これを使えば比較的簡単に作れますね。
|
|
2015/1/3(Sat) 20:34:48|NO.66845
>>MIZUSHIKIさん
ありがとうございます!
私もcatsさんと同じく、ListView_SubItemHitTestを使って簡単に出来ることに驚きました。
あとはリスト内に入力ボックスを設置する事が問題になってきますね。
あと、リストビューのスタイルのLVS_EDITLABELSを消してしまうと、編集が開始された通知「LVN_BEGINLABELEDIT」が
取得できなくなってしまうので、デフォルトで作成される入力ボックスを削除する事も問題ですね。
出来そうな気がしますが、少し調べてみます。
|
|
2015/1/4(Sun) 00:36:58|NO.66850
/*横槍(表計算ソフトのようなセルの表示方法?)
ttp://fs-cgi-basic01.freespace.jp/~hsp/ver3/hsp3.cgi?print+200610/06100013.txt
用途によっては良いかも知れません。*/
|
|
2015/1/4(Sun) 13:23:54|NO.66860
>>fortunehillさん
自分で全部作っちゃうみたいな感じですね。
もし、リストビューを自作するとして、Yoshiさんも仰っているように、マス目の所はどうやって作っているんでしょうかね。
|
|
2015/1/4(Sun) 13:36:57|NO.66861
リストビューのサブアイテムの編集ですが、もう少し考えてみることにしました。
#include "llmod3/llmod3.hsp"
#include "llmod3/listview.hsp"
#include "llmod3/img.hsp"
#uselib "user32.dll"
#func global GetCursorPos "GetCursorPos" sptr
#func global ScreenToClient "ScreenToClient" sptr,sptr
#func CreateWindowExA "CreateWindowExA" int, sptr, sptr, int, int, int, int, int, int, int, int, int
#cfunc CreateWindowExW "CreateWindowExW" int, wptr, wptr, int, int, int, int, int, int, int, int, int
#func GetWindowText "GetWindowTextA" int,int,int
#func MoveWindow "MoveWindow" int,int,int,int,int,int ;位置の変更
#uselib "gdi32.dll"
#func DeleteObject "DeleteObject" int ;オブジェクト削除
#func GetStockObject "GetStockObject" int ;オブジェクト削除
//----マクロ
#const WM_NOTIFY 0x004E ;メッセージ用
#const LVS_EDITLABELS 0x0200 ;編集を可能にする(値を調べるのにかなり苦労した。)
oncmd gosub *NOTIFY,WM_NOTIFY ;割り込み
#define ListView_SubItemHitTest(%1,%2) sendmsg %1,0x1039/*LVM_SUBITEMHITTEST*/,0,varptr(%2)
#const LVN_BEGINLABELEDIT $FFFFFF97 ;編集が開始された ;追加
#const LVM_GETEDITCONTROL 0x1018
#const LVM_GETHEADER $0000101F ;カラム部分のハンドル取得用
#const HDM_GETITEMCOUNT $00001200
#define LVM_GETITEMA 4101 ;項目テキスト取得用
#define LVM_SETITEMA 4102 ;項目テキスト再設定用
//----リストビュー作成
listview 400,200,$310009 | LVS_EDITLABELS
id=stat :hwd=objinfo_hwnd(id)
listaddcl 0,"test1",100,2
listaddcl 1,"test2",100
listaddcl 2,"test3",100 // 変更
repeat 10
listadd 0,"あいうえお",0
listadd 1,"かきくけこ",0
listadd 0,"さしすせそ",1
listadd 1,"たちつてと",1
listadd 0,"なにぬねの",2
listadd 1,"はひふへほ",2
loop
stop
//----WM_NOTIFYメッセージ
*NOTIFY
dupptr nmhdr,lparam,12 ; NMHDR 構造体の割り当て
if nmhdr.0!=hwd :return
if nmhdr.2=-106{
//----テキストの取得
mod=0 ;モード変更
sdim text
GetWindowText HWND_input,varptr(text),64
;dialog text
//----テキストを設定
dim lvi,9
lvi=1,lvHitInfo(3),lvHitInfo(4),0,0,varptr(text),64
lvi = 1
sendmsg hwd,LVM_GETITEMA+1,0,varptr(lvi)
;dupptr a,lparam,64
;sendmsg hwd,0x1006/*LVM_SETITEMA*/,0,varptr(a)+12
}
//----編集が開始された
if nmhdr.2=LVN_BEGINLABELEDIT{
//入力ボックスのハンドルを取得
sendmsg nmhdr.0 , LVM_GETEDITCONTROL , 0,0 ;入力ボックスのハンドルを取得
HWND_input=stat
//
dim pt,2
GetCursorPos varptr(pt) // ← カーソルの位置を取得
gcp=pt(0),pt(1)
ScreenToClient hwd, varptr(pt) // ← カーソル位置をリストビューの座標位置に変換
stc=pt(0),pt(1)
dim lvHitInfo,6
lvHitInfo(0)=pt(0),pt(1)
ListView_SubItemHitTest hwd, lvHitInfo // ← リストビューの座標位置が、どのセル内のものかを取得(マクロ)
;dialog strf("GetCursorPos(%d,%d), ScreenToClient(%d,%d)\n\n → ListViewCell(%d,%d)", gcp(0), gcp(1), stc(0), stc(1), lvHitInfo(3), lvHitInfo(4) )
//----取得したアイテムのテキストを取得
sdim text
dim lvi,9
lvi=5,lvHitInfo(3),lvHitInfo(4),0,0,varptr(text),64
sendmsg hwd,LVM_GETITEMA,0,varptr(lvi)
;dialog text
mod=2 ;編集モード
return
}
if mod{ ;編集モード直前の処理(LVN_BEGINLABELEDIT処理直前だと、入力ボックスが作成されて無いので、作成された後に実行)
if mod=2{ ;作成直前一回だけ実行
sendmsg HWND_input,0x000C,64,varptr(text) ;入力ボックスの内容を変更
mod=1
}
MoveWindow HWND_input,lvHitInfo.0,lvHitInfo.1,60,20,1 ;入力されるとオブジェクトが移動されるので、固定する。
}
return 0
サブアイテムをクリックし、編集させることは出来るようになったのですが、後もう一歩のところで躓いています。
入力ボックスの位置とサイズは変更できるようになったのですが、
入力ボックスをアイテムのサイズに合わせる事と、編集中の時に左のアイテムのテキストが消えてしまう事で困っています。

| |
|
2015/1/4(Sun) 20:00:03|NO.66872
>入力ボックスをアイテムのサイズに合わせる
LVM_GETSUBITEMRECTでいけないですか?
>編集中の時に左のアイテムのテキストが消えてしまう事で困っています。
LVS_EDITLABELSに頼らずに自分でinputを処理するようにすればいいのでは。
クリックされたアイテムが既にフォーカス状態なら編集モードに入り、
エンターを押すかinputからフォーカスが外れたときに編集モードを終了という風に。
LVN_ITEMCHANGING内でLVM_GETNEXTITEMを使えばクリック直前のフォーカスの状態がわかるんじゃないかと思います。
|
|
2015/1/5(Mon) 13:46:47|NO.66882
>>LVS_EDITLABELSに頼らずに自分でinputを処理するようにすればいいのでは。
すみません言い忘れていました。
リストビューの項目画面のウィンドウハンドルが分からなかったもので、
前回の回答のようにエディットボックスのハンドルを取得して色々やってました。
YTTさんが仰っている事が、リストビューの項目画面のウィンドウハンドルが
既に分かっているものだとすれば、どうやってリストビューの項目画面のウィンドウハンドル
を取得するのでしょうか?
私の言っている事がおかしかったら申し訳ないです。
|
|
2015/1/5(Mon) 16:07:00|NO.66884
YTT氏を参考に
案①
#include "llmod3/llmod3.hsp"
#include "llmod3/listview.hsp"
#include "llmod3/img.hsp"
#uselib "user32"
#func MoveWindow "MoveWindow" int,int,int,int,int
#func SetWindowText "SetWindowTextA" int,prefstr
listview 400,200,$210201
hList=objinfo_hwnd(stat)
listaddcl 0,"test1",100,2
listaddcl 1,"test2",100
listaddcl 2,"test3",100
repeat 10
listadd 0,"あいうえお",0
listadd 1,"かきくけこ",0
listadd 0,"さしすせそ",1
listadd 1,"たちつてと",1
listadd 0,"なにぬねの",2
listadd 1,"はひふへほ",2
loop
mref text,65
LVITE=1,0,0,0,0,varptr(text),1024
oncmd gosub *WM_NOTIFY,$4e
stop
;-------------------------------------------------------------------------------
*WM_NOTIFY
dupptr code,lparam,112
if code=hList {
if code(2)=-121 {;LVN_HOTTRACK
rect=2,code(4),0,0
return
}
if code(2)=-105 {;LVN_BEGINLABELEDIT
LVITE(2)=rect(1)
sendmsg hList,4141,code(4),varptr(LVITE)
sendmsg hList,(rect(1)>0)*42+4110,code(4),varptr(rect)
sendmsg hList,4120
hEdit=stat
SetWindowText hEdit
return
}
if code(2)=-106 {;LVN_ENDLABELEDIT
code(5)=LVITE(2)
sendmsg hList,4102,,varptr(code(3))
hEdit=0
return
}
if hEdit {
MoveWindow hEdit,rect,rect(1),rect(2)-rect,rect(3)-rect(1)
}
}
return
案② ※ダブルクリックで編集
#include "llmod3/llmod3.hsp"
#include "llmod3/listview.hsp"
#include "llmod3/img.hsp"
#uselib "user32"
#func MoveWindow "MoveWindow" int,int,int,int,int
#func SetWindowLong "SetWindowLongA" int,int,int
#func ShowWindow "ShowWindow" int,int
listview 400,200,$210001
hList=objinfo_hwnd(stat)
listaddcl 0,"test1",100,2
listaddcl 1,"test2",100
listaddcl 2,"test3",100
repeat 10
listadd 0,"あいうえお",0
listadd 1,"かきくけこ",0
listadd 0,"さしすせそ",1
listadd 1,"たちつてと",1
listadd 0,"なにぬねの",2
listadd 1,"はひふへほ",2
loop
mref text,65
LVITE=1,0,0,0,0,varptr(text),1024
input text
obj=stat
hEdit=objinfo_hwnd(stat)
SetWindowLong hEdit,-20
ShowWindow hEdit
oncmd gosub *WM_NOTIFY,$4e
stop
;-------------------------------------------------------------------------------
*WM_NOTIFY
dupptr code,lparam,112
if code=hList {
if code(2)=-3 {;NM_DBLCLK
rect=2,code(4),0,0
LVITE(2)=code(4)
sendmsg hList,4141,code(3),varptr(LVITE)
sendmsg hList,(rect(1)>0)*42+4110,code(3),varptr(rect)
MoveWindow hEdit,rect,rect(1),rect(2)-rect,rect(3)-rect(1)
ShowWindow hEdit,1
objprm obj,text
objsel obj
return
}
if code(2)=-100 {;LVN_ITEMCHANGING
objsel -1
if stat=obj {
oncmd 0
sendmsg hList,4102,,varptr(LVITE)
ShowWindow hEdit
oncmd 1
}
}
}
return

| |
|
2015/1/5(Mon) 20:11:46|NO.66885
>どうやってリストビューの項目画面のウィンドウハンドルを取得するのでしょうか?
リストビューのハンドルはすでにobjinfo_hwndで取得していますよね。
項目画面というのがアイテムやサブアイテムのことなら、それら一つ一つにウインドウなどありません。
リストビュー全体で一つのウインドウです。
子ウインドウとしてヘーダーコントロール(一番上のタイトル部分)はありますが。
なんとなくサンプル作ってみました
ちょっとまだ変なところもありますが参考にはなると思います。
#include "llmod3/llmod3.hsp"
#include "llmod3/listview.hsp"
#include "llmod3/img.hsp"
#undef charupper
#undef charlower
#include "user32.as"
#define SW_HIDE $00000000
#define SW_SHOW $00000005
#define WM_COMMAND $00000111
#define WS_CLIPCHILDREN $02000000
listview 400,200,$310009|WS_CLIPCHILDREN
hList=objinfo_hwnd(stat)
listaddcl 0,"test1",100,2
listaddcl 1,"test2",100
listaddcl 2,"test3",100
repeat 10
listadd 0,"あいうえお",0
listadd 1,"かきくけこ",0
listadd 0,"さしすせそ",1
listadd 1,"たちつてと",1
listadd 0,"なにぬねの",2
listadd 1,"はひふへほ",2
loop
dim point,2
dim rect,4
dim lvhittestinfo ,6
dim lvitem,9
cfocus=-1
sdim text,1000
input text,0,0
obj=stat
hEdit=objinfo_hwnd(stat)
SetParent hEdit,hList
ShowWindow hEdit,SW_HIDE
oncmd gosub *WM_NOTIFY,$4e
oncmd gosub *ONCOMMAND,WM_COMMAND
stop
;-------------------------------------------------------------------------------
*WM_NOTIFY
#define LVM_SUBITEMHITTEST $00001039
#define LVM_GETSUBITEMRECT $00001038
#define LVIR_LABEL $00000002
#define LVIF_TEXT $00000001
#define LVM_GETITEM $00001005
#define LVM_SETITEM $00001006
#define LVM_GETNEXTITEM $0000100C
#define LVNI_FOCUSED $00000001
#define LVN_ITEMCHANGING $FFFFFF9C
#define NM_CLICK $FFFFFFFE
#define NM_KILLFOCUS $FFFFFFF8
#define EN_KILLFOCUS $00000200
#define WM_SETTEXT $0000000C
#define WM_GETTEXT $0000000D
dupptr code,lparam,12
if code=hList {
if code(2)=NM_CLICK {
sendmsg hList,LVM_GETNEXTITEM,-1,LVNI_FOCUSED
if stat<0:return
if stat!=cfocus:return
GetCursorPos varptr(point)
ScreenToClient hList, varptr(point)
lvhittestinfo=point(0),point(1)
sendmsg hList,LVM_SUBITEMHITTEST,0,varptr(lvhittestinfo)
rect=LVIR_LABEL,lvhittestinfo(4),0,0
sendmsg hList,LVM_GETSUBITEMRECT,lvhittestinfo(3),varptr(rect)
lvitem=LVIF_TEXT,lvhittestinfo(3),lvhittestinfo(4),0,0,varptr(text),1000
sendmsg hList,LVM_GETITEM,0,varptr(lvitem)
MoveWindow hEdit,rect,rect(1),rect(2)-rect,rect(3)-rect(1),1
ShowWindow hEdit,SW_SHOW
objprm obj,text
objsel obj
return
}
if code(2)=LVN_ITEMCHANGING {
sendmsg hList,LVM_GETNEXTITEM,-1,LVNI_FOCUSED
if stat<0:return 0
cfocus=stat
return 0
}
}
return
*ONCOMMAND
if lparam==hEdit{
if (wparam>>16&0xffff)=EN_KILLFOCUS{
sendmsg hEdit,WM_GETTEXT,1000,varptr(text)
lvitem=LVIF_TEXT,lvhittestinfo(3),lvhittestinfo(4),0,0,varptr(text),1000
sendmsg hList,LVM_SETITEM,0,varptr(lvitem)
ShowWindow hEdit,SW_HIDE
cfocus=-1
}
}
return

| |
|
2015/1/5(Mon) 20:16:08|NO.66886
AさんYTTさん、ありがとうございました。
あと、サンプルまで作っていただいて、本当にありがとうございました!
無事解決しました。
>>子ウインドウとしてヘーダーコントロール(一番上のタイトル部分)はありますが。
てっきり、アイテムの部分が子ウィンドウなのかと思っていました。
私の勘違い申し訳ないです。
|
|