• ベストアンサー

PostMessageの連続送信

phoenix343の回答

  • phoenix343
  • ベストアンサー率15% (296/1946)
回答No.3

はじめまして PostMessage関数はキューに登録してすぐ制御を返します。 連続して送ると 逆転されて発行することは大いにありえます キューってのはシステムが保持しますからねぇ 同じ使うのならすぐに制御を返してくれる SendNotifyMessage関数や SendMessageCallback関数なんかはどうですか? これはキューに登録するのではなく、直接指定した ウィンドウハンドルのプロシージャを呼び出し、制御を返す…と いう関数ですから、少なくとも逆転するとは思えないんですが。 詳しくはMSDNに載っているはずですから、モノは試しでやってみる価値はあると思います。 うまくいかなかったらごめんなさい。

BAIKAN
質問者

お礼

ありがとうございます、できれば同期型ではなく非同期型で制御したかったので・・・ この方法も検討してみます。

関連するQ&A

  • PostMessageで外部のexeへメッセージを送ったときに不具合が出る

    現在、PostMessageを利用して外部のexeへファイル名(フルパス)を送信して、 そのファイルをexeで読み込むようにさせています。 以下、そのプログラムです。 CWnd *hWnd = FindWindow("ConsoleWindowClass", "C:\\WINDOWS\\system32\\cmd.exe"); char str[256]="C://sumple//test.txt\n" int len = 256; for( int i=0; i<len; i++ ){ ____char c; ____c = toupper( str[i] ); ____switch( str[i] ) ____{ ________case '\n': ________c = VK_RETURN; ________break; ____} ____hWnd->PostMessage(WM_KEYDOWN, c, 0 ); } ところが、たとえばファイルパスが"C://sumple//aa.txt\n" のように、同じ文字が連続して存在すると"aa.txt"ではなく"a.txt"として送信されてしまいます。 このような現象にはどう対応すればよいのでしょうか? また、"/"や"."などの記号は"Csumpleaatt\n"のように存在しないとして処理されているようなので case '/': ____hWnd->PostMessage(WM_KEYDOWN, VK_DIVIDE, 0 ); ____break; のように直接仮想キーコードで入力しています。(こちらは上手くいっています) 文字の連続で起こる現象にも使えるかと思って case 'a': ____hWnd->PostMessage(WM_KEYDOWN, 0x41, 0 ); ____break; としてみたのですが、やはり駄目でした。 ファイル名に連続した文字を使わなければいいのでしょうが、汎用性を持たせるためにもどうにか解決したいと思います。 どうかご解答をお願いします。

  • PostMessageで外部のexeへメッセージを送ったときに不具合が出る

    現在、PostMessageを利用して外部のexeへファイル名(フルパス)を送信して、 そのファイルをexeで読み込むようにさせています。 以下、そのプログラムです。 CWnd *hWnd = FindWindow(\"ConsoleWindowClass\", \"C:\\\\WINDOWS\\\\system32\\\\cmd.exe\"); char str[256]=\"C://sumple//test.txt\\n\" int len = 256; for( int i=0; i<len; i++ ){ ____char c; ____c = toupper( str[i] ); ____switch( str[i] ) ____{ ________case \'\\n\': ________c = VK_RETURN; ________break; ____} ____hWnd->PostMessage(WM_KEYDOWN, c, 0 ); } ところが、たとえばファイルパスが\"C://sumple//aa.txt\\n\" のように、同じ文字が連続して存在すると\"aa.txt\"ではなく\"a.txt\"として送信されてしまいます。 このような現象にはどう対応すればよいのでしょうか? また、\"/\"や\".\"などの記号は\"Csumpleaatt\\n\"のように存在しないとして処理されているようなので case \'/\': ____hWnd->PostMessage(WM_KEYDOWN, VK_DIVIDE, 0 ); ____break; のように直接仮想キーコードで入力しています。(こちらは上手くいっています) 文字の連続で起こる現象にも使えるかと思って case \'a\': ____hWnd->PostMessage(WM_KEYDOWN, 0x41, 0 ); ____break; としてみたのですが、やはり駄目でした。 ファイル名に連続した文字を使わなければいいのでしょうが、汎用性を持たせるためにもどうにか解決したいと思います。 どうかご解答をお願いします。

  • Excel VBAでIE「ダウンロードの表示」生成

     Internet Explorer で、「ダウンロードの表示」のDialogウィンドウをショートカット(Ctrl + J )を使って表示させたいのですが、Excel VBA で以下のコードで試したのですが、うまくいきません。どういうコードを書いたらよいのでしょうか?アクセスキーを使った方法では、「ツール」で N  に該当するのが「ダウンロードの表示」と「Send To Note」の2つあって起動できません。  よろしくお願いします。 Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Public 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 Public Const WM_KEYDOWN = &H100 Public Const WM_KEYUP = &H101 Public Const VK_CONTROL = &H11 Public Const VK_J = &H4A Public Const navOpenInNewTab = &H800 Sub Test() Dim objIE As Object Dim hWnd_objIE As Long Dim Ret As Long 'IE起動 Set objIE= CreateObject("InternetExplorer.Application") objIE.Visible = True objIE.navigate "https://www.google.co.jp/", navOpenInNewTab Do While objIE.Busy = True Or objIE.readyState <> 4 DoEvents Loop 'objIEのhWnd取得 hWnd_objIE = objIE.hwnd 'IEの親ウィンドウのhWnd取得する 'hWnd_objIE のウィンドウにPostMessageする Ret = PostMessage(hWnd_objIE, WM_KEYDOWN, VK_CONTROL, 0) Ret = PostMessage(hWnd_objIE, WM_KEYDOWN, VK_J, 0) Sleep 100 Ret = PostMessage(hWnd_objIE, WM_KEYUP, VK_CONTROL, 0) Ret = PostMessage(hWnd_objIE, WM_KEYUP, VK_J, 0) End Sub

  • 応答なしの外部アプリの強制終了

    現在、応答なし状態の外部アプリを強制終了させたいのですが上手くいきません。 アプリが応答なしかどうかはSendMessageTimeoutを使用して判断できるます。 しかし、強制終了をPostMessage(hwnd, WM_CLOSE, 0, 0)でしても戻り値は正常なのですがアプリは終了してくれません。(応答なしだから?でも戻り値返してるって事は応答なしじゃないの?謎) 一応、外部アプリが実行中の状態でPostMessageをコールしたらちゃんと終了してくれました。 他にアプリを強制終了させるような関数をあるのでしょうか?あるのであれば教えてください。 よろしくお願い致します。 === 環境 === Windows2000 VC++ 6.0

  • ウィンドウのないActiveXコントロールへのメッセージ通知方法

     内部的にWinsock2を使用して別のサーバアプリケーションと通信を行うActiveXコントロールを作成しています。サーバからのデータ受信を非同期で行うため、WSAAsyncSelect()関数を使用して指定したウィンドウにWinsockからイベントメッセージ(メッセージIDはWM_USER+1を使用)を通知させます。 コントロールをウィンドウなしのアクティベーション使用で開発しているので、WSAAsyncSelect()のメッセージ通知対象ウィンドウがコントロール内にありません。 コンテナによりコントロール充てにメッセージを送ってくれるということなので、コンテナのウィンドウハンドルを取得し、WSAAsyncSelect()のメッセージ通知対象ウィンドウに設定しました。が、コントロールのOnMessageWindowless()にWM_USER+1のイベントは来ていないようです。 私が試したウィンドウハンドルは、次のコードで取得できるものです。 1. AfxGetMainWnd()->m_hWnd 2. CWnd::GetActiveWindow()->m_hWnd (CWndは使用するなとありましたが)  取得するウィンドウハンドルが間違っているのでしょうか?それとも、コンテナアプリケーションはWM_USERメッセージをコントロールに送ることができないのでしょうか?もしくは、コンテナにWM_USER+1のメッセージはコントロールへ、という設定をしてやる必要があるのでしょうか?  なお、なぜウィンドウありのコントロールにしないかと申しますと、ウィンドウありだとコンテナ(IEを想定)に乗った直後にウィンドウが生成されず、自分のウィンドウハンドルを取得しようとするとNULLが返ってしまうからです。ユーザがマウスで一度クリックすればOKなのですが・・・オブジェクト生成時に自動的にウィンドウを生成する方法がわかりませんでした。もしこちらが分かればウィンドウありで行くこともできますので、分かる方いらっしゃいましたらお願いいたします。

  • CTreeCtrlのCreate関数でエラーになります。

    Visual C++ .NET Win32 プロジェクト で、アプリケーションを作成しようと思っています。 #include<afxwin.h> #include<afxcmn.h> // マルチスレッド CTreeCtrl *m_TreeCtrl; LRESULT CALLBACK int WindowProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { switch(message) { case WM_LBUTTONDOWN: m_TreeCtrl=new CTreeCtrl; m_TreeCtrl->Create(WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_BORDER | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_HASLINES | TVS_DISABLEDRAGDROP, CRect(10, 10, 300, 100), CWnd::FromHandle(hWnd), 10000); break; case WM_CREATE: break; case WM_DESTROY: PostQuitMessage(0); break; case WM_PAINT: HDC hDC; PAINTSTRUCT Paint; hDC=BeginPaint(hWnd,&Paint); EndPaint(hWnd,&Paint); } return DefWindowProc(hWnd,message,wParam,lParam); } ・・・ と記述すると、エラーになります。 解決方法を教えてください。

  • タイトルバーの無いウィンドウのドラッグについて

    タイトルバーの無いウィンドウをドラッグするために以下のようにしています。 void CMyWnd::OnLButtonDown(UINT nFlags, CPoint point) { PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y)); CWnd::OnLButtonDown(nFlags, point); } 一方で、ドラッグ操作後に呼ばれたLButtonUpを察知するために以下のコードで実現しようとしました。 BOOL DragFlg; //FALSEのときはドラッグしていない //TRUEのときはドラッグした LButtonDownイベントハンドラ { DragFlg = FALSE; PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y)); } OnMouseMoveイベントハンドラ { DragFlg = TRUE; } LButtonUpイベントハンドラ { if(DragFlg == FALSE){ //ドラッグしなかった(ただのシングルクリック) } else{ //ドラッグした } } ところが、タイトルバーの無いウィンドウをドラッグするためのコードがあるため、OnMouseMoveイベントハンドラが発生しません。 このような場合、どのようにして実現すれば良いのでしょうか? #この前の2つの質問は、原因が分かった為削除します。

  • VC++&グローバルフックについて質問です

    vc++2008,Windows Vistaの環境でプログラムを作成しています。 以下、aが押されたら、設定したhWndにWM_KEYDOWN,VK_LEFTのメッセージを送るプログラムのつもりで書きました。 http://www.shos.info/develop/cwin/tipswin.html#windows008 を参考にしています。 しかし、dllにしてWinMainで呼び出したのですが動作しません。 エラーも出ないのでなぜ動かないのかがわかりません。 このプログラムをちゃんと動かすにはどうしたらいいでしょうか。 どうかご指摘ください。よろしくお願いします。 //hook.h #ifdef HOOKAPI #else #define HOOKAPI extern "C" __declspec(dllimport) #endif HOOKAPI HINSTANCE _hInstance; HOOKAPI HHOOK _hHook; HOOKAPI HWND _hWnd; HOOKAPI BOOL Set(HWND hWnd); HOOKAPI void Reset(); //hook.cpp #include <windows.h> #define HOOKAPI extern "C" __declspec(dllexport) #include "hook.h" #pragma data_seg(".share") HHOOK _hHook = NULL; HWND _hWnd = NULL; HINSTANCE _hInstance; #pragma data_seg() #pragma comment(linker, "/section:.share,rws") LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam) { /* ここでは 'A' が押されたら予め設定済みの _hWnd にメッセージを送る */ if (nCode >= 0 && nCode != HC_NOREMOVE && wParam == 'A') { PostMessage(_hWnd, WM_KEYDOWN, VK_LEFT, 0); CallNextHookEx(_hHook, nCode, wParam, lParam); return 1; } return CallNextHookEx(_hHook, nCode, wParam, lParam); } BOOL Set(HWND hWnd) { /* キーのフック */ _hHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)HookProc, _hInstance, 0); /* ここで hInstance は DLL のインスタンス ハンドル */ _hWnd = hWnd; return (_hHook != NULL); } void Reset() { if (_hHook != NULL) { UnhookWindowsHookEx(_hHook); _hHook = NULL; } }

  • WM_CLOSEで閉じれないウィンドウを閉じるには?

    以下にソースを張ります。 #include <stdio.h> #include <windows.h> BOOL CALLBACK EnumWindowProc(HWND hwnd, LPARAM lp) { static bool is_first = true; DWORD style = ::GetWindowLong(hwnd, GWL_STYLE); DWORD dwPID; if ( ::IsWindow(hwnd) && ::IsWindowVisible(hwnd) && (style&WS_CAPTION) && !(style&WS_POPUP) ) { char buf[65536]; ::GetWindowText(hwnd, buf, 65535); GetWindowThreadProcessId( hwnd, &dwPID ); if ( buf[0] != '\0' ) { if ( is_first ) is_first = false; else //printf("%c\n", 1); printf("%s%d\n", buf,hwnd); } } return TRUE; } int main (void){ ::EnumWindows(EnumWindowProc, 0); HWND hWnd; printf("プロセスIDを入力:\n"); scanf("%d",&hWnd); if( hWnd != NULL ){ printf( "終了します。-- pause --\n" ); getchar(); PostMessage( hWnd, WM_CLOSE, 0, 0 ); }else{ printf( "起動してないウインドウズです。\n" ); } return 0; } これですとたとえばメモ帳を編集していたときに WM_CLOSE メッセージを送ったときに「変更を保存しますか?」のようなダイアログが出る アプリがあります。これをダイアログが出ずに強制終了するには どうしたらよいでしょか?よろしくお願いします。

  • VBAで外部プログラム操作

    AccessVBAからTelnet操作を行いたく 苦肉の策で下記のような処理を組み込みました。 Private Sub Command1_Click()   Shell "cmd.exe"   stopTime 50   Call EnumWindows(AddressOf Rekkyo, 0)   lRet = FindWindow(vbNullString, "C:\WINDOWS\system32\cmd.exe")   Call SendMessage(lRet, WM_SYSCOMMAND, WM_MAXIMIZE, ByVal 0&)   Call PostMessageStrings("telnet hoge.hoge")   Call PostMessageStrings("username")   Call PostMessageStrings("passwd")   Call PostMessageStrings("テルネット上の処理")   Call PostMessageStrings("quit")   Call PostMessageStrings("exit") end sub Public Function PostMessageStrings(strPost As String)   Dim i As Integer   '1文字ずつ分解して送信   For i = 1 To Len(strPost)     Call PostMessage(lRet, &H102, Asc(Mid(strPost, i, 1)), 0)   Next   '送信後に改行コードを送信   Call PostMessage(lRet, &H102, 13, 0) End Function shell で起動したコマンドプロンプトのウィンドウが 最小化された状態で以降の処理が進められてしまいます。 何かいい案は無いでしょうか? もしくは、もっと効率よくtelnet操作できる方法は無いでしょうか? 以上よろしくお願いいたします。