hinekure.net が http://hspdev-wiki.net/ から自動クローリングした結果を表示しています。画像やリソースなどのリンクが切れています。予めご了承ください。
OwnerDraw/ODButton - HSP開発wiki
トップ    編集凍結 差分バックアップ添付複製名前変更リロード   新規一覧単語検索最終更新   最終更新のRSS

小ワザ

オーナードローボタン

オーナードローボタンを作成してみましょう。

作成する(HSP3)

[hsp3]

サンプルプログラムを作りながら説明していきます。
オーナードローについての基本的な流れにそってやってみましょう。
今回はほとんどを HSP3 の基本命令で作っています。

(注意)今回はコントロールへ描画するのに裏技的な方法を使っています。
うかつに使うと危険なのでサンプルプログラムでの使用に留めてください。

1 : 対象のコントロールをオーナードロー状態にする

今回はオーナードローボタンを作るので 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

2 : 必要な設定を行う

オーナードローボタンの場合はここで設定することはありません。

3 : 描画を行うタイミングを待つ

HSP3 でウィンドウメッセージが送られてきたら何かを行うという処理をする場合は oncmd 命令を使います。

オーナードローボタンを描き換える必要があるときは WM_DRAWITEM メッセージが送られてきます。
このメッセージがきたらサブルーチンに跳んでボタンの描画を行います。

	#define WM_DRAWITEM 0x002B
	oncmd gosub *draw_ownerdrawbutton, WM_DRAWITEM


メインルーチンの残りとボタンを押したときの処理をします。
今回はボタンを押すとダイアログを表示するだけです。

	stop
*futubutton
	dialog "普通のボタンが押されました。"
	stop
*ownerdrawbutton
	dialog "オーナードローボタンが押されました。"
	stop

4 : コントロールを描画する

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

以上でサンプルプログラムの完成です。

naznyark --2006-01-08 (日) 00:26:19

改良する(まだ書いていません)

コメント

  • 続きはまた今度。 -- naznyark? 2006-01-08 (日) 00:27:05
  • カスタムボタンがあったのでボタンはどうしようと思っていましたが、いいですね。
    カスタムボタンで行っているオーナードローの解説的で^^
    あとデバイスコンテキストですが「出来るのかなぁ」と思ってやらずにいたものが「やってもいい」みたいで^^ -- kz3 2006-01-08 (日) 08:42:26

URL B I U SIZE Black Maroon Green Olive Navy Purple Teal Gray Silver Red Lime Yellow Blue Fuchsia Aqua White

トップ    編集凍結 差分バックアップ添付複製名前変更リロード   新規一覧単語検索最終更新   最終更新のRSS
Last-modified: 2007-04-25 (水) 08:12:20 (2419d)