- PR -

Controlの継承について

投稿者投稿内容
manabu
会議室デビュー日: 2005/09/16
投稿数: 5
投稿日時: 2005-09-16 09:35
Controlクラスを継承して、カスタムコントロールを作っています。
BorderStyleを実装したいのですが、クライアント領域の原点を変更できません。

UpDateBoundsメソッドを使って、コントロール領域とクライアント領域のサイズを
それぞれ設定する事はできたのですが、クライアント領域の原点が変わらないため
描画する際にBorderに被ってしまいます。

OnPaintなどで得られるGrapicsをワールド変換しても
メソッドを抜けた後は戻ってしまいます。

何か解決できる方法はありますでしょうか。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-09-16 09:53
こんにちは、じゃんぬ です。

引用:

manabuさんの書き込み (2005-09-16 09:35) より:

OnPaintなどで得られるGrapicsをワールド変換しても
メソッドを抜けた後は戻ってしまいます。


ん?
OnPaint メソッドで ControlPaint.DrawBorder メソッドを使ったのですよね?
WndProc をオーバライドして、WM_PAINT をキャッチして、
OnPaint を明示的に呼び出していますか?


_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
manabu
会議室デビュー日: 2005/09/16
投稿数: 5
投稿日時: 2005-09-16 10:25
引用:


WndProc をオーバライドして、WM_PAINT をキャッチして、
OnPaint を明示的に呼び出していますか?




OnPaintはオーバーライドしました。

OnPaint内だけでなく、CreateGraficsなどを呼んだ時にも
原点位置の修正を適用したいのですが、WndProcのオーバーライドで
可能でしょうか?

標準のコントロール(Panelなど)ではできているようなのですが。
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2005-09-16 11:42
こんにちわ。

http://www.microsoft.com/japan/msdn/net/general/win32map.asp
こんなの見つけました。
参考になるかもしれません。
ya
大ベテラン
会議室デビュー日: 2002/05/03
投稿数: 212
投稿日時: 2005-09-16 15:41
BorderStyleプロパティはWin32のWindow Styleによって実現します。
まじめに説明すると長くなるのでコードで。

コード:

public class MyControl : System.Windows.Forms.Control {
	public MyControl() {
	}

	private const int WS_BORDER        = 0x00800000;
	private const int WS_EX_CLIENTEDGE = 0x00000200;
	protected override CreateParams CreateParams {
		get {
			CreateParams p = base.CreateParams;
			switch(this.BorderStyle) {
				case BorderStyle.FixedSingle : {
					p.Style |= WS_BORDER;
				} break;
				case BorderStyle.Fixed3D : {
					p.ExStyle |= WS_EX_CLIENTEDGE;
				} break;
			}
			return p;
		}
	}

	private BorderStyle borderStyle = BorderStyle.None;
	public BorderStyle BorderStyle {
		get {
			return this.borderStyle;
		}
		set {
			this.borderStyle = value;
			this.UpdateStyles();
		}
	}
}



まず、BorderStyleを実現するにはWindowStyleを設定しないといけないので
CreateParamsをオーバーライドします。そして、自分の状態に合わせた設定
をするコードを書きます。
次に状態変更ですが、Win32だとSetWindowLongPtrあたりでやるんですが、
これに相当するのはControl.UpdateStyles()メソッドです。
なのでBorderStyleのセッタでこれを呼び出してあげます(するとCreateParams
が再び呼ばれそれがSetWindowLongPtrされます)。

たぶんこれでお悩みは解決…するはずですが。
manabu
会議室デビュー日: 2005/09/16
投稿数: 5
投稿日時: 2005-09-16 17:44
ありがとうございます。
BorderStyleの実装できました。

さらに、スクロールバーをコントロールに追加したいのですが
Win32のWS_VSCROLL,WS_HSCROLLを使って、表示する事はできるのですが、
表示されたスクロールバーのMax,Minの設定、スクロールイベントの取得は
どうしたらいいのでしょうか?

続けて質問すみませんが、よろしくお願いします。
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2005-09-16 18:24
>Win32のWS_VSCROLL,WS_HSCROLLを使って、表示する事はできるのですが、

これをやったら、WndProc で取るしかないのでは?(完全に推測)
ya
大ベテラン
会議室デビュー日: 2002/05/03
投稿数: 212
投稿日時: 2005-09-16 19:09
引用:


さらに、スクロールバーをコントロールに追加したいのですが
Win32のWS_VSCROLL,WS_HSCROLLを使って、表示する事はできるのですが、
表示されたスクロールバーのMax,Minの設定、スクロールイベントの取得は
どうしたらいいのでしょうか?



それらをAPI(SetScrollInfoとかScrollWindowExとかをWM_VSCROLLメッセージにあわせてね)を使って直接Controlに実装することも可能です(実際の手順はほとんどWin32のスクロール関係の知識があればわかる=その手のWeb上の資料を当たればわかる…猫でもわかるとか)が、WinFormsはその手の機能を実装したコントロール、ScrollableControlがすでにあるのでそっちから継承しましょう。

http://www.atmarkit.co.jp/fdotnet/practprog/wisearch02/wisearch02_01.html
@ITにちょうどいい記事があったのでリンクを張っておきます。基本的にはこの手順が一番いいでしょう。

# っていうか、BorderStyle&ScrollableなコントロールってPanelが適任ですから
# これから継承すればいいのでは?
# いや、自分で実装すればWinFormsに対する理解は深まるので無駄ではないですけど

スキルアップ/キャリアアップ(JOB@IT)