- - PR -
別アプリの制御について
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2006-12-06 20:27
いつもお世話になっております。
だんご虫です。 SendMessageを使用して別アプリの制御を行いたいと思い、 以下のコードでテスト的にアプリを作成しました。 送り側アプリコード Private Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr End Function <DllImport("user32.dll")> _ Private Shared Function PostMessage _ (ByVal hWnd As IntPtr, ByVal Msg As Integer, _ ByVal wParam As IntPtr, ByRef lParam As COPYDATASTRUCT) As IntPtr End Function Private Structure COPYDATASTRUCT Public dwData As IntPtr Public cbData As Integer Public lpData As IntPtr End Structure Private Sub SendMess() Dim hWnd As IntPtr Dim cds As COPYDATASTRUCT Dim s As String hWnd = FindWindow(Nothing, "別アプリB") If Not hWnd.Equals(IntPtr.Zero) Then s = "ほげほげ" cds = New COPYDATASTRUCT cds.dwData = IntPtr.Zero cds.lpData = Marshal.StringToHGlobalUni(s) cds.cbData = (s.Length + 1) * 2 PostMessage(hWnd, WM_COPYDATA, IntPtr.Zero, cds) Marshal.FreeHGlobal(cds.lpData) End If End Sub 受け側あぷりコード Private Const WM_COPYDATA As Integer = &H4A Private Structure COPYDATASTRUCT Public dwData As IntPtr Public cbData As Integer Public lpData As IntPtr End Structure Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) If m.Msg = WM_COPYDATA Then Dim cds As COPYDATASTRUCT cds = CType(Marshal.PtrToStructure(m.LParam, GetType(COPYDATASTRUCT)), COPYDATASTRUCT) MessageBox.Show(Marshal.PtrToStringUni(cds.lpData)) Else MyBase.WndProc(m) End If End Sub 以上のSendMessageでの同期的な制御はできたのですが、 非同期での実装方法がいまいちわかりません。 初心者の為ちんぷんかんぷんな事を言ってるいるかもしれませんが、 ご教授お願い致します | ||||||||
|
投稿日時: 2006-12-06 22:25
できないです。 WM_COPYDATA メッセージは PostMessage() することが出来ません。 | ||||||||
|
投稿日時: 2006-12-06 22:59
渋木宏明(ひどり)さん御回答ありがとうございます。
なるほど、できないのですね・・・。 アプリAからアプリBの非同期で制御を行う場合は、 どのような方法が一般的なのでしょうか? | ||||||||
|
投稿日時: 2006-12-06 23:43
こんばんは。
「制御」というと、一方が他方に対して一方的に指示をする関係をイメージしてしまいますが、 そういうことを意図されているのでしょうか? それともアプリ同士で「協調動作」をさせたいのでしょうか? 「非同期で制御したい」が具体的にイメージできないのですが、 画面を持つアプリ間なら、ウィンドウメッセージもあるでしょうし、 各種さまざまなプロセス間通信の方法も用意されています。 その中でやりたいことに一番適した方法を選択します。 | ||||||||
|
投稿日時: 2006-12-07 00:17
Tdnr_Sym様 御回答ありがとうございます。
やりたい事は、 アプリAで行ったデータ更新を アプリBに通知し、アプリBで表示中のグリッドのデータにアプリAで 行った更新が反映される(データ再読込み)というものです。 | ||||||||
|
投稿日時: 2006-12-07 01:21
最初にそれを書きましょう。 手法の話から入るから、望む答えがなかなか得られないのです。 で、「データ更新があったこと」を伝えるだけなら、ユーザ定義のメッセージを PostMessage() すればいいんじゃないでしょうか。 [ メッセージ編集済み 編集者: 渋木宏明(ひどり) 編集日時 2006-12-07 01:21 ] | ||||||||
|
投稿日時: 2006-12-07 03:00
DDEメッセージとして実装するのが正統的な気がしますが、面倒くさいです。 通信用に見えない(表示されない)コントロールを持たせておいて、そこ宛に WM_SETTEXTをPostMessageで送る、とかいうのが簡単ではないかと。
更新したファイル名等、付随するデータを送りたい場合に、それじゃダメなんですよね。 | ||||||||
|
投稿日時: 2006-12-07 14:46
渋木宏明(ひどり)様
coasm様 ご回答ありがとうございます。 ユーザー定義のPostMessageを行う為、 テスト的に以下のことをやったのですが、 受け側アプリのほうの If m.Msg = WmUserTest Then で、m.Msgが0となってしまいうまくいきませんでした。 ご教授お願い致します。 メッセージ送信側アプリ <DllImport("user32", SetLastError:=True)> _ Private Shared Function RegisterWindowMessage(ByVal lpMessage As String) As Integer End Function Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" ( _ ByVal hwnd As Long, _ ByVal wMsg As Long, _ ByVal wParam As Long, _ ByVal lParam As Long _ ) As Long Private Sub PostMess() Dim hWnd As Long Dim msgstr As String WmUserTest = RegisterWindowMessage("WM_USER_TEST") hWnd = FindWindow(Nothing, "TESTB") PostMessage(hWnd, WmUserTest, 0, 0) End Sub 受け側アプリ Public WmUserTest As Integer <DllImport("user32", SetLastError:=True)> _ Private Shared Function RegisterWindowMessage(ByVal lpMessage As String) As Integer End Function Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) Static rcvmsg As String WmUserTest = RegisterWindowMessage("WM_USER_TEST") ’ここでm.Msg=0となってしまう If m.Msg = WmUserTest Then MessageBox.Show("aaaaa") Exit Sub Else MyBase.WndProc(m) End If End Sub |