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


HSPTV!掲示板


未解決 解決 停止 削除要請

2014
0518
catsタブコントロールの拡張7解決


cats

リンク

2014/5/18(Sun) 13:59:23|NO.62078

HSPでタブコントロールを拡張したいのですが、
参考になるサイトやソースがあればご教示ください。
具体的には以下のような動作を目指しています。
・閉じるボタン設置
・ドラッグでタブ移動(+ピン留め)
・タブに右クリックメニュー設置(一応実装済み)
特に閉じるボタンの設置が必要なのですが、
C#などのソースしか見つかりません。
今のところ以下のリンク先のモジュールでできそうな気も
するのですが、分かりません(TFS_CLOSEBUTTONか?)
http://hsp.tv/play/pforum.php?mode=pastwch&num=58781
webブラウザのようにユーザーが追加、削除をできる
ようなタブコントロールを作る予定ですので、
完全に自己描画するのは難しいかと考えております。



この記事に返信する


fortunehill

リンク

2014/5/18(Sun) 14:24:54|NO.62079

/*ご参考かも?(Delphi)
ttp://mrxray.on.coocan.jp/Halbow/Chap29.html
*/



cats

リンク

2014/5/18(Sun) 16:54:34|NO.62086

>fortunehillさん
ご回答ありがとうございます。
http://lhsp.s206.xrea.com/hsp_object6.html#1
こちらのタブコントロール用のモジュールにイメージを
設定してみたのですが変化がありませんでした。
Delphiは初めて見たので読み間違えたのかもしれませんが。
それから、タブのアイコンのクリック判定ってできるものなのでしょうか?

#uselib "comctl32.dll" #cfunc ImageList_Create "ImageList_Create" sptr,sptr,sptr,sptr,sptr #func ImageList_AddIcon "ImageList_AddIcon" sptr,sptr #uselib "user32.dll" #cfunc LoadIcon "LoadIconA" sptr,sptr /************追加****************/ #define global ILC_COLOR 0x0000 #define global ILC_COLOR4 0x0004 #define global ILC_COLOR8 0x0018 #define global ILC_COLOR16 0x0010 #define global ILC_COLOR24 0x0018 #define global ILC_COLOR32 0x0020 #define global ILC_COLORDDB 0x00FE #define global ILC_MASK 0x0001 #define TCM_SETIMAGELIST 0x1303 /*********************************/ #module #uselib "user32" #func GetClientRect "GetClientRect" int, int #func SetWindowLong "SetWindowLongA" int, int, int #func SetParent "SetParent" int, int #uselib "gdi32" #cfunc GetStockObject "GetStockObject" int ; CreateTab p1, p2, p3, p4 ; タブコントロールを設置します。statにタブコントロールのハンドルが ; 返ります。 ; p1〜p2=タブコントロールのX/Y方向のサイズ ; p3(1)=タブの項目として貼り付けるbgscr命令の初回ウィンドウID値 ; p4=タブコントロールの追加ウィンドウスタイル #deffunc CreateTab int p1, int p2, int p3, int p4 winobj "systabcontrol32", "", , $52000000 | p4, p1, p2 hTab = objinfo(stat, 2) sendmsg hTab, $30, GetStockObject(17) TabID = p3 if TabID = 0 : TabID = 1 dim rect, 4 return hTab ; InsertTab "タブつまみ部分の文字列" ; タブコントロールに項目を追加します。 #deffunc InsertTab str p2 pszText = p2 : tcitem = 1, 0, 0, varptr(pszText) sendmsg hTab, $1307, TabItem, varptr(tcitem) GetClientRect hTab, varptr(rect) sendmsg hTab, $1328, , varptr(rect) bgscr TabID + TabItem, rect.2 - rect.0, rect.3 - rect.1, 2, rect.0, rect.1 SetWindowLong hwnd, -16, $40000000 SetParent hwnd, hTab TabItem++ return #deffunc ChangeTab gsel wID + TabID, -1 sendmsg hTab, $130B wID = stat gsel wID + TabID, 1 return #global screen , 400, 300 syscolor 15 : boxf pos 50, 50 CreateTab 300, 200, 1 hTabControl = stat InsertTab "AAA" pos 50, 50 : mes "A" InsertTab "BBB" pos 50, 50 : mes "B" InsertTab "CCC" pos 50, 50 : mes "C" InsertTab "DDD" pos 50, 50 : mes "D" gsel 1, 1 gsel /************追加****************/ hIM = ImageList_Create(16, 16, ILC_COLOR24 | ILC_MASK, 4, 0) ;イメージリスト生成 repeat 4 ImageList_AddIcon hIM, LoadIcon(0, 32512+cnt) ;イメージリストに適当に追加 loop sendmsg hTabControl, TCM_SETIMAGELIST, 0, hIM ;メッセージ送信 /********************************/ oncmd gosub *notify, $4E stop ; タブ項目切り替え処理部分です。 *notify dupptr nmhdr, lparam, 12 if nmhdr.0 = hTabControl & nmhdr.2 = -551 { ChangeTab gsel } return



