ab.com コミュニティ

ActiveBasicを通したコミュニケーション
現在時刻 - 2024年3月29日(金) 01:58

全ての表示時間は UTC+09:00 です




新しいトピックを投稿する  トピックへ返信する  [ 3 件の記事 ] 
作成者 メッセージ
投稿記事Posted: 2011年5月21日(土) 13:57 
Ver 4.24.00を使用
MainWndに配置したStatic、EditBox、CommandButtonなどに、マウスポインタが行った(クリックなどせずに、ただその領域内へ移動するだけ)時に其々の説明を例えばステ-タスバ-2に表示させたいのですが、
MainWnd_Create時に、
コード:
GetClientRect(hStatic1, Static1_rc)
などで、其々のRECT座標を取得しておき、MainWnd_MouseMoveイベントで、
コード:
GetCursorPos(PointerPos)

で、PointerPosを取得し、If条件文で(MainWnd_PosはMainWnd_Moveイベントで取得済み)
コード:
	If PointerPos.x >=MainWnd_Pos.x+30 and PointerPos.x <=MainWnd_Pos.x+30+Static1_rc.right _
		and PointerPos.y >=MainWnd_Pos.y+15 and PointerPos.y <=MainWnd_Pos.y+15+Static1_rc.bottom _
		Then
		wsprintf(buffer, "Static1の説明")
	ElseIf PointerPos.x >=MainWnd_Pos.x+18 and PointerPos.x <=MainWnd_Pos.x+24+EditBox1_rc.right _
		and PointerPos.y >=MainWnd_Pos.y+58 and PointerPos.y <=MainWnd_Pos.y+64+EditBox1_rc.bottom _
		Then
		wsprintf(buffer, "EditBox1の説明")
	ElseIf PointerPos.x >=MainWnd_Pos.x+478 and PointerPos.x <=MainWnd_Pos.x+481+CommandButton1_rc.right _
		and PointerPos.y >=MainWnd_Pos.y+18 and PointerPos.y <=MainWnd_Pos.y+21+CommandButton1_rc.bottom _
		Then
		wsprintf(buffer, "CommandButton1の説明")
	Else
		wsprintf(buffer, "")
	End If
とbufferに其々の説明文を入れて、
(EditBox1はX=20、Y=60にあり、CommandButton1はX=480、Y=20にある場合で、其々の領域より少し大きくしないとダメなので端数にしている)
コード:
SendMessage(hStatusWnd, SB_SETTEXT, 2, buffer)
でステ-タスバ-2に表示させます。
また
コード:
wsprintf(buffer, "Pointer Pos: x%d, y%d", PointerPos.x, PointerPos.y)
	SetWindowText(hEditBox2, buffer)
でPointerPos.xとPointerPos.yをEditBox2へ表示するようにしておきます。

マウスをゆっくりと動かすとステ-タスバ-2、EditBox2とも期待通りに表示されるので、プログラムは正常に動いていると思うのですが、マウスを少し速く移動させてEditBoxやCommandButtonに持っていくとStatic1以外は、EditBoxではポインタが"I"表示に変化したりして(CommandButtonでもOSが何かを掴むのか)、GetCursorPos(PointerPos)の位置取得が遅れて取りこぼしが出て、PointerPosが正確にEditBox2に表示しなくなり、If条件文に合わなくなってステ-タスバ-2にも表示しません。
(ポインタの移動速度や加速度は関係ありませんでした)

(1)マウスを速く移動させても位置取得遅れが出ない方法は?
(2)Static以外のEditBoxやCommandButtonなどでは、その領域にポインタが入るとPointerPos表示が止まり値が変化しません。
これらの領域に入っても位置を入手する方法は?
(3)ステ-タスバ-0、ステ-タスバ-1にポインタが行ってもその説明文をステ-タスバ-2へ出したいのですが、現状ではステ-タスバ-やタイトルバ-へ行くともう位置を入手しません。(ステ-タスバ-の作成はHelpにCreateStatusWindowの記述がないので、Win32プログラミング講座のStep21、22に倣った)
これらの領域に入っても位置を入手する方法は?
(4)GetCursorPos()以外でよい方法はありませんか?


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2011年5月25日(水) 00:57 
質問すべてを解決するには
MainWnd_MouseMoveで処理させず、スレッドでGetCursorPos()させればよい。

Createイベントで
CreateThread(ByVal NULL , 0, AddressOf(cap) , 0 , 0 , ID)
などとやりスレッド関数を転がせばおk
Sub cap()
Dim po As POINTAPI
Dim hWnd As HWND
Dim ttl[200] As Byte
While 1
GetCursorPos(po)
hWnd = WindowFromPoint(po.x , po.y)
If hWnd <> 0 Then
GetWindowText(hWnd , ttl , 200)
SetWindowText(GetDlgItem(hMainWnd , Static1) , ttl)

If GetAsyncKeyState(Asc("X")) and &H8000 Then
PostMessage(hWnd , WM_CLOSE , 0 , 0)
End If
End If
Sleep(20)
Wend
End Sub


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2011年6月12日(日) 13:31 
教えて頂いたCODEでは動きませんでしたが、スレッド関数なるものを調べて以下の内容で出来ました。
これで「これは何々、左クリックなら何々、右クリックなら何々が出来る etc.」等のヒント文(簡単なヘルプみたいなもの)が出せます。
ありがとうございます。

