- れい
- ぬし
- 会議室デビュー日: 2005/11/01
- 投稿数: 346
|
投稿日時: 2007-06-09 22:20
ALTによるボーダーの切り替え、移動、サイズ変更の最小コードです。
ついでにフォームをクリックすると移動できるようにしてあります。
メニューはMainMenuコントロールを使わないとだめです。
コード: |
|
Public Class Form1
Private Const WM_NCHITTEST As Integer = &H84
Private Const HTERROR = (-2)
Private Const HTTRANSPARENT = (-1)
Private Const HTNOWHERE = 0
Private Const HTCLIENT = 1
Private Const HTCAPTION = 2
Private Const HTSYSMENU = 3
Private Const HTGROWBOX = 4
Private Const HTSIZE = HTGROWBOX
Private Const HTMENU = 5
Private Const HTHSCROLL = 6
Private Const HTVSCROLL = 7
Private Const HTMINBUTTON = 8
Private Const HTMAXBUTTON = 9
Private Const HTLEFT = 10
Private Const HTRIGHT = 11
Private Const HTTOP = 12
Private Const HTTOPLEFT = 13
Private Const HTTOPRIGHT = 14
Private Const HTBOTTOM = 15
Private Const HTBOTTOMLEFT = 16
Private Const HTBOTTOMRIGHT = 17
Private Const HTBORDER = 18
Private Const HTREDUCE = HTMINBUTTON
Private Const HTZOOM = HTMAXBUTTON
Private Const HTSIZEFIRST = HTLEFT
Private Const HTSIZELAST = HTBOTTOMRIGHT
Public Property ClientRectangleOnly() As Boolean
Get
Return Me.Region IsNot Nothing
End Get
Set(ByVal value As Boolean)
If value = Me.ClientRectangleOnly Then Exit Property
If Me.Region Is Nothing Then
Dim r As Rectangle
r.X = Me.PointToScreen(Me.ClientRectangle.Location).X - Me.Left
r.Y = Me.PointToScreen(Me.ClientRectangle.Location).Y - Me.Top
r.Width = Me.ClientRectangle.Width
r.Height = Me.ClientRectangle.Height
Me.Region = New Region(r)
Else
Me.Region = Nothing
End If
End Set
End Property
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Select Case m.Msg
Case WM_NCHITTEST
Dim p As Point
p = Me.PointToClient(New Point(m.LParam.ToInt32 Mod 65536, m.LParam.ToInt32 \\ 65536))
If p.X > Me.ClientRectangle.Right Then Exit Select
If p.X < Me.ClientRectangle.Left Then Exit Select
If p.Y < Me.ClientRectangle.Top Then Exit Select
If p.Y > Me.ClientRectangle.Bottom Then Exit Select
If p.X < Me.ClientRectangle.Left + 5 Then
If p.Y < Me.ClientRectangle.Top + 5 Then
m.Result = HTTOPLEFT
Exit Sub
End If
If p.Y > Me.ClientRectangle.Bottom - 5 Then
m.Result = HTBOTTOMLEFT
Exit Sub
End If
m.Result = HTLEFT
Exit Sub
End If
If p.X > Me.ClientRectangle.Right - 5 Then
If p.Y < Me.ClientRectangle.Top + 5 Then
m.Result = HTTOPRIGHT
Exit Sub
End If
If p.Y > Me.ClientRectangle.Bottom - 5 Then
m.Result = HTBOTTOMRIGHT
Exit Sub
End If
m.Result = HTRIGHT
Exit Sub
End If
If p.Y < Me.ClientRectangle.Top + 5 Then
m.Result = HTTOP
Exit Sub
End If
If p.Y > Me.ClientRectangle.Bottom - 5 Then
m.Result = HTBOTTOM
Exit Sub
End If
m.Result = HTCAPTION
Exit Sub
End Select
MyBase.WndProc(m)
End Sub
Private Sub Form1_ClientSizeChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.ClientSizeChanged
If Me.ClientRectangleOnly Then
Dim r As Rectangle
r.X = Me.PointToScreen(Me.ClientRectangle.Location).X - Me.Left
r.Y = Me.PointToScreen(Me.ClientRectangle.Location).Y - Me.Top
r.Width = Me.ClientRectangle.Width
r.Height = Me.ClientRectangle.Height
Me.Region = New Region(r)
End If
End Sub
Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
If e.Alt Then
If Me.ClientRectangleOnly Then
Me.ClientRectangleOnly = False
Else
Me.ClientRectangleOnly = True
End If
e.Handled = True
End If
End Sub
End Class
|
|
- extream
- ベテラン
- 会議室デビュー日: 2005/12/26
- 投稿数: 83
|
投稿日時: 2007-06-10 14:11
れいさん、いつも丁寧な回答ありがとうございます。
いろいろアルゴリズムを教えていただき、本当に感謝しますm(__)m
私は、まだUI系のロジックはあまり組んだことがなく、ノウハウが少ないので非常に助かります。
では、まず一通り組んでから、どのような処理を行っているのかを追ってみます。
コード例の提示ありがとうございました m(__)m
|
- extream
- ベテラン
- 会議室デビュー日: 2005/12/26
- 投稿数: 83
|
投稿日時: 2007-06-10 16:47
れいさんに教えていただいたソースをC#に変換して実装したところ、期待どおりの動作を行っていることを確認できました。
ありがとうございます m(__)m
Windowメッセージは今まで触ったことがほとんどないので教えていただきたい点があります。
教えていただいたコードでは、クライアント領域に関しては期待とおりの動作ができるのですが、ラベルコントロールなどで動作させることができません。
現在作成しているフォームの外周に画像を貼っています。
(たとえば、左端(0,0)の位置からSize(10,Form.Height)のラベル)
このコントロール上でも、実際にフォームを操作しているようにしたいのです。
(フォーム内のすべてのコントロールではないです。)
これは、WndProc関数のCase文を増やすだけで対応できるのでしょうか?
ただ、ラベルコントロール上にマウスが来た時の
・Forms.Message.Msg
を調べようとしたのですが、デバッグすると常にWndProc関数が呼ばれてしまうので確認できませんでした。
指定したコントロール上でも、フォームと同じ動作を行うようにする手段はあるのでしょうか?
もしくは、そのようなことはできないのでしょうか?
|
- れい
- ぬし
- 会議室デビュー日: 2005/11/01
- 投稿数: 346
|
投稿日時: 2007-06-11 09:22
引用: |
|
教えていただいたコードでは、クライアント領域に関しては期待とおりの動作ができるのですが、ラベルコントロールなどで動作させることができません。
|
なにがどう動作しないのかがわかりません。
引用: |
|
現在作成しているフォームの外周に画像を貼っています。
(たとえば、左端(0,0)の位置からSize(10,Form.Height)のラベル)
|
画像を貼るのにラベルとは変わっていますね
引用: |
|
このコントロール上でも、実際にフォームを操作しているようにしたいのです。
(フォーム内のすべてのコントロールではないです。)
これは、WndProc関数のCase文を増やすだけで対応できるのでしょうか?
|
?
操作透過ということかな?
引用: |
|
ただ、ラベルコントロール上にマウスが来た時の
・Forms.Message.Msg
を調べようとしたのですが、デバッグすると常にWndProc関数が呼ばれてしまうので確認できませんでした。
|
WndProcやPaintイベント、DragDropなどのデバッグは工夫が入りますよ。
Debug.WriteLineなどを使いましょう。
引用: |
|
指定したコントロール上でも、フォームと同じ動作を行うようにする手段はあるのでしょうか?
|
なにがしたいのかよくわかりませんが…
フォームと同じ動作ってなんでしょう?
コントールのクライアント領域の大きさを変えたいのですか?
コントロールが無いときと同じ動作にしたいのですか?
どちらにしろ、先ほどのコードを見ればわかりますが、
コントロールのサイズ変更したいときには
そのコントロールのWndProcでHTTOPやHTRIGHTなどを返せばいいんです。
どういった順番でWndProcが呼ばれるのかは
MSDNを見たり自分で調べたりしましょう。
|
- extream
- ベテラン
- 会議室デビュー日: 2005/12/26
- 投稿数: 83
|
投稿日時: 2007-06-11 09:53
れいさん、いつも丁寧な回答ありがとうございます。
>画像を貼るのにラベルとは変わっていますね
ピクチャボックスと間違えました。
説明下手ですいません。
やりたい事は、
・フォームの外周にピクチャボックスを配置した場合、教えていただいた
コードではフォームサイズを変更できなかったので、フォーム外周に
コントロールを配置しても、フォームサイズを変更できるようにしたい。
です。
れいさんのコメントに調べるにあたりヒントとなるキーワードが多々ありましたので、まず調べてみます。
|
- extream
- ベテラン
- 会議室デビュー日: 2005/12/26
- 投稿数: 83
|
投稿日時: 2007-06-13 10:02
みなさん、回答ありがとうございます。
現在調査中なのですが、
・WndProc
では、フォーム上(コントロールを除く)のイベントでしかコールされないものですよね?
れいさんのコメントの中に、
「コントロールのWndProcでHTTOPやHTRIGHTなどを返せばいいんです」
とあるのを見落としていたのですが、これはユーザコントロールを作成して、そのコントロール内でWndProcをオーバーライドすればよいのでしょうか?
それとも、わざわざユーザコントロールを作成しなくても、各コントロールのWndProcをオーバーライドできるものなのでしょうか?
ご存知の方いたら教えてください。
よろしくお願いします。
|
- ぶさいくろう
- ぬし
- 会議室デビュー日: 2005/11/22
- 投稿数: 1232
- お住まい・勤務地: 川崎市(は俺も含めてロクな人間が住んでないよw)
|
投稿日時: 2007-06-13 11:55
継承コントロールを作ってオーバーライドすればよし。
|
- extream
- ベテラン
- 会議室デビュー日: 2005/12/26
- 投稿数: 83
|
投稿日時: 2007-06-13 13:52
ぶさいくろうさん、回答ありがとうございます。
「継承コントロール」で検索し、オーバーライドの方法がわかりました。
ありがとうございます。
テストPGを作成し、デバッグしている時に気づいたことがあります。
コントロールのWndProcをオーバーライドすることで、コントロール上にマウスが来たかどうかはわかるようになりました。
しかし、そのタイミングで
・HTRIGHT
・HTLEFT
を返してもマウスが「⇔」に変わりますが、フォームのサイズが変更しませんでした。
(フォーム右端に配置したコントロールの場合、フォームの外側にマウスを移動することができませんでした。)
また、コントロールのサイズも変更しませんでした。
コントロールのWndProcでイベントを取得し、アイコンを「⇔」に変え、フォームのサイズを変える事はできないのでしょうか?(フォームのWndProcを呼び出す?)
やりたい事は、以下です。
・下記のようにフォームの右端にピクチャボックスを配置する。
・ピクチャボックス上にマウスが来た場合に、フォームの横サイズを変更する
┌──────┐
| ■|
| ■|
| ■|
| ■|
└──────┘
質問ばかりですいません。。。
よろしくお願いしますm(__)m
|