◆ タブ操作

[Top] [投稿ルール] [新規質問] [このトピックに発言]
投稿者:猫太 [E-Mail] [HomePage]  投稿日:2005/09/10(土) 19:12:30 No.1

何回も質問すいません(^_^;)
タブの操作についてなんですが、タブの画面切り替え方がわからないので教えていただけないでしょうか??

#uselib "user32.dll"
#func CreateWindowEx "CreateWindowExA" sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr
CreateWindowEx 0,"SysTabControl32","",0x40000000|0x10000000,0,0,640,400,hwnd,0,hinstance,0

htab=stat
repeat 20
a++
caption="Tab"+a
tcitem=0x0001,0,0,varptr(caption)
sendmsg htab,0x1307,a,varptr(tcitem)
loop
stop


投稿者:月影とも [HomePage]  投稿日:2005/09/11(日) 00:26:16 No.2

WM_NOTIFYが絡むとメッセージの形に慣れるまでがちょっと難しいかな?
とりあえずタブチェンジの通知を取得する部分はこんな感じで。
それともウィンドウ内部への描画の仕方がわからない、とかだったら「まとはずれでごめんなさい」ですが。

#define WM_NOTIFY $4e
#define TCM_INSERTITEMA $1307
#define TCN_SELCHANGE   $FFFFFDD9
#define TCM_GETCURSEL   $130b

;WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN
winobj "SysTabControl32","",0,$56000000,640,400
oncmd gosub *onNOTIFY,WM_NOTIFY ;// タブが変わるとメッセージが飛んでくる

dim tcitem,7
repeat 5
    caption="Tab"+cnt
    tcitem = 1,0,0,varptr(caption)
    sendmsg objinfo(0,2) ,TCM_INSERTITEMA, cnt, varptr(tcitem)
loop

stop

*onNOTIFY
;// WM_NOTIFYのlparamにNMHDR構造体のアドレスが入っていて
;// その構造体に含まれる通知コードが TCN_SELCHANGE なら、タブチェンジ。
	dupptr NMHDR,lparam,12
	if NMHDR.2 == TCN_SELCHANGE { gosub *onTCN_SELCHANGE }
return

*onTCN_SELCHANGE
;// NMHDR.0 にはメッセージ送信元のハンドルが入っているので、
;// タブコントロールを複数作るときはそのハンドルをobjinfoのハンドルと比較して特定すること。
    sendmsg NMHDR.0 ,TCM_GETCURSEL, 0, 0 : tabid = stat

;// ここでダイアログを表示する代わりに TABコントロールの中に表示される内容を書き換える。
;// BGSCRを貼り付けて作っている場合は、最初に全部非表示のまま貼り付けておいて、
;// ここで gselで表示されるべき表示、それ以外を非表示にする感じかな。
    dialog "Tab"+tabid+"が選択されました" 
return


投稿者:猫太 [E-Mail] [HomePage]  投稿日:2005/09/11(日) 00:51:10 No.3

すいませんm(_ _)m
描画の方もお願いできますか??

投稿者:月影とも [HomePage]  投稿日:2005/09/11(日) 14:07:38 No.4

BGSCRをタブコントロールに貼り付けてみるパターンで。