MainWnd_Createイベントで各コントロ-ルのハンドルを取得、
コード:
	hcap =CreateThread(ByVal NULL, 0, AddressOf(cap), 0, 0, VarPtr(ThreadID))
として、MainWnd_MoveやMainWnd_ResizeイベントでMainWndのRECT座標を取得、MainWnd_ActivateイベントでActivateFlag変数を決めて、 各ハンドル(・RECT変数)やStatusbar_Sizes[3]をグローバル変数にして、
コード:
Function cap(ThreadID As DWord) As DWord	'ThreadIDは引数なので他の変数名でもOK
	Dim buffer[255] As Byte
	Dim po As POINTAPI
	Dim hWnd As HWND
	Dim ComboBox1_rc As RECT		'スレッド処理以外でも使う場合はグローバル変数へ
	Dim GroupBox1_rc As RECT		'同上

	While 1
		If ActivateFlag =1 Then		'ウィンドウがアクティブならスレッド処理
			GetCursorPos(po)

			If po.x >=MainWnd_rc.left and po.x <=MainWnd_rc.right _
				and po.y >=MainWnd_rc.top and po.y <=MainWnd_rc.bottom _
				Then
				hWnd =WindowFromPoint(po.x, po.y)
				GetWindowRect(hComboBox1, ComboBox1_rc)		'ComboBox1 Hint文の為
				GetWindowRect(hGroupBox1, GroupBox1_rc)		'GroupBox1 Hint文の為

				If hWnd =hStatic1 Then
					lstrcpy(buffer, "Hint文 Static1")
				Else If hWnd =hEditBox1 Then
					lstrcpy(buffer, "Hint文 EditBox1")
				Else If hWnd =hEditBox2 Then
					lstrcpy(buffer, "Hint文 EditBox2")
				Else If hWnd =hCommandButton1 Then
					lstrcpy(buffer, "Hint文 CommandButton1")
'				Else If hWnd =hComboBox1 Then					'これはNG
				Else If po.x >=ComboBox1_rc.left and po.x <=ComboBox1_rc.right _
					and po.y >=ComboBox1_rc.top and po.y <=ComboBox1_rc.bottom _
					Then
					lstrcpy(buffer, "Hint文 ComboBox1")
				Else If hWnd =hStatusWnd and po.x <=MainWnd_rc.left+Statusbar_Sizes[0]+2 _
					Then							'+2や+6は微調整量(各自の好み)
					lstrcpy(buffer, "Hint文 Statusbar0")
				Else If hWnd =hStatusWnd and po.x >MainWnd_rc.left+Statusbar_Sizes[0]+6 _
					and po.x <=MainWnd_rc.left+Statusbar_Sizes[1]+2 _
					Then
					lstrcpy(buffer, "Hint文 Statusbar1")
				Else If hWnd =hStatusWnd and po.x >MainWnd_rc.left+Statusbar_Sizes[1]+6 _
					and po.x <=MainWnd_rc.left+Statusbar_Sizes[2]+2 _
					Then
					lstrcpy(buffer, "Hint文 Statusbar2")
				Else If hWnd =hStatusWnd and po.x >MainWnd_rc.left+Statusbar_Sizes[2]+6 _
					and po.x <=MainWnd_rc.left+Statusbar_Sizes[3] _
					Then
					lstrcpy(buffer, "Hint文 Statusbar3")
				Else If po.x >=GroupBox1_rc.left and po.x <=GroupBox1_rc.right _
					and po.y >=GroupBox1_rc.top and po.y <=GroupBox1_rc.bottom _
					Then
					lstrcpy(buffer, "Hint文 GroupBox1")
				Else
					lstrcpy(buffer, "")
				End If
			Else						'Statusbar2の表示が空にならない事があるので必要
				lstrcpy(buffer, "")
			End If
		SendMessage(hStatusWnd, SB_SETTEXT, 2, buffer)
		Sleep(20)						'ポインタが行ってから変化するまでの時間
		End If
	Wend
	'スレッドハンドルを閉じてメモリ解放
	CloseHandle(hcap)
End Function
ところで、マウスポインタがステ-タスバ-(この場合 Statusbar0~Statusbar3、で例えばStatusbar1)の所にあって、其々の場所でクリック(左とか右とか)したら何か処理をさせたいのですが、例えば左クリックで、
SetWindowText(hEditBox3, "Statusbar1で左クリックした")
でEditBox3に文字を表示させたい時はどんな方法、ソ-スコ-ドにしたらよいのでしょうか?


通報する
ページトップ
   
期間内表示:  ソート  
新しいトピックを投稿する  トピックへ返信する  [ 3 件の記事 ] 

全ての表示時間は UTC+09:00 です


オンラインデータ

このフォーラムを閲覧中のユーザー: Ahrefs [Bot] & ゲスト[21人]


トピック投稿:  可
返信投稿:  可
記事編集: 不可
記事削除: 不可
ファイル添付: 不可

検索:
ページ移動:  
Powered by phpBB® Forum Software © phpBB Limited
Japanese translation principally by ocean