HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2017
0306
UNGAWM_COMMANDでlistboxのIDがうまく取れません5解決


UNGA

リンク

2017/3/6(Mon) 18:30:13|NO.78402


#define WM_COMMAND $111 oncmd gosub *show,WM_COMMAND list="a\nb\nc\nd\n" listbox tmp,100,list hListbox = objinfo(stat,2) stop *show gsel 0 sendmsg hListbox,$188 title ""+stat ; screen 2 ;★ return

上記のスクリプトですがこの状態ではうまくいきます。
ところが、★のとこのコメントアウトを解除するとうまくいかなくなる。
つまり、oncmdのジャンプ先のサブルーチンで画面操作すると、何故かう
まくいかない!!

これってHSPの仕様でしょうか?何か解決方法があったら教えてください。



この記事に返信する


掘木

リンク

2017/3/7(Tue) 02:22:44|NO.78408

コメントアウト状態では上手く行っているように見えはするけども、
その時点でメッセージが来ているタイミング、回数、パラメータ等は確認しましたか?

LISTBOXのWM_COMMANDは選択項目の変更時に送られてくるのはそうでしょうけど、
選択変更時以外にも送られてくることを加味しないといけないです。
http://wisdom.sakura.ne.jp/system/winapi/win32/win68.html
Cの資料ですが、後ろのほうの"リストボックスの通知コード"って辺りが参考になるかと。

動かない要因はLBN_SETFOCUS(4)が来たタイミングで別ウィンドウにフォーカスが移るためです。
なお、LISTBOXの通知コードのLBN_SELCHANGEは1らしい。LBN_DBLCLKは2な模様。

追記:$188はLB_GETCURSELですかね。



UNGA

リンク

2017/3/7(Tue) 08:08:24|NO.78409

お返事ありがとうございます。

$188はLB_GETCURSELです。

内部的にstatに値が入るより前にscreen 2にフォーカスが移ってしまうってことですか?
試しにscreen 2の前にwait 500くらい噛ませてみると確かにstatに値が入りますね。
何か良い方法が無いものか・・・。



掘木

リンク

2017/3/7(Tue) 16:10:25|NO.78412

ん?statに値が入る前にだとかはSendMessageなのでそんなこと気にする必要がなく、
実際に選択位置がstatには返っています。
ただ、statに値が入るためには実際にリストボックスの選択変更が成功した後でなくてはならず、
そもそも、リストボックスの選択変更に成功していないんです。

・マウスクリックによって、選択を変更しようとする
→まず、リストボックスはフォーカスを獲得する
→フォーカス獲得によってリストボックスは親へ通知(WM_COMMANDが発生)
→フォーカスが新しくできたウィンドウによって剥奪される(screen2の時点で割り込み #1)
→フォーカス喪失にによって、親ウィンドウへ通知(WM_COMMANDが発生)
→screen2が再生成される(*show終わり)
→(#1)の続きが実行される。(*show終わり)
→クリック動作によって選択を変更しようとしていたリストボックスはフォーカスがないため、
 その操作を失敗とする。
>新しくウィンドウが出てくるが、リストボックス選択位置は見た目上も実際の値も変化していない。
!結果として、選択変更によるWM_COMMANDは発生しない。


#define global WM_COMMAND $111 #define global LB_GETCURSEL $188 #define global LBN_SELCHANGE 1 #define global LBN_DBLCLK 2 #define global LBN_SELCANCEL 3 #define global LBN_SETFOCUS 4 #define global LBN_KILLFOCUS 5 #define global ctype LOWORD(%1) ((%1)&0xFFFF) #define global ctype HIWORD(%1) LOWORD((%1)>>16) oncmd gosub *show,WM_COMMAND listbox tmp,100,"a\nb\nc\nd\n" hListbox = objinfo(stat,2) pos 160,0 // test-code stop *show // logmes strf("%08X",wparam) if ( lparam == hListBox ){ // LOWORD(wparam) == 0x4000 + 0(object-id) でも単一ウィンドウならば可能。 // Debug-Area gsel 0 if ( HIWORD(wparam) == LBN_SELCHANGE ) : mes "選択変更" if ( HIWORD(wparam) == LBN_DBLCLK ) : mes "ダブルクリック" if ( HIWORD(wparam) == LBN_SELCANCEL ) : mes "選択キャンセル" if ( HIWORD(wparam) == LBN_SETFOCUS ) : mes "フォーカス獲得" if ( HIWORD(wparam) == LBN_KILLFOCUS ) : mes "フォーカス喪失" // end-Debug-Area if ( HIWORD(wparam) == LBN_SELCHANGE ){ gsel 0 sendmsg hListbox,$188 title ""+stat screen 2 ;★ return 0 } } return // DefWindowProc()
WM_COMMANDで何かするなら、だれが何の目的で送ったものかを確認しないと。
ちなみに、すでに選択中のものを選んでも選択変更が来るのはリストボックス側の仕様です。
実際に変更されたかどうかは前回値との比較で。



UNGA

リンク

2017/3/8(Wed) 11:10:17|NO.78422

詳しい解説有難うございます。

Listboxの項目を選択した時に、まず「フォーカス獲得によってリストボックスは親へ
通知(WM_COMMANDが発生)する」のだという認識がありませんでした。

勉強になりました。



UNGA

リンク

2017/3/8(Wed) 11:10:44|NO.78423

ありがとうございました。



ONION software Copyright 1997-2023(c) All rights reserved.