DOBON.NET DOBON.NETプログラミング掲示板過去ログ

フォーム移動を知る方法につきまして

環境/言語:[WindowsXP]
分類:[VB6以前]

2010/04/22(Thu) 17:24:43 編集(投稿者)

お世話になります。
フォームサイズの変化はリサイズにより知る事はできますが、
Private Sub Form_Resize()
   ・
   ・
End Sub
フォームのサイズはそのままでフォーム移動されたかを知る方法はありますでしょうか。
よろしくお願いします。

言語:VB6.0
LocationChanged イベントでしょうか?
■No26744に返信(AKIさんの記事)
> フォームのサイズはそのままでフォーム移動されたかを知る方法はありますでしょうか。

イベントとしては用意されていませんが、フォームをサブクラス化して
WM_MOVE メッセージを拾う事で知ることができます。

# WM_SIZE も見た方が良いかも。
Hongliangさん

投稿下さいましてお礼を申し上げます。

>LocationChanged イベントでしょうか?
はい、
LocationChanged イベントをWebで調べましたらNET Framework使用で
ウィンドウの位置が変更されたときに発生しますとありました。
言語はVB6ですので使用できないみたいです。

ありがとうございました。
魔界の仮面弁士さん

投稿下さいましてお礼を申し上げます。

>フォームをサブクラス化してWM_MOVE メッセージを拾う事で知ることができます。
はい、
WM_MOVE、WM_SIZEを調べて行って見ます。

ありがとうございました。
お世話になります。

魔界の仮面弁士さんより、ご指導してもらいました
>イベントとしては用意されていませんが、フォームをサブクラス化して
>WM_MOVE メッセージを拾う事で知ることができます。

下記のWebにサブクラス化の記述がありました。
Fromをサブクラス化して WM_MOVEメッセージを捕まえてみましょう
http://questionbox.jp.msn.com/qa4620863.html


一点、変更いたしました。

変更前   Const GWL_WNDPROC = (-4)

変更後   Public Const GWL_WNDPROC = (-4)

フォームの移動後、即
Left,Top情報「MsgBox x - nLeft & " - " & y - nTop」
になります。

以下のように変更できればと思っています。

フォームの移動終了後(クリックをはなした時に)
Left,Top情報「MsgBox x - nLeft & " - " & y - nTop」
ができればと思っています。
ご指導を願えますと幸いです。
追記
クリックをはなした時等などの記述がありました。

http://www.winapi-database.com/tips/25/index.html

もし解決できましたら改めてご報告致します。
システムメニューから移動を選択される可能性もあるので
クリックだけでは判断できないと思います。

サブクラス化までできているようなので
WM_EXITSIZEMOVE で判断してみてはいかがでしょうか。
ここのサイトでも説明されてました。
http://dobon.net/vb/dotnet/form/exitmove.html
subaru さん

投稿下さいましてお礼を申し上げます。

ご指導及び情報提供下さいましてありがとうございました。
>http://dobon.net/vb/dotnet/form/exitmove.html




皆様方へ

アドバイス、ご指導により解決することができるようになりました。
心より感謝を申し上げます。本当にありがとうございました。




ウインドウ移動(WM_MOVE)からHitTestに変更しました。

変更前  Public Const WM_MOVE = &H3 'ウインドウが移動した

変更後  Public Const HitTest = &H84 '非クライアント領域のどの部分でマウスが操作されたか調べる



参考

追加   Form1.Text1 , Form1.Text2

'
--------------------------------------------------------------------
'
Private Sub Form_Load()

lpfnProc = SetWindowLong(Me.hWnd, GWL_WNDPROC, AddressOf myProc)

End Sub


'標準モジュール

Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" _
(ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, _
ByVal Msg As Long, ByVal wParam As Long, _
ByVal lParam As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Const GWL_WNDPROC = (-4)
Public Const WM_MOVE = &H3 'ウインドウが移動した

Public Const HitTest = &H84 '非クライアント領域のどの部分でマウスが操作されたか調べる

Public lpfnProc As Long
Public Declare Function GetAsyncKeyState Lib "user32.dll" (ByVal vKey As Long) As Long

Public Declare Function GetWindowRect Lib "user32" (ByVal hWnd As Long, lpRect As RECT) As Long

Public Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type

Public Function myProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As _
Long, ByVal lParam As Long) As Long
If uMsg = HitTest Then
If GetAsyncKeyState(vbKeyLButton) = 0 Then

Form1.Text1 = "停止"

Dim nRect As RECT
Call GetWindowRect(Form1.hWnd, nRect)

Form1.Text2 = nRect.Left & " - " & nRect.Top

Else


Form1.Text1 = "移動中"


End If


End If

myProc = CallWindowProc(lpfnProc, hWnd, uMsg, wParam, lParam)
End Function




'
--------------------------------------------------------------------
'
解決済み!
■No26760に返信(AKIさんの記事)
> ウインドウ移動(WM_MOVE)からHitTestに変更しました。

WM_NCHITTEST + GetAsyncKeyState だけで検出しているようですが、
それだと、マウスカーソルが重なった時にしか判定されません。

WM_MOVE 等も処理しておかないと、マウスを使わない移動…たとえば、
Move メソッドや Left/Topプロパティによるプログラムからの移動を
検出できないことになります。

また、ユーザーからの操作にしても、[Alt]+[Space] , [M] のキー操作時や、
タスクバー/タイトルバーの右クリックで[移動]を選んだ場合などから
カーソルキーで移動させた場合に、移動が検出できなくなってしまいますよ。
魔界の仮面弁士 さん

投稿下さいましてお礼を申し上げます。

下記のご指摘
>マウスカーソルが重なった時にしか判定されません。
>Move メソッドや Left/Topプロパティによるプログラムからの移動を検出できないことになります。
>カーソルキーで移動させた場合に移動が検出できなくなってしまいます。

は、問題発生する恐れを事前に防止することができました。
大変貴重な情報提供を下さいまして本当にありがとうございました。


下記の方法に改めました。

参考

HitTestからウインドウ移動(WM_MOVE)に変更しました。

追加   Form1.Text1

'
'--------------------------------------------------------------------
'

Private Sub Form_Load()

lpfnProc = SetWindowLong(Me.hWnd, GWL_WNDPROC, AddressOf myProc)

End Sub


'標準モジュール

Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" _
(ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, _
ByVal Msg As Long, ByVal wParam As Long, _
ByVal lParam As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Public Const GWL_WNDPROC = (-4)
Public Const WM_MOVE = &H3 'ウインドウが移動した
Public lpfnProc As Long
Public Declare Function GetWindowRect Lib "user32" (ByVal hWnd As Long, lpRect As RECT) As Long

Public Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type

Public Function myProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As _
Long, ByVal lParam As Long) As Long

If uMsg = WM_MOVE Then     'ウインドウが移動した

Dim nRect As RECT
Call GetWindowRect(Form1.hWnd, nRect)

Form1.Text1 = nRect.Left & " - " & nRect.Top

End If

myProc = CallWindowProc(lpfnProc, hWnd, uMsg, wParam, lParam)
End Function



'
'--------------------------------------------------------------------
'
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板