774

リンク

2014/5/18(Sun) 19:35:30|NO.62093

イメージ設定についてですが、コントロール項目追加時のTCITEM構造体で
iImageメンバが無効になっている為表示されないようです。

#deffunc InsertTab str p2, int p3 ;p3:イメージリスト内の画像idx指定 pszText = p2 : tcitem = 1|2, 0, 0, varptr(pszText), 0, p3
のようにすると表示されるかと思います。

クリック判定については、NM_Clickメッセージを捕獲し
TCM_GetItemRect等でタブ項目内での座標を割り出すような感じでしょうか。

閉じるボタンを追加するには
オーナードローかボタン等を子コントロールとして乗せる方法になると思うのですが
ここまで来るといっそ自作してしまった方が、個人的には楽な気がします。

どうしても既存コントロールと外観を合わせたいと言う事でしたら
コントロール描画系APIを駆使すればなんとかなる…かも知れませんし。



cats

リンク

2014/5/18(Sun) 20:37:52|NO.62095

>イメージ設定についてですが、コントロール項目追加時のTCITEM構造体で
>iImageメンバが無効になっている為表示されないようです。
なるほど。
774さんの指摘された箇所を訂正したところアイコンが表示されました。

>ここまで来るといっそ自作してしまった方が、個人的には楽な気がします。
やはり自作の方が楽でしょうか。
とりあえずモジュールを作ってみます。



m

リンク

2014/5/18(Sun) 20:52:54|NO.62096

タブのアイコン、文字列、空白部分の判定はTCM_HITTESTで調べる事ができます。
細かい座標は774さんも書いていますがTCM_GETITEMRECTから相対的に求めます。


#uselib "user32.dll" #func ScreenToClient "ScreenToClient" int,var #func ClientToScreen "ClientToScreen" int,var #define global NM_CLICK $FFFFFFFE #define global NM_RCLICK $FFFFFFFB #define global TCM_HITTEST $0000130D #define global TCM_GETITEMRECT $0000130A #define global TCHT_NOWHERE $00000001 #define global TCHT_ONITEM $00000006 #define global TCHT_ONITEMICON $00000002 #define global TCHT_ONITEMLABEL $00000004 *notify dupptr nmhdr, lparam, 12 if nmhdr.0 = hTabControl & nmhdr.2 = -551 { ChangeTab gsel 0 return } if nmhdr(0) == hTabControl { debugLog = "" if nmhdr(2) == NM_CLICK : debugLog += "L-Click" if nmhdr(2) == NM_RCLICK : debugLog += "R-Click" if debugLog == "" : return // マウスのスクリーン座標をタブコントロールのクライアント座標に変換してTCM_HITTESTで判定 TCHITTESTINFO = ginfo_mx, ginfo_my, 0 ScreenToClient hTabControl, TCHITTESTINFO sendmsg hTabControl, TCM_HITTEST, 0, varptr(TCHITTESTINFO) tabID = stat debugLog += " Tab:"+tabID if TCHITTESTINFO(2) == TCHT_NOWHERE : debugLog += " NOWHERE" if TCHITTESTINFO(2) == TCHT_ONITEM : debugLog += " ONITEM" if TCHITTESTINFO(2) == TCHT_ONITEMICON : debugLog += " ONITEMICON" if TCHITTESTINFO(2) == TCHT_ONITEMLABEL : debugLog += " ONITEMLABEL" // タブアイテムの位置からの相対座標 RECT = 0,0,0,0 sendmsg hTabControl,TCM_GETITEMRECT, tabID, varptr(RECT) RECT(2) -= RECT(0) : RECT(3) -= RECT(1) ClientToScreen hTabControl, RECT debugLog += " CPos("+(ginfo_mx-RECT(0))+","+(ginfo_my-RECT(1))+") Size("+RECT(2)+","+RECT(3)+")" logmes debugLog } return



cats

リンク

2014/5/18(Sun) 21:02:19|NO.62097

>mさん
掲示して下さったソースを動かした所、
タブ内のクリックした位置が正確に取得できました。
閉じるボタンは文字の左側になりますが、
何か問題に直面しない限りこの方法を使おうと思います。

回答してくださった皆さん、ありがとうございました。



774

リンク

2014/5/18(Sun) 22:10:34|NO.62101

閉じるボタンは右側に配置するのだと勝手に思い込んでました、すみません m(_ _)m
>個人的には楽な気がします。
は標準タブコントロールの右側に設置するくらいなら、ということで…



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