2008-09-09 1 views
5

アプリケーションが別のアプリケーションの背後にあり、 私のアプリケーションのタスクバーアイコンをクリックすると、 が開いている場合でも、アプリケーション全体が がzオーダーの先頭に来ることが期待されます。子ウィンドウをクリックしてもアプリケーションが常に前面に表示されるわけではないのはなぜですか?

しかし、いくつかの(私の他の)ダイアログボックスの中には、ダイアログボックスだけが前面に来るものもあります。残りのアプリケーションは遅れています。

私はSpy ++を見てきました。正しく動作するものについては、 ダイアログの親にWM_WINDOWPOSCHANGINGが送信されています。 の残りのアプリケーションを残しておくと、WM_WINDOWPOSCHANGINGはダイアログの親に送信された ではありません。

私は、1つのダイアログで通常はアプリ全体が表示され、もう1つは表示されないという例があります。作業ダイアログボックスと非作業ダイアログボックスは、同じウィンドウスタイル、サブスタイル、親、所有者、ontogenyを持ちます。

要するに、DialogBoxParam()で作成されたWS_POPUPWINDOWウィンドウで、第3引数として同じHWNDに渡された です。

誰かがWindowsプログラムでこの動作上の不自然さに気付いたことはありますか?ボタンをクリックすると、タスクバーがアプリケーションに送信するメッセージは何ですか?誰が責任を負うのは、アプリケーションのウィンドウのすべてがフォアグラウンドになることです。

私の場合、ベースの親子関係はMDIフレームです...何らかの理由でその要素がありますか?

答えて

0

ダイアログの親ウィンドウは正しく設定されていますか?

これを投稿した後、自分でWindowsフォームアプリケーションを起動し、問題を再現しました。私は2つのダイアログを持っています.1つは正常に動作し、もう1つは正しく動作しません。見つけたらこの投稿を更新します。

あなたはどこですか?

1

タスクバーアイコンをクリックすると、WindowsはWM_ACTIVATEメッセージをアプリケーションに送信します。

あなたはあなたのコードが処理のためにDefWindowProc関数ウィンドウプロシージャにWM_ACTIVATEメッセージを渡していますか?

4

私はこれが非常に古いことを知っていますが、私はそれを見つけたばかりです。

ダイアログボックスをフォアグラウンドにすると、ではなく、でメインウィンドウが表示されるアプリケーションでは、開発者は単にダイアログボックスの所有者を指定しなかっただけです。

これは、ダイアログボックスやメッセージボックスのようなモーダルウィンドウ、およびモードレスウィンドウの両方に適用されます。モードレスポップアップの所有者を設定すると、ポップアップが常にその所有者の上に保持されます。Win32 APIでは

、ダイアログボックスが表示またはメッセージボックスがパラメータとしてオーナーウィンドウを取るための機能が:

INT_PTR DialogBox(
    HINSTANCE hInstance, 
    LPCTSTR lpTemplate, 
    HWND hWndParent,  /* this is the owner */ 
    DLGPROC lpDialogFunc 
); 

int MessageBox(
    HWND hWnd,   /* this is the owner */ 
    LPCTSTR lpText, 
    LPCTSTR lpCaption, 
    UINT uType 
); 

Similary、.NETのWinFormsで、所有者が指定することができます。

public void Show(
    IWin32Window owner, 
) 
public DialogResult ShowDialog(
    IWin32Window owner 
) 

public static DialogResult Show(
    IWin32Window owner, 
    string text 
) /* ...and other overloads that include this first parameter */ 

また、リサイズでは、モードレスウィンドウの所有者を設定するのは簡単ですまたは、同等:ストレートWinAPIのコードで

form.Owner = this; 
form.Show(); 

ウィンドウが作成されるときに、モードレスウィンドウの所有者が設定することができる。

HWND CreateWindow(
    LPCTSTR lpClassName, 
    LPCTSTR lpWindowName, 
    DWORD dwStyle, 
    int x, 
    int y, 
    int nWidth, 
    int nHeight, 
    HWND hWndParent, /* this is the owner if dwStyle does not contain WS_CHILD */ 
    HMENU hMenu, 
    HINSTANCE hInstance, 
    LPVOID lpParam 
); 

又は後:

SetWindowLong(hWndPopup, GWL_HWNDPARENT, (LONG)hWndOwner); 

又は(64ビット互換)

SetWindowLongPtr(hWndPopup, GWLP_HWNDPARENT, (LONG_PTR)hWndOwner); 
MSDN約 SetWindowLong[Ptr]を言うために、次のことをしている0

注:

は、子ウィンドウの親を変更するにはGWLP_HWNDPARENTインデックスとSetWindowLongPtrを呼び出さないでください。代わりに、SetParent関数を使用します。

これは、上記の最後の2つのスニペットが間違っていることを暗示しているように思われるので、やや誤解を招きます。これはそうではありません。 SetParentを呼び出すと、所有するウィンドウにするのではなく、意図したポップアップを親ウィンドウの子のWS_CHILDビットを設定)に変更します。上記のコードは、既存のポップアップを所有ウィンドウにする正しい方法です。

+0

あなたの答えをありがとう!しかし、これは私のアプリケーションの問題の原因ではありません。私が私の質問で言ったように、私はすべての場合に所有者を渡しています。他のアイデア? –

+0

偶然、再現性のあるサンプルがありますか? –

関連する問題