hinekure.net が http://hspdev-wiki.net/ から自動クローリングした結果を表示しています。画像やリソースなどのリンクが切れています。予めご了承ください。 |
オーナードローボタンを作成してみましょう。
サンプルプログラムを作りながら説明していきます。
オーナードローについての基本的な流れにそってやってみましょう。
今回はほとんどを HSP3 の基本命令で作っています。
(注意)今回はコントロールへ描画するのに裏技的な方法を使っています。
うかつに使うと危険なのでサンプルプログラムでの使用に留めてください。
今回はオーナードローボタンを作るので button 命令で作ったボタンのスタイルを変更することに
します。
画面の初期化も行っておきます。
コントロールへの描画に使用するためにバッファ画面も用意しておきます。
screen 0, 640, 480, 0 buffer 1, 640, 480, 0 gsel 0, 0
比較用に普通のボタンも作っておきます。大きめのサイズにしています。
objsize 160, 120 button "普通", *futubutton
同じ大きさでオーナードローボタンの元になるボタンを作ります。今回はウィンドウの中心に置きます。
objinfo 命令でウィンドウハンドルという数値を取得しておくと何かと便利です。
pos 240, 180 button "オーナードロー", *ownerdrawbutton hwndODB=objinfo(1, 2)
ボタンのスタイルをオーナードロースタイルに変更します。
対象のボタンに対して sendmsg 命令で BM_SETSTYLE メッセージを送って BS_OWNERDRAW に設定します。
(詳しくは説明しません。よくわからない人は自分で調べるか、こうするんだと思って流してください。)
#define BM_SETSTYLE 0x00F4 #define BS_OWNERDRAW 0x0000000B sendmsg hwndODB, BM_SETSTYLE, BS_OWNERDRAW, 0
オーナードローボタンの場合はここで設定することはありません。
HSP3 でウィンドウメッセージが送られてきたら何かを行うという処理をする場合は
oncmd 命令を使います。
オーナードローボタンを描き換える必要があるときは WM_DRAWITEM メッセージが送られてきます。
このメッセージがきたらサブルーチンに跳んでボタンの描画を行います。
#define WM_DRAWITEM 0x002B oncmd gosub *draw_ownerdrawbutton, WM_DRAWITEM
メインルーチンの残りとボタンを押したときの処理をします。
今回はボタンを押すとダイアログを表示するだけです。
stop *futubutton dialog "普通のボタンが押されました。" stop *ownerdrawbutton dialog "オーナードローボタンが押されました。" stop
WM_DRAWITEM メッセージがきたときには描画に役立つ情報も一緒に送られてきます。
その情報は HSP3 のシステム変数の wparam,lparam に代入されています。
wparam にはコントロールの識別 ID 値が、 lparam には情報の入った DRAWITEMSTRUCT 構造体への
ポインタが 代入されています。
(構造体についても詳しくは説明しません。一つの変数の中にいろいろな値が入っているものです。)
描画のためのサブルーチンです。まず必要な情報を使いやすい形にします。
lparam にポインタで渡された DRAWITEMSTRUCT 構造体の内容を 12 個の要素をもつ配列変数 DIS として
扱えるようにしています。
さらに配列の要素を名前で指定できるようにマクロ名に数値を割り当てています。
*draw_ownerdrawbutton ; DRAWITEMSTRUCT { #enum DIS_CtlType =0; UINT CtlType; #enum DIS_CtlID ; UINT CtlID; #enum DIS_itemID ; UINT itemID; #enum DIS_itemAction; UINT itemAction; #enum DIS_itemState ; UINT itemState; #enum DIS_hwndItem ; HWND hwndItem; #enum DIS_hDC ; HDC hDC; #enum DIS_rcItem0 ; RECT rcItem; #enum DIS_rcItem1 ; #enum DIS_rcItem2 ; #enum DIS_rcItem3 ; #enum DIS_itemData ; ULONG_PTR itemData; ; } wp=wparam lp=lparam dupptr DIS, lp, 48, 4
WM_DRAWITEM メッセージはどのオーナードローコントロールに描画の必要が生じても送られてきます。
このプログラムでは必要ないのですが、コントロールごとに別々の処理を行うために
DIS の値を調べます。
DIS.DIS_CtlType? にはコントロールの種類を示す値が入っています。ボタンの場合は 4 です。
DIS.DIS_hwndItem にはコントロールのウィンドウハンドルが入っています。
これでどのボタンを描画するべきか判断します。
if DIS.DIS_CtlType=4 { if DIS.DIS_hwndItem=hwndODB {
以下の処理はコントロールに描画するための準備ですが裏技的な方法なので説明しません。
selwndOld=ginfo(3) gsel 1, 0 mref BMSCR, 67 hdcOld=BMSCR(4) BMSCR(4)=DIS.DIS_hDC
描画を行います。
DIS.DIS_rcItem0(1,2,3) には描画する必要がある範囲の左上の点の X 座標、Y 座標、
右下の点の X 座標、Y 座標がそれぞれ入っています。
この範囲の外には描画しないように注意してください。
今回はまず範囲全体を赤で塗りつぶして、さらにその上から青の楕円を描いています。
このサンプルプログラムの方法では一部の描画命令では描画できないようです。
x1=DIS.DIS_rcItem0 y1=DIS.DIS_rcItem1 x2=DIS.DIS_rcItem2 y2=DIS.DIS_rcItem3 color 255, 0, 0 boxf x1, y1, x2, y2 color 0, 0, 255 circle x1, y1, x2, y2, 1
描画後の後処理とサブルーチンの終わりです。
BMSCR(4)=hdcOld gsel selwndOld, 0 } } return
以上でサンプルプログラムの完成です。