C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: DLL側で呼び出し元を親ウィンドウにしたい


(過去ログ 137 を表示中)

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■80631 / inTopicNo.1)  DLL側で呼び出し元を親ウィンドウにしたい
  
□投稿者/ ホエホエ (1回)-(2016/07/28(Thu) 18:36:46)

分類:[C/C++] 

タイトルの通りですがなんですが…VC++MFCにて作成した標準DLLを
作成済アプリケーションプログラム(EXE)から呼び出すようにして
その中で呼び出し元を親ウィンドウにしてダイアログを表示したいと
思ってるのですが、以下の手順では上手くいきません。

1.API関数GetModuleHandleを使用して、呼び出し元プログラムのインスタンスハンドルを取得

2.FindWindowとGetWindowを使用し、すべてのウィンドウハンドルからGetWindowLong関数で
  インスタンスハンドルを取得し、呼び出し元インスタンスハンドルと一致するウィンドウを探す

と言う流れなのですが、GetWindowLong関数で一致するインスタンスハンドルが複数存在してしまい
目的のウィンドウ(呼出元プログラム)を特定できません。

どこがおかしいのでしょうか?または他に良い方法はありませんか?
HMODULEから簡単にHWNDが取れれば解決しそうなんですが…

引用返信 編集キー/
■80633 / inTopicNo.2)  Re[1]: DLL側で呼び出し元を親ウィンドウにしたい
□投稿者/ みい (55回)-(2016/07/28(Thu) 19:57:58)
No80631 (ホエホエ さん) に返信
> どこがおかしいのでしょうか?または他に良い方法はありませんか?
> HMODULEから簡単にHWNDが取れれば解決しそうなんですが…
dllの関数の引数にハンドルを追加して、EXEからの呼び出し時に
画面のハンドル(※モジュールハンドルではなく「画面」ハンドル)
を渡してはいかがでしょうか。

引用返信 編集キー/
■80634 / inTopicNo.3)  Re[2]: DLL側で呼び出し元を親ウィンドウにしたい
□投稿者/ ホエホエ (2回)-(2016/07/28(Thu) 20:17:50)
みいさん>
コメントありがとうございます。

> dllの関数の引数にハンドルを追加して、EXEからの呼び出し時に
> 画面のハンドル(※モジュールハンドルではなく「画面」ハンドル)
> を渡してはいかがでしょうか。
→残念ながらアプリケーション(EXE)側はソースもなく変更できませんので
 DLL側でどうにか取得する必要がありまして…

引用返信 編集キー/
■80643 / inTopicNo.4)  Re[1]: DLL側で呼び出し元を親ウィンドウにしたい
□投稿者/ ito (28回)-(2016/07/29(Fri) 09:02:29)
No80631 (ホエホエ さん) に返信
> と言う流れなのですが、GetWindowLong関数で一致するインスタンスハンドルが複数存在してしまい
> 目的のウィンドウ(呼出元プログラム)を特定できません。
特定のウィンドウは、タイトル(キャプション)/クラス名から判断できないのでしょうか!?
GetWindowText, GetClassName API辺りが使えそうです。

GUIスレッドで処理させるために、非表示のウィンドウを作成して処理を行わせるって事は普通にありますので、
IsWindowVisible API辺りも使えるかと。

引用返信 編集キー/
■80644 / inTopicNo.5)  Re[3]: DLL側で呼び出し元を親ウィンドウにしたい
□投稿者/ みい (56回)-(2016/07/29(Fri) 09:20:25)
No80634 (ホエホエ さん) に返信
> みいさん>
> コメントありがとうございます。
>
>>dllの関数の引数にハンドルを追加して、EXEからの呼び出し時に
>>画面のハンドル(※モジュールハンドルではなく「画面」ハンドル)
>>を渡してはいかがでしょうか。
> →残念ながらアプリケーション(EXE)側はソースもなく変更できませんので
>  DLL側でどうにか取得する必要がありまして…
VisualStudio付属ツールのSpy++を使って取得できそうなアプリケーション側の
値を確認してみてはいかがでしょうか。

itoさん既出のGetWindowText&GetClassNameで他アプリケーションにメッセージ
送り込むのは昔(VC6時代…)よくやってました。
引用返信 編集キー/
■80646 / inTopicNo.6)  Re[1]: DLL側で呼び出し元を親ウィンドウにしたい
□投稿者/ とっちゃん (395回)-(2016/07/29(Fri) 11:03:59)
No80631 (ホエホエ さん) に返信
> タイトルの通りですがなんですが…VC++MFCにて作成した標準DLLを
> 作成済アプリケーションプログラム(EXE)から呼び出すようにして
> その中で呼び出し元を親ウィンドウにしてダイアログを表示したいと
> 思ってるのですが、以下の手順では上手くいきません。
>


GetCurrentProcessId API でプロセスIDを取得。(1に該当)
EnumWindows API で トップレベルウィンドウを対象に自分のプロセスIDと一致するウィンドウを検索。(2に該当)
ウィンドウのプロセスIDは GetWindowThreadProcessId API で取得できます。

最初に見つけたウィンドウが表示されていればそれを使えばOK.
出ていない場合は、とりあえずキープしておいてほかにウィンドウがないかを検索。
ウィンドウの種類が特定できる場合(スタイルなどを見る)はそれを見て判定もできます。

EnumWindow から戻ってきた時点で確定したHWNDが無効な状態(IsWindowEnabled == FALSE)なら
GetLastActivePopup API でそのウィンドウが現在表示しているポップアップウィンドウのハンドルを取得。

これで、ほぼどんな状況下でもウィンドウを引っ張り出せるはずです。


引用返信 編集キー/
■80647 / inTopicNo.7)  Re[2]: DLL側で呼び出し元を親ウィンドウにしたい
□投稿者/ ホエホエ (3回)-(2016/07/29(Fri) 11:25:25)
itoさん>
コメントありがとうございます。

> 特定のウィンドウは、タイトル(キャプション)/クラス名から判断できないのでしょうか!?
> GetWindowText, GetClassName API辺りが使えそうです。
→対象のアプリケーションが今後もバージョンアップにより改変される予定ですので
 ウィンドウタイトルやクラス名の決め打ちは、現状には対応できるんですが…

> GUIスレッドで処理させるために、非表示のウィンドウを作成して処理を行わせるって事は普通にありますので、
> IsWindowVisible API辺りも使えるかと。
→もしかしたらGetWindowLong関数で一致するインスタンスハンドルが複数存在するうちの
 1つは上記のことが該当するのかもしれませんね(対象のアプリケーション画面は1つのはずなので)



みいさん>
再コメントありがとうございます。

> VisualStudio付属ツールのSpy++を使って取得できそうなアプリケーション側の
> 値を確認してみてはいかがでしょうか。
→クラス名をSPY++で調べて決め打ちにする方法も考えたんですが、
 その方法ではアプリケーションがバージョンアップされた際に
 クラス名の変更に対応できないと思い、毎度動的に取得できる方法は
 ないかと思いまして…
引用返信 編集キー/
■80648 / inTopicNo.8)  Re[2]: DLL側で呼び出し元を親ウィンドウにしたい
□投稿者/ ホエホエ (4回)-(2016/07/29(Fri) 11:43:56)
とっちゃんさん>
コメントありがとうございます。

> EnumWindow から戻ってきた時点で確定したHWNDが無効な状態(IsWindowEnabled == FALSE)なら
> GetLastActivePopup API でそのウィンドウが現在表示しているポップアップウィンドウのハンドルを取得。
>
> これで、ほぼどんな状況下でもウィンドウを引っ張り出せるはずです。
→対象ウィンドウ判定に助言いただいた条件を追加して絞り込んで、
 目的のウィンドウハンドルだけを取得することができました!!
 助かりました、ありがとうございます。


解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -