Delphi 7 で記述された Windows フォーム アプリケーションと、MFC を使用して記述された C++ .dll があります。
現在、プログレスバーにユーザーの計算プロセスを表示するために、.dll からメインの実行可能ファイルへの基本的なメッセージ投稿を実装しようとしていますが、いくつかの問題に直面していました。
最初に私のアプローチを説明しましょう。次のような簡単なメッセージを Delphi アプリケーションに登録します。
WM_MSG := RegisterWindowMessage('WM_MSG');
ライブラリ部分でも同じことを行います。
UINT nMsgID = RegisterWindowMessage(_T("WM_MSG"));
これで問題ありません。デバッグ時に両側で同じ値を確認できます。
私のライブラリ関数は次のようになります(プログレスバーをテストするためのダミーの例です):
extern "C" __declspec(dllexport) int MyFunction() {
UINT nMsgID = RegisterWindowMessage(_T("WM_MSG"));
HWND hWnd = FindWindow(NULL, "Form1");
if (hWnd > 0)
for (int i = 0; i < 100000; i++) {
int param = ceil(100 * (double) i / (double) 100000);
PostMessage(hWnd, nMsgID, param, NULL);
}
return 1;
}
実行可能なOnMessageイベント:
procedure TForm1.OnMessageEvent(var Msg: tagMSG; var Handled: Boolean);
begin
Handled := True;
if Msg.message = WM_MSG then
ProgressBar1.Position := Msg.wParam
else Handled := False;
end;
実行可能ファイルからの C++ 関数呼び出し:
procedure TMyFunctionDLL.Execute;
var
i: Integer;
tHWND: HWND;
begin
tHWND := FindWindow(nil, 'mainF');
i := Func;
end;
最初の問題は、tHWND変数とhWnd変数の値が不可解に異なることです。いくつかの調査の後、私は 3 つの状況を発見しました: 1. 負または正の巨大なhWnd 2. ゼロhWnd 3. 未定義 ('???')
すべての場合において、変数hWndは未使用としてマークされており、それが何を意味するのかわかりません。最も興味深いのは、コードを非常に単純な Delphi 形式 (1 つのユニットのみ) でテストすると、コードが機能することです。この単純な Delphi フォームは、実際のデータが計算される実際の C++ .dll コードでうまく機能します。しかし、一般的な Delphi アプリケーション (多くのユニットでありながら 1 つのフォーム) を使用すると、メイン アプリケーションの OnMessage イベントが C++ dll からのイベントをキャッチしないようです。
したがって、2 つの質問があります。1. hWnd値が常に異なるのはなぜですか。2. メイン アプリケーションをプログレスバーで正しく動作させるにはどうすればよいですか?
私はこれを解決するためにさまざまなアプローチを使用してきました。Application.HandleまたはForm1.Handleを関数パラメーターとして C++ ライブラリに渡すなど。通過中にパラメーター値が変更されたことについてさえ言わずに、それらのどれも機能しませんでした(それは別の質問になるはずです)。また、FindWindow() と PostMessage() の代わりに ::FindWindow() と ::PostMessage() を使用してみました(それらの違いは何ですか?)、どちらも役に立ちませんでした。私はすでに一日中状況を改善しようとしていますが、それを解決する方法がわかりません。どんなアイデアでも助けてください。