レガシ MFC ベースのアプリケーション (MFC-app) 用のテスト アプリケーション (testApp) を構築しています。それらの間のメッセージパッシングを使用して、MFC アプリでのマウスクリックをシミュレートしようとしています。MFC アプリ メニューからダイアログ ボックスを表示するために、これを正常に行うことができました。ただし、MFC アプリのビューでマウス クリックをシミュレートしようとすると、動作しないようです。
私が持っている主な質問は、 SendMessage,PostMessage 関数を使用して CView の派生クラスと通信しようとする際に既知の制限があるかどうかです。また、メッセージを処理するために ON_COMMAND() ハンドラーを再利用していることにも注意してください。これは、TestApp を介してメニュー オプションのクリックによって呼び出される同じハンドラーを実行することが目標であるためです。私が試したことと私が得ているエラーの詳細:
試行 1。
テストアプリ:
::SendMessage を MFC アプリの CMainFrame に送信し、目的の入力で CView を表示するように依頼します。->これは機能します
MFC アプリケーション:
CMainFrame: ここで説明されているアプローチを使用して、CView (CDesignView) の派生クラスとその HWND ハンドルへの ptr を取得します: https://support.microsoft.com/en-us/kb/108587 使用されるコードを以下に貼り付けます。
CMDIChildWnd * pChild = MDIGetActive();
if ( !pChild )
return -1;
CView *pView = pChild->GetActiveView();
if (!pView) {
MessageBox(_T("Could not get a handle to the design"), _T("Test2 Error"), MB_OK);
return -1;
}
// Fail if view is of wrong kind
if ( !pView->IsKindOf( RUNTIME_CLASS(CDesignView) ) ) {
MessageBox(_T("View obtained is not of type DesignView"), _T("Test2 Error"), MB_OK);
return -1;
}
CDesignView* designView = (CDesignView*)pView ;
HWND view_hWnd = designView->m_hWnd ;
if (!view_hWnd) {
MessageBox(_T("designView handle could not be obtained"), _T("Test2 Error"), MB_OK);
return -1;
}
-------------------> この時点で、コードには view_hWnd と designView の非 NULL 値が含まれています。ただし、これらを SendMessage に使用すると失敗します。
designView->PostMessageW(ID_DESIGN_xxx,NULL, NULL) ;
--> これは機能しません。つまり、メッセージが送信されなかったかのようにアプリに変化はありません。ID_DESIGN_xxx ハンドラーは呼び出されません。ハンドラーは、CDesignView メッセージ マップで次のように宣言されます。
ON_COMMAND(ID_DESIGN_xxx、OnXXX)
(注: 目標はテストすることなので、MFCApp が CDesignView のこの関数に対応するメニュー オプションに既に使用していたハンドラーを再利用しています)
-------------------->以下のようにハンドラーへの直接呼び出しに置き換えると、動作します:
designView->OnStarOrder() ;
ただし、あまりにも多くのビュー ハンドラーをパブリックとして公開する必要があり、実際の使用モデルを厳密にシミュレートするテスト アプリの目的を無効にするため、これは私が望む動作ではありません。
------------------->さらにデバッグするために、以下のようにネイティブの WM_xxx メッセージを呼び出してみました。
designView->PostMessageW(WM_CLOSE,NULL, NULL) ;
これにより、このチェックで例外が失敗しました: IsKindOf( RUNTIME_CLASS(CView) assertion fail.
試行 2
また、上記のように独自のメインフレームでメッセージを送信する代わりに、TestApp が MFCApp CDesignView にメッセージを送信するようにしました。そこで、ON_COPY メッセージを使用して、上記のコードから TestApp に CDerivedView ハンドル view_hWnd を渡しました。次に、TestApp は ::SendMessage(view_hWnd,WM_CLOSE,NULL, NULL) を実行します。同じエラーが発生しました。このアプローチは、CDesignView が SendMessage の時点でアクティブなウィンドウではない可能性を排除しようとしました。この場合、TestApp にメッセージを送信させる前に、MFCApp の CView を手動でクリックします。
これらのどれも機能していないようです。続行するために提供できる提案は、非常に役立ちます。前もって感謝します!