VB6で別のVB6プログラムのSliderを操作したい への返答
投稿で使用できる特殊コードの説明。(別タブで開きます。)
以下の返答は逆順(新しい順)に並んでいます。
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2021/2/10 11:15:52
> Call SendMessage(lngBtnWnd1, TBM_SETPOS, 1&, ByVal 5)
今回は、API 宣言を ByRef lParam As Any にしているようなので、
実際には ByVal 5 ではなく、ByVal 5& と記述するべきですね。
(実際には固定値ではなく、Long 型変数を指定されるのだと思いますが)
今回は、API 宣言を ByRef lParam As Any にしているようなので、
実際には ByVal 5 ではなく、ByVal 5& と記述するべきですね。
(実際には固定値ではなく、Long 型変数を指定されるのだと思いますが)
WPARAM 型 … Win16 では 16bit長、Win32 では 32bit長、Win64 では 64bit長
LPARAM 型 … Win16 では 32bit長、Win32 では 32bit長、Win64 では 64bit長
LPARAM 型 … Win16 では 32bit長、Win32 では 32bit長、Win64 では 64bit長
投稿者 ひでぽん  (社会人)
投稿日時
2021/2/10 10:27:57
魔界の仮面弁士さま
回答ありがとうございます。
>FormA と FormB が共に自作なら、プロセス間通信のために
>DDE を使うという選択肢もあります。
DDEについては共に変更可能なので試してみようと思います。
後SendMessageの方もご教示頂きました方法で動作確認できました。これでとりあえず行けそうです。
ご教示ありがとうございました。
以下に修正したソースのせておきます。
Private Const TBM_SETPOS As Long = &H405&
'FormA.exeのSlider1を操作
Private Sub Command2_Click()
Dim lngWindWnd As Long
Dim lngBtnWnd1 As Long
lngWindWnd = FindWindow(vbNullString, "FormA")
lngBtnWnd1 = FindWindowEx(lngWindWnd, 0, "Slider20WndClass", vbNullString)
Call SendMessage(lngBtnWnd1, TBM_SETPOS, 1&, ByVal 5)
End Sub
解決しましたのでこれで完了とさせて頂きます。
回答ありがとうございます。
>FormA と FormB が共に自作なら、プロセス間通信のために
>DDE を使うという選択肢もあります。
DDEについては共に変更可能なので試してみようと思います。
後SendMessageの方もご教示頂きました方法で動作確認できました。これでとりあえず行けそうです。
ご教示ありがとうございました。
以下に修正したソースのせておきます。
Private Const TBM_SETPOS As Long = &H405&
'FormA.exeのSlider1を操作
Private Sub Command2_Click()
Dim lngWindWnd As Long
Dim lngBtnWnd1 As Long
lngWindWnd = FindWindow(vbNullString, "FormA")
lngBtnWnd1 = FindWindowEx(lngWindWnd, 0, "Slider20WndClass", vbNullString)
Call SendMessage(lngBtnWnd1, TBM_SETPOS, 1&, ByVal 5)
End Sub
解決しましたのでこれで完了とさせて頂きます。
投稿者 ひでぽん  (社会人)
投稿日時
2021/2/10 10:04:10
るきおさん
spy++は試してみてメッセージが受信できる事はわかったのですがその後が勉強不足でわからなかったのです。回答ありがとうございました。
spy++は試してみてメッセージが受信できる事はわかったのですがその後が勉強不足でわからなかったのです。回答ありがとうございました。
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2021/2/7 10:46:13
> Slider1.Value = CLng(SliderLabelText.Text)
SliderLabelText じゃなくて
SliderLinkText でした…。
まあ SendMessage を使って組んであるものを
今更 DDE に置き換える必要もないですし、蛇足でしたね。
> TBM_SETPOS メッセージ (&H405&) ですね。
参考までに、その他のメッセージも紹介しておきます。
https://docs.microsoft.com/en-us/windows/win32/controls/bumper-trackbar-control-reference-messages
> FindWindowEx(lngWindWnd, 0, "Slider20WndClass", vbNullString)
これは MSCOMCTL.OCX の方の Slider ですね。
http://www.thevbzone.com/modControls.bas
SliderLabelText じゃなくて
SliderLinkText でした…。
まあ SendMessage を使って組んであるものを
今更 DDE に置き換える必要もないですし、蛇足でしたね。
> TBM_SETPOS メッセージ (&H405&) ですね。
参考までに、その他のメッセージも紹介しておきます。
https://docs.microsoft.com/en-us/windows/win32/controls/bumper-trackbar-control-reference-messages
> FindWindowEx(lngWindWnd, 0, "Slider20WndClass", vbNullString)
これは MSCOMCTL.OCX の方の Slider ですね。
SliderWndClass - Microsoft Windows Common Controls 5.0 [COMCTL32.OCX] (Slider)
Slider20WndClass - Microsoft Windows Common Controls 6.0 [MSCOMCTL.OCX] (Slider)
Slider20WndClass - Microsoft Windows Common Controls 6.0 [MSCOMCTL.OCX] (Slider)
http://www.thevbzone.com/modControls.bas
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2021/2/6 12:27:06
> SendMessageの引数の2番目と3番目がよくわからなくて困っています。
TBM_SETPOS メッセージ (&H405&) ですね。
WPARAM には ByVal 1& (再描画する) を渡し、
LPARAM を スライダー値を表す Long 値にします。
> FormA.exeのSlider(スライダーバー)をFormB.exeから操作したいのです。
FormA と FormB が共に自作なら、プロセス間通信のために
DDE を使うという選択肢もあります。
以下サンプル。On Error 処理は省いています。
=== FormA.exe ===
=== FormB.exe ===
TBM_SETPOS メッセージ (&H405&) ですね。
WPARAM には ByVal 1& (再描画する) を渡し、
LPARAM を スライダー値を表す Long 値にします。
> FormA.exeのSlider(スライダーバー)をFormB.exeから操作したいのです。
FormA と FormB が共に自作なら、プロセス間通信のために
DDE を使うという選択肢もあります。
以下サンプル。On Error 処理は省いています。
=== FormA.exe ===
プロジェクト名 = "ProjectA"
メインフォーム … Name や Caption は任意
LinkMode: 1 - ソース
LinkTopic: "HideponForm"
TextBox コントロール … Visible は True でも False でも良い
Name: SliderLinkText
メインフォーム … Name や Caption は任意
LinkMode: 1 - ソース
LinkTopic: "HideponForm"
TextBox コントロール … Visible は True でも False でも良い
Name: SliderLinkText
Private Sub SliderLinkText_Change()
Slider1.Value = CLng(SliderLabelText.Text)
End Sub
=== FormB.exe ===
Private Sub Form_Load()
TextBox1.Text = "5" 'Slider に渡したい値
Text1.LinkTopic = "ProjectA|HideponForm"
Text1.LinkItem = "SliderLinkText"
End Sub
Private Sub Command1_Click()
'現在の Text1.Text の値を FormA.exe に送り込む
Text1.LinkMode = vbLinkManual
Text1.LinkPoke
Text1.LinkMode = vbLinkNone
End Sub
投稿者 るきお  (社会人)
投稿日時
2021/2/5 20:27:31
直接の回答ではありません。
Spy++ というツールを使うとウィンドウが受け取っているメッセージを傍受できます。
Spy++ を仕掛けてからスライダーを操作することで、メッセージとパラメーターがわかるかもしれません。
Spy++ はVisual Studio に付属しています。
このサイトでの場所の説明がわかりやすかったです。
https://buralog.jp/visual-studio-2019-spyxx-path/
Spy++ のメッセージビュー
https://docs.microsoft.com/ja-jp/visualstudio/debugger/messages-view?view=vs-2019
ただ、これを素の状態で仕掛けるとものすごい大量のメッセージが次々と表示されるので、目的のメッセージを探すのは大変です…。
Spy++ というツールを使うとウィンドウが受け取っているメッセージを傍受できます。
Spy++ を仕掛けてからスライダーを操作することで、メッセージとパラメーターがわかるかもしれません。
Spy++ はVisual Studio に付属しています。
このサイトでの場所の説明がわかりやすかったです。
https://buralog.jp/visual-studio-2019-spyxx-path/
Spy++ のメッセージビュー
https://docs.microsoft.com/ja-jp/visualstudio/debugger/messages-view?view=vs-2019
ただ、これを素の状態で仕掛けるとものすごい大量のメッセージが次々と表示されるので、目的のメッセージを探すのは大変です…。
投稿者 ひでぽん  (社会人)
投稿日時
2021/2/5 18:51:31
VB6で作成されているプログラム、FormA.exeとFormB.exeがあります。
FormA.exeのSlider(スライダーバー)をFormB.exeから操作したいのです。
試しにFormA.exeにCommandボタンを配置してFormB.exeから操作してみたのですがそれはクリックできました。
ただSlider(スライダーバー)を操作する際のSendMessageの引数の2番目と3番目がよくわからなくて困っています。ご存じの方ご教示ください。
以降にテストサンプルを記述します。
--FormA.exe--
'フォームのキャプション=FomrA
'Slider1とCommand1を1配置
'※Slider1バーが移動するので操作が確認できるので
'※Command1のみ操作されたことがわかるようにメッセージを表示
Private Sub Command1_Click()
MsgBox "操作されました"
End Sub
--FormB.exe--
'フォームのキャプション=FomrB
'Command1とCommand2を1配置
'※Command1でFomrAのCommand1を操作
'※Command2でFomrAのSlider1を操作
Option Explicit
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Const WM_COMMAND = &H111
Private Const BN_CLICKED = &H0&
Private Const WM_CLOSE As Long = &H10
'FormA.exeのボタン(Command1)を操作
Private Sub Command1_Click()
Dim lngWindWnd As Long
Dim lngBtnWnd1 As Long
lngWindWnd = FindWindow(vbNullString, "FormA")
lngBtnWnd1 = FindWindowEx(lngWindWnd, 0, "ThunderRT6CommandButton", vbNullString)
Call SendMessage(lngWindWnd, WM_COMMAND, BN_CLICKED, ByVal lngBtnWnd1)
End Sub
'FormA.exeのSlider1を操作
Private Sub Command2_Click()
Dim lngWindWnd As Long
Dim lngBtnWnd1 As Long
lngWindWnd = FindWindow(vbNullString, "FormA")
lngBtnWnd1 = FindWindowEx(lngWindWnd, 0, "Slider20WndClass", vbNullString)
Call SendMessage(lngWindWnd, ????, ????, ByVal lngBtnWnd1)
'※引数の2番目と3番目の設定値がよくわかりません。
End Sub
FormA.exeのSlider(スライダーバー)をFormB.exeから操作したいのです。
試しにFormA.exeにCommandボタンを配置してFormB.exeから操作してみたのですがそれはクリックできました。
ただSlider(スライダーバー)を操作する際のSendMessageの引数の2番目と3番目がよくわからなくて困っています。ご存じの方ご教示ください。
以降にテストサンプルを記述します。
--FormA.exe--
'フォームのキャプション=FomrA
'Slider1とCommand1を1配置
'※Slider1バーが移動するので操作が確認できるので
'※Command1のみ操作されたことがわかるようにメッセージを表示
Private Sub Command1_Click()
MsgBox "操作されました"
End Sub
--FormB.exe--
'フォームのキャプション=FomrB
'Command1とCommand2を1配置
'※Command1でFomrAのCommand1を操作
'※Command2でFomrAのSlider1を操作
Option Explicit
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Const WM_COMMAND = &H111
Private Const BN_CLICKED = &H0&
Private Const WM_CLOSE As Long = &H10
'FormA.exeのボタン(Command1)を操作
Private Sub Command1_Click()
Dim lngWindWnd As Long
Dim lngBtnWnd1 As Long
lngWindWnd = FindWindow(vbNullString, "FormA")
lngBtnWnd1 = FindWindowEx(lngWindWnd, 0, "ThunderRT6CommandButton", vbNullString)
Call SendMessage(lngWindWnd, WM_COMMAND, BN_CLICKED, ByVal lngBtnWnd1)
End Sub
'FormA.exeのSlider1を操作
Private Sub Command2_Click()
Dim lngWindWnd As Long
Dim lngBtnWnd1 As Long
lngWindWnd = FindWindow(vbNullString, "FormA")
lngBtnWnd1 = FindWindowEx(lngWindWnd, 0, "Slider20WndClass", vbNullString)
Call SendMessage(lngWindWnd, ????, ????, ByVal lngBtnWnd1)
'※引数の2番目と3番目の設定値がよくわかりません。
End Sub
>WPARAM 型 … Win16 では 16bit長、Win32 では 32bit長、Win64 では 64bit長
>LPARAM 型 … Win16 では 32bit長、Win32 では 32bit長、Win64 では 64bit長
ご指摘ありがとうございます。修正しておきます。
それとご教示頂きましたDDEリンクも試してみたました。
こちらもうまくいきました。色々とありがとうございました。