解説としては↓に乗っ取って書いてます。とりあえず読んでみてください(無責任
タブコントロールを作成してみる ACT-2
http://yokohama.cool.ne.jp/chokuto/urawaza/tabctl2.html

#define WM_NOTIFY $4e
#define TCM_INSERTITEMA $1307
#define TCN_SELCHANGE   $FFFFFDD9
#define TCM_GETCURSEL   $130b

#uselib "user32.dll" ;// 新たに追加した定義
#func GetClientRect "GetClientRect" int, var
#func SetWindowLong "SetWindowLongA" int,int,int
#cfunc GetWindowLong "SetWindowLongA" int,int
#func SetParent "SetParent" int,int
#func MoveWindow "MoveWindow" int,int,int,int,int,int
#define  TCM_ADJUSTRECT    $1328
#cfunc GetSysColor "GetSysColor" int
#define ColorFromCOLORREF(%1) color (%1)&$FF,(%1)>>8&$FF,(%1)>>16&$FF

;// コントロールの作成
ColorFromCOLORREF(GetSysColor(15)):boxf ;// システムカラーでの塗りつぶすとそれっぽい
pos 20,20 : winobj "SysTabControl32","",0,$56000000,600,400 : TABhWnd = objinfo(stat,2)
oncmd gosub *onNOTIFY,WM_NOTIFY

dim tcitem,7

TABS = 5

repeat TABS
    caption="Tab"+cnt
    tcitem = 1,0,0,varptr(caption)
    sendmsg TABhWnd ,TCM_INSERTITEMA, cnt, varptr(tcitem)
loop


;// 内容てきとー作る 
;// もちろんそれぞれの窓ごとにバラバラに作ってOKだけど、
;// 窓切り替えの時に楽なように連番で作ることをオススメ。
;// この例では WindowId は 20〜 の連番
repeat TABS ;// 新たに追加した部分 
    ;// BGSCRするときはこっから
    windowid = 20+cnt
    dim rect,4 : GetClientRect TABhWnd,rect ;// コントロールの表示領域の取得
    sendmsg TABhWnd, TCM_ADJUSTRECT, 0, varptr(rect) 
    bgscr windowid, rect.2-rect.0 , rect.3-rect.1, 2 ;// 子ウィンドウの作成
    SetWindowLong hwnd, -16, GetWindowLong(hwnd, -16)&$7FFFFFFF|$40000000 ;//ウィンドウスタイルの変更
    SetParent hwnd, TABhWnd ;// 親ウィンドウの設定
    width rect.2,rect.3,rect.0,rect.1 ;// 移動
    ;// ここまでがお約束。
    ColorFromCOLORREF(GetSysColor(15)):boxf ;// システムカラーでの塗りつぶすとそれっぽい
    color : pos 10*cnt,10*cnt : mes "TAB"+cnt+"の内容です。"
loop

gosub *onTCN_SELCHANGE
stop


*onNOTIFY
    dupptr NMHDR,lparam,12
    if NMHDR.2 == TCN_SELCHANGE { gosub *onTCN_SELCHANGE }
return

*onTCN_SELCHANGE
    sendmsg NMHDR.0 ,TCM_GETCURSEL, 0, 0 : tabid = stat
    ;// 窓を切り替える。wid 20〜の連番にしておいたのでrepeatで非表示にできる。
    repeat TABS : gsel 20+cnt, (cnt=tabid)*2-1 : loop 
return


投稿者:電気男  投稿日:2005/09/11(日) 16:04:57 No.5

横から口を挟んですいません。
タブのフォントの種類や色を変更することは出来るのですか?
もう少しシステムフォントにしてみたいです。

投稿者:猫太 [E-Mail] [HomePage]  投稿日:2005/09/11(日) 16:32:43 No.6

タブって難しいですね〜(^_^;)かなり苦戦しています(~_~)
あと、タブのスタイル変更はどこをいじればいいんですか??
多段表示のタブとか作りたいもんで(^_^;)すいません、お願いしますm(__)m

投稿者:月影とも [HomePage]  投稿日:2005/09/12(月) 01:18:58 No.7

フォントの設定方法ですが
wparam をHFONTにしてWM_SETFONTメッセージを送れば任意のフォントに設定できます。
;// デフォルトGUIにしてみる。
##define WM_SETFONT $30
#uselib "gdi32.dll"
#cfunc GetStockObject "GetStockObject" int
#define DEFAULT_GUI_FONT	17
SendMsg TABhWnd, WM_SETFONT, GetStockObject(DEFAULT_GUI_FONT), 0

;// 任意のフォントにしてみる。
#define WM_SETFONT	$30
#uselib "gdi32.dll"
#cfunc CreateFontIndirect "CreateFontIndirectA" var
#func DeleteObject "DeleteObject" int
font "MS 明朝",18
mref bmscr,67
TABhFont = CreateFontIndirect(BMSCR.49) ;// 作ったフォントハンドルは
SendMsg TABhWnd, WM_SETFONT, TABhFont, 1
onexit goto *delfont ;// 使い終わるときには消してください。
stop
*delfont
    DeleteObject TABhFont
    end

下の方法はちょっと考えてスクリ書いてから、調べたらちゃんと
http://yokohama.cool.ne.jp/chokuto/urawaza/setfont.html
載ってるじゃないですか、、ここの4番目の方法です。

で、スタイルですが、
http://msdn.microsoft.com/library/ja/shellcc/platform/commctls/tab/styles.asp
オフィシャルはこのドキュメントあたりですがあいにく日本語化されていません。
なので……
Mr.XRAY - Halbow資料館
http://homepage2.nifty.com/Mr_XRAY/Halbow/Chap29.html#Chap29-3
言語はDelphiですが、定数値は同じですので参考にしてください。
他のコントロールのスタイルもたくさん載ってるので。
winobj命令は第3引数に拡張スタイル、第4引数にスタイルを設定できます(ヘルプ参照のこと)
そこにこんな値を足していってください。
;// ちなみに拡張スタイルはそこには書いてませんがこんなのがあります。
#define TCS_EX_FLATSEPARATORS $1
  ;// タブをボタンにしたときに 自動で付く。
  ;// ボタンとボタンの間に入る | を表示する。
#define TCS_EX_REGISTERDROP	$2
  ;// タブのドラッグ&ドロップ周り。


>電気男さん
関連して聞きたいことがあったらどんどん聞いておきましょう。遠慮は要らないですよん。

投稿者:電気男  投稿日:2005/09/12(月) 11:20:19 No.8

月影とも様、
 気を使って頂き有難うございます。

 確かにこれでフォントは変えられるのですが、フォントの色を変更できます
 か?
 あと、任意のフォントを選択した場合、終了時にハンドルを消すようですが
 これは、絶対やらなければならないのでしょうか?
 やらなくてもOKのような気もしますが…

投稿者:月影とも [HomePage]  投稿日:2005/09/13(火) 04:14:49 No.9

MSDNの英語のドキュメント一通り流し読んできましたが色は無理な気がします。
いや、まぁ、オーナードローすればできないことなんてないのでしょうが……

DeleteObjectは……
限りある資源を有効に……。
プログラム終了時に必ず解放されるハンドルとそうでないのとあったりします。
バグだとか仕様だとかイロイロありますが。
たとえば……どのプログラムも使っていないのに削除できないフォルダとかに出会ったことないですか?
そういうのは大抵そこを使ったアプリケーションが解放を忘れているからです。

で、以下は概念的な話ですが、
「ハンドルを解放しなくてもいいや」ってのは
「メモリリークやリソースリークしてもいいや」って考え方と同じ、になりませんかね。
今時のOSなら、アプリケーションが使ったメモリ空間はしっかり解放するでしょうが、
APIを使って「(アプリケーションのために)OSが自分の空間上に確保したメモリ」は
果たして必ず解放されるのでしょうか……?
(まぁ、最近のちゃんとしたOSなら解放されると思いますが……)

Windowsのリソースはその上で動作するすべてのソフトウェアで共有する資源です。
CreateしたハンドルはどこにCreateしてるのかと言うと、
OSからリソースを借りてそこにCreateしてるわけで、
それを返さないままプロセスを終了して、OSの「強制返却」に任せるってのは、
いかがなもんですかね。
結局、借りたものは返しましょう、みたいな話。

さぁ、あなたが確保したそのハンドル、本当に絶対解放されるんですか?

というわけで、自分は解放するようにしています。
まぁ、これが絶対正しいと言うつもりもく、ごく個人的な私の意見です。
……ですので、そういう細かいところはお任せします。

投稿者:猫太 [E-Mail] [HomePage]  投稿日:2005/09/13(火) 16:41:19 No.10

月影ともさん回答ありがとうございます!!見事多段表示になりました(^^)
これで解決かと思ってたんですけど・・・ひとつ問題が起こりまして、タブを作った後タブを選択して、タブを作ったウィンドウをgselで消したあと、またそのウインドウを開くとさっき選択したタブのままになっていてそのタブに一番最初のタブ(タブ0)の内容が描画されます。何かタブを初期化する方法はございませんか??一応サンプル載せておきます。

#define WM_NOTIFY $4e
#define TCM_INSERTITEMA $1307
#define TCN_SELCHANGE   $FFFFFDD9
#define TCM_GETCURSEL   $130b

#uselib "user32.dll" ;// 新たに追加した定義
#func GetClientRect "GetClientRect" int, var
#func SetWindowLong "SetWindowLongA" int,int,int
#cfunc GetWindowLong "SetWindowLongA" int,int
#func SetParent "SetParent" int,int
#func MoveWindow "MoveWindow" int,int,int,int,int,int
#define  TCM_ADJUSTRECT    $1328
#cfunc GetSysColor "GetSysColor" int
#define ColorFromCOLORREF(%1) color (%1)&$FF,(%1)>>8&$FF,(%1)>>16&$FF
wx=600:wy=400


;// コントロールの作成
ColorFromCOLORREF(GetSysColor(15)):boxf ;// システムカラーでの塗りつぶすとそれっぽい
 : winobj "SysTabControl32","",0,$56000200,wx,wy : TABhWnd = objinfo(stat,2)
oncmd gosub *onNOTIFY,WM_NOTIFY

dim tcitem,7

TABS = 10

repeat TABS
    caption="Tab"+cnt
    tcitem = 1,0,0,varptr(caption)
    sendmsg TABhWnd ,TCM_INSERTITEMA, cnt, varptr(tcitem)
loop


;// 内容てきとー作る 
;// もちろんそれぞれの窓ごとにバラバラに作ってOKだけど、
;// 窓切り替えの時に楽なように連番で作ることをオススメ。
;// この例では WindowId は 20〜 の連番
repeat TABS ;// 新たに追加した部分 
    ;// BGSCRするときはこっから
    windowid = 20+cnt
    dim rect,4 : GetClientRect TABhWnd,rect ;// コントロールの表示領域の取得
    sendmsg TABhWnd, TCM_ADJUSTRECT, 0, varptr(rect) 
    bgscr windowid, rect.2-rect.0 , rect.3-rect.1, 2 ;// 子ウィンドウの作成
    SetWindowLong hwnd, -16, GetWindowLong(hwnd, -16)&$7FFFFFFF|$40000000 ;//ウィンドウスタイルの変更
    SetParent hwnd, TABhWnd ;// 親ウィンドウの設定
    width rect.2,rect.3,rect.0,rect.1 ;// 移動
    ;// ここまでがお約束。
    ColorFromCOLORREF(GetSysColor(15)):boxf ;// システムカラーでの塗りつぶすとそれっぽい
    color 255 : mes "TAB"+cnt+"の内容です。"
    button "OK",*m
loop
*m
gsel 0,-1
screen 2,300,200
button gosub "オプション",*op
gosub *onTCN_SELCHANGE
stop


*onNOTIFY
    dupptr NMHDR,lparam,12
    if NMHDR.2 == TCN_SELCHANGE { gosub *onTCN_SELCHANGE }
return

*onTCN_SELCHANGE
    sendmsg NMHDR.0 ,TCM_GETCURSEL, 0, 0 : tabid = stat
    ;// 窓を切り替える。wid 20〜の連番にしておいたのでrepeatで非表示にできる。
    repeat TABS : gsel 20+cnt, (cnt=tabid)*2-1 : loop 
return

*op
	gsel 0,1
	return


投稿者:電気男  投稿日:2005/09/13(火) 19:41:45 No.11

月影とも様
了解しました。いろいろとありがとうございました。

投稿者:月影とも [HomePage]  投稿日:2005/09/13(火) 20:56:39 No.12

いっけねー。これじゃダメですね……(汗

タブの初期化は
#define TCM_SETCURSEL $130C
wparam=item lparam=0 で
でsendmsgすれば切り替わります。

*op
    tabid = 0
    sendmsg TABhWnd, $130C, tabid, 0
    repeat TABS : gsel 20+cnt, (cnt=tabid)*2-1 : loop 
    gsel 0,1
    return

後、*m内の gosub *onTCN_SELCHANGE は上手く動くわけがないので消しちゃってくださorz

投稿者:電気男  投稿日:2005/09/13(火) 21:24:34 No.13

KbMediaPlayerってご存知ですか?あの、ウルトラマリンが再生できる
やつです。このプレイヤーのタブでは、タブの耳(?)部分にマウスを
もって行くと、文字が若干青っぽくなります。これは、どのようにやって
いるのでしょうか??っと思い、聞いてみました。もちろん、この
プレイヤー自体、C++で開発されていますので勝手が違うのかも
知れませんが、HSPでも、同様の事が出来るのではないかと思い
質問してみました。

投稿者:月影とも [HomePage]  投稿日:2005/09/13(火) 22:59:41 No.14

ソフトはわかりませんが、文字が青くなるのは TCS_HOTTRACK スタイルを付加したときのこと、かな。
winobjのp2に$40を足してみてください。他のスタイルについては上の方のNo.7を見てください。

投稿者:猫太 [E-Mail] [HomePage]  投稿日:2005/09/16(金) 01:00:51 No.15

月影ともさんありがとうございます!!ちゃんと初期化されました(^^)
これで先に進めます(^^)v
また何かあったら書き込みに着ます(^_^;)
電気男さん。
僕はタブの質問は解決しましたので、解決にしてよろしいですか??

投稿者:電気男  投稿日:2005/09/17(土) 18:45:49 No.16

解決!!(≧▽≦)
OKです。
では、私が解決印押しておきます。

投稿者:電気男  投稿日:2005/09/21(水) 03:30:50 No.17

本当に何度も申し訳ないです、
タブ項目の文字列フォントをデフォルトフォントしたいのですが、

;// デフォルトGUIにしてみる。
##define WM_SETFONT $30
#uselib "gdi32.dll"
#cfunc GetStockObject "GetStockObject" int
#define DEFAULT_GUI_FONT	17
SendMsg TABhWnd, WM_SETFONT, GetStockObject(DEFAULT_GUI_FONT), 0


をどこに入れたらいいのか、教えてもらった時はうまく行ったのですが
今、やってみたら、どこだかちょっとわからなくなってしまいました。
一番上ではまずいのですよね?

投稿者:月影とも [HomePage]  投稿日:2005/09/21(水) 12:46:31 No.18

winobj "SysTabControl32","",0,$56000200,wx,wy : TABhWnd = objinfo(stat,2)
より後に実行されれば大丈夫です。
#define が ##define になってますが、それでは無視されるので直しておいてください。

投稿者:電気男  投稿日:2005/09/21(水) 22:42:48 No.19

##になっているのが原因のようでした。
提供されるものも使いこなせず申し訳ございませんでした。

追加発言 [▲]
お名前 (必須)
パスワード(必須)下の「記事 修正/削除フォーム」で修正、削除ができます。
Eメール (非推奨)
ホームページ (任意)

発言 (エラー時再送信禁止)
・1行が長い場合、右端で折り返しします。適度に改行を入れてください。
スクリプトは小文字の <pre>〜</pre> で囲んでください。 詳細説明
顔文字(^^) スパムと誤認識されたら

←解決時は質問者本人がここをチェックしてください。     [File upload]
送信前に 今一度 誹謗・中傷と勘違いされるような内容など含まれていないか お確かめください。


記事 修正/削除フォーム
 処理  記事No  パスワード

WwwLounge Ver2.16
Arranged by puma

無料ホームページ ブログ(blog)