すみません、処理の効率化のために冒頭のモジュールを一部改変しましたので、
前のものは削除して上げ直します。
以下、本文を再掲します。
--------------------------------------------------
「それならinputで入力欄を作り、ボタンを押すなりEnterを押すなりしたら私のモジュールで
リストボックスの内容を変更すればいいじゃないか」…と思いましたが、
「inputやmesboxを使わずに」ということは、このやり方では駄目ということでしょうか?
「その場で文字を打ち込んで」という部分から推察しますが、
「Excelのように直接編集できるリストボックス」を作りたいということでしょうか?
直接編集、というのはちょっと調べてもわからなかったので、妥協案として
「リストボックスをダブルクリックしたら入力欄をポップアップで表示する」という線で
行ってみました。
ご要望通りのものなのかわかりかねますが、せっかく作りましたので貼っておきます。
#include "user32.as"
#include "gdi32.as"
//以下はポップアップ表示中に一時的に画面上のオブジェクトを消し、
//代わりにオブジェクトを模した「画像」を表示するモジュール
//<使い方>
//・screenでウィンドウを初期化したら、fakeobj_init p1を実行する。
//p1は内部での処理で使用するバッファの番号。
//p1は省略可能で、省略した場合は200番が指定される。
//・listbox等、オブジェクトを追加するたびに、fakeobj_add p1を実行してオブジェクトを登録する。
//p1はオブジェクトのID。
//・fakeobj_go p1で、登録したオブジェクトを一時的に消し、代わりに偽のオブジェクトを描画する。
//p1は省略可能。p1に0以外の値を指定した場合は、画面全体を描画対象にする。
//省略するか0を指定した場合は、これまでに登録したオブジェクトが存在する範囲のみが対象。
//・fakeobj_resumeで、消したオブジェクトを復活させる。
//・不要になったらfakeobj_endを実行。
#module
#const objmax 100 //オブジェクトの最大数
#define ctype lower(%1,%2) ((%2)+((%1)-(%2))*((%1)<(%2))) //小さい方を返す
#define ctype higher(%1,%2) ((%2)+((%1)-(%2))*((%1)>(%2))) //大きい方を返す
#define global fakeobj_init(%1=200) _fakeobj_init %1
#deffunc _fakeobj_init int _buf_id
boot_flag=1 : objnum=0
dim h_list,objmax
buf_id=_buf_id
x_min=0 : x_max=0 : y_min=0 : y_max=0 //画面書き換えの範囲
first_flag=0
dim rect,4
sel=ginfo_sel : wid=ginfo_sx : hei=ginfo_sy
buffer buf_id,wid,hei : gsel sel
return
#deffunc fakeobj_add int objid
if boot_flag=0 : return
h_list(objnum)=objinfo(objid,2)
GetWindowRect h_list(objnum),varptr(rect)
ScreenToClient hwnd,varptr(rect) : ScreenToClient hwnd,varptr(rect(2))
if first_flag {
x_min=lower(x_min,rect(0)) : y_min=lower(y_min,rect(1))
x_max=higher(x_max,rect(2)) : y_max=higher(y_max,rect(3))
} else {
first_flag=1
x_min=rect(0) : y_min=rect(1) : x_max=rect(2) : y_max=rect(3)
}
objnum++
return
#define global fakeobj_go(%1=0) _fakeobj_go %1
#deffunc _fakeobj_go int all_flag
if (boot_flag=0)|(objnum=0) : return
if all_flag {
x=0 : y=0 : w=wid : h=hei
} else {
x=x_min : y=y_min : w=x_max-x_min : h=y_max-y_min
}
GetDC hwnd : hdc0=stat
sel=ginfo_sel : gsel buf_id
hdc1=hdc : BitBlt hdc1,x,y,w,h,hdc0,x,y,0x00CC0020 //SRCCOPY
gsel sel : ReleaseDC hwnd,hdc0
BitBlt hdc,x,y,w,h,hdc1,x,y,0x00CC0020 : redraw 1,x,y,w,h
repeat objnum : ShowWindow h_list(cnt),0 : loop
return
#deffunc fakeobj_resume
if boot_flag=0 : return
repeat objnum : ShowWindow h_list(cnt),5 : loop
return
#deffunc fakeobj_end
if boot_flag=0 : return
sel=ginfo_sel : buffer buf_id,1,1 : gsel sel
objnum=0 : boot_flag=0
return
#global
//ここまでモジュール
//このモジュールを作ったのは、ポップアップ入力中にオブジェクトをクリックすると
//クリック判定が上手くいかず、ウィンドウメッセージで処理するのも手間だと思ったので。
#define global b_not(%1) ((%1)^0xFFFFFFFF) //p1のnotを返す
fakeobj_init
//ポップアップ用の入力欄
pop_wid=100 : pop_hei=20 //ポップアップのサイズをここで設定する
_dummy_="" : input _dummy_,pop_wid,pop_hei,0
pop_h=objinfo(stat,2) //ポップアップのハンドル
GetWindowLong pop_h,-16
SetWindowLong pop_h,-16,stat&b_not(0x10010000) //ウィンドウスタイルからWS_TABSTOPとWS_VISIBLEを削除し、ポップアップを隠す
a=0
listbox a,,"あ\nい\nう\nえ\nお"
list_h=objinfo(stat,2) //リストボックスのハンドル
fakeobj_add stat //オブジェクトのフェイク表示の対象にする
GetWindowLong list_h,-16
SetWindowLong list_h,-16,stat|0x1 //LBS_NOTIFYを設定し、WM_COMMANDで通知を受け取れるようにする
pop_flag=0 //ポップアップを表示しているフラグ
edit_h=0 //ポップアップ表示時、編集の対象となるリストボックスのハンドル
edit_l=0 //ポップアップ表示時、編集の対象となるリストボックスの行
dim point,2 //カーソル位置取得に使用する
dim rect,4 //リストボックスの範囲取得に使用する
oncmd gosub *cmd,0x0111 //WM_COMMAND
onclick gosub *click
onkey gosub *key
stop
*cmd
if ((wparam>>16)&0xFFFF)=2 { //通知がLBN_DBLCLKなら
if lparam=list_h { //通知を送ってきたのがリストボックスなら
edit_h=lparam
sendmsg edit_h,0x0188,0,0 //LB_GETCURSEL
if stat!=-1 {
edit_l=stat
gosub *pop_start
}
}
}
return
*click
if pop_flag {
gosub *pop_cancel //画面のどこかをクリックしたら入力を取り消す場合。
//入力を反映する場合はこれを消して下の行のコメントアウトを外す
//gosub *pop_finish
}
return
*key
if pop_flag {
if wparam=13 : gosub *pop_finish //ポップアップ内を入力中にEnterが押されたら、変更を反映する。
}
return
*pop_start
//これを呼ぶ前にedit_hにリストボックスのハンドルを、edit_lに行番号を入れておくこと
sendmsg edit_h,0x18A,edit_l,0 //LB_GETTEXTLEN
if stat=-1 : return
sdim s,stat+1
sendmsg edit_h,0x189,edit_l,varptr(s) //LB_GETTEXT。sにリストボックスの指定行のテキストが入る
sendmsg pop_h,0xC,0,varptr(s) //WM_SETTEXT。ポップアップにテキストを表示。
GetWindowRect edit_h,varptr(rect) : ScreenToClient hwnd,varptr(rect) //リストボックスの範囲を取得
fakeobj_go //オブジェクトをフェイク化
GetCursorPos varptr(point) : ScreenToClient hwnd,varptr(point) //マウスカーソル位置を取得(mouseyが上手く動作しないので)
SetWindowPos pop_h,0,rect(0),point(1)-pop_hei/2,0,0,0x41 //SWP_SHOWWINDOW|SWP_NOSIZE
SetFocus pop_h
sendmsg pop_h,0xD5,0,0 //EM_GETLIMITTEXT
sendmsg pop_h,0xB1,stat,-1 //EM_SETSEL。カーソルをポップアップの末尾に。
pop_flag=1
return
*pop_finish
sendmsg pop_h,0xE,0,0 //WM_GETTEXTLENGTH
sdim s,stat+1
sendmsg pop_h,0xD,stat+1,varptr(s) //WM_GETTEXT。sにポップアップ内のテキストが入る
sendmsg edit_h,0x0182,edit_l,0 //LB_DELETESTRING
if stat!=-1 : sendmsg edit_h,0x0181,edit_l,varptr(s) //LB_INSERTSTRING
*pop_cancel
ShowWindow pop_h,0 //ポップアップを隠す
fakeobj_resume
pop_flag=0
return