毎度、お世話になっております。
WindowsXP+VC6.0にて開発しております。
アプリケーションが2つ(A.EXEとB.EXE 双方ともCFormView)あり、
AからBに対してSendMessage()を行い、Bは状態を返すといったような
ものを作成しております。
この場合、Bがモーダル又はモードレスのダイアログを表示している場合
FALSEを返すようにしたいのです。
ダイアログにウィンドウクラス名を設定し、FindWindow()により表示され
ているか有無を調べようと考えております。
色々と探しているのですが、ダイアログベースアプリに関しての変更方法
はあるのですが、ダイアログに関してはヒットしません。
ご存知の方、ご教授願います。
また、この方法以外にも良きやり方があれば合わせてお願い致します。
ダイアログベースアプリも単なるダイアログだから同じじゃないの。
何かできない理由あったっけ?
下記2つの方法で試しましたがSpyでクラス名を確認すると
#32770 (ダイアログ)のままで変わりませんでした。
双方ともOnCreate()に記述。
------------------------------
WNDCLASS wc;
::GetClassInfo(AfxGetInstanceHandle(), #32770, &wc);
wc.lpszClassName = MyPrivateClassName;
AfxRegisterClass(&wc);
------------------------------
WNDCLASS wc;
wc.style = CS_DBLCLKS;
wc.lpfnWndProc = DefDlgProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.hInstance = AfxGetInstanceHandle() ;
wc.hIcon = NULL;
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = _T(MyPrivateClassName);
AfxRegisterClass( &wc ) ;
------------------------------
やり方がわるいのでしょうか?
B.EXEがダイアログが表示中であるかどうかの管理をちゃんと行なえば
良いような気もしますが、そのやり方では駄目なんでしょうか?
特にモードレスダイアログの場合はダイアログの表示側で
きちんと管理する必要があると思うのですけれど。
PATIO様 回答ありがとうございます。
確かにB.EXEでダイアログ表示前にフラグをONさせ、閉じた後にOFFすれば
実現は可能かと思います。
ただ、フラグ的なものに依存すると処理が煩雑化し、プログラム自体わかり
づらいものになってしまうような気がします。
そこで、ダイアログ自体にウィンドウクラス名をつければ、見た目もすっきり
し、良いのではないかと思いました。
ウィンドウクラス名にとらわれず、実現でれば良いのですが。
RegisterWindowMessage 関数でメッセージを登録して通信する方法はだめですか?
MFC ダイアログ ボックスの独自のウィンドウ クラス名を提供する方法
http://support.microsoft.com/default.aspx?scid=kb%3Bja%3B251059
で、任意のダイアログのウィンドウクラス名を変更できるみたいです。
#SDI/MDIアプリでも使えます
#メッセージボックスはこの方法では変更できません
補足です。
> MFC ダイアログ ボックスの独自のウィンドウ クラス名を提供する方法
> http://support.microsoft.com/default.aspx?scid=kb%3Bja%3B251059
通常はリンク先で説明している手順の3, 4を実施するだけでOKです。
というか、手順1, 2をやると、あとでMFCの動作がいろいろおかしくなる
らしいのでやらないほうがいいでしょう。
み様
> MFC ダイアログ ボックスの独自のウィンドウ クラス名を提供する方法
> http://support.microsoft.com/default.aspx?scid=kb%3Bja%3B251059
これは、ダイアログベースに対するクラス名の変更ですので、
使えないと思います。(勘違いしていたらごめんなさい)
結果、メッセージを受け取ったときにEnumWindows()で得られたハンドル
の親ウィンドウを調べることでできそうな感じです。
(自作のダイアログにクラス名を付けられたとしても、
コモンダイアログには付けられないので)
> これは、ダイアログベースに対するクラス名の変更ですので、
> 使えないと思います。(勘違いしていたらごめんなさい)
明らか、勘違いですね。(^^;
PATIOさんの提案が最も一般的で間違いの無い方法で、
ゆうづうもききます。
が、どうしても「窓探し」でやりたい場合は窓にIDをつけるのが簡単。
クラス名では、同クラスが複の数窓を開いている場合に問題になる
からです。では、どのようにIDをつけるかというと
::SetWindowLong( hdlg, DWL_USER, id);
で、できます。取得するには
id = ( int)::GetWindowLong( hdlg, DWL_USER);
ただし、ウインドウとダイアログで扱いが異なるので注意。
IDの代わりにもっと複雑な、例えばクラスインスタンスの
ポインタ等も設定できますので、好きに使いましょう(笑)。
> 結果、メッセージを受け取ったときにEnumWindows()で得られたハンドル
> の親ウィンドウを調べることでできそうな感じです。
> (自作のダイアログにクラス名を付けられたとしても、
> コモンダイアログには付けられないので)
そういうことなら仕方ないかな。
親ウィンドウがNULL(MFCだと自動でメインウィンドウが使われる)とか別のウィンドウ
が指定されている場合はないとして。
GatLastActivePopup(親ウィンドウ)で調べられそう。
MSDNの説明だとそういう使い方に使っていいのか判らないので、
EnumWindows()で片っ端に調べた方がいいな。
俺も、ウィンドウがあるかないかでメッセージを受け付けることができるか判断するのは
変だと思う。
特にモードレスとか変じゃない。
モードレスを出している間にメインウィンドウの閉じるなどを実行できてしまうから、
別アプリからのSendMessage対応ではなく
初めからその手の対策済みでプログラムを作っているべきなんじゃない。
とはいうものの
モードがある(条件によって動作が変わる)プログラムって面倒だよね。
皆様、色々とありがとうございます。
とりあえず、EnumWindows()でそれらしきことが実現できているようです。
まだ、細部にわたりチェックはしていませんが、うまく行けば、この方法
で進めたいと思います。
また、新たな問題等ありましたら再びお邪魔するかも知れませんが、
その時は、お願いします。