親ウィンドウに対する EnableWindowについて

[戻る]
サウロ 2010/05/25(火) 12:42:05
環境:
WinXP Pro SP2
VC2005 standard 非MFC

http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+201005/10050018.txt
上記に関して、画像の四隅が透明色になっているため結局自分でダイアログクラスをつく
ることにしました。
下記の様にEnableWindow(親窓, FALSE )にしたところ、子ウィンドウについてもクリッ
クイベントを検知してくれなくなってしまいました。
CreateWindow の内部からはプロシージャは呼ばれていますが、メッセージループに入っ
てからはプロシージャに貼ったブレークポイントには止まってくれません。

ところがIsWindowEnabled(子窓)の戻り値は1になっています。
何がまずいのでしょうか?
よろしくお願いします。

LRESULT CALLBACK DialogProc( HWND hWnd, UINT message, WPARAM wparam, LPARAM
lparam ){
    switch( message ){
    case WM_LBUTTONDOWN:
        PostMessage( hWnd, WM_CLOSE, 0, 0 );
        return 0;
    }

    return DefWindowProc(hWnd,message,wparam,lparam);
}

void CDialog::Show(){
    EnableWindow( m_hParentWnd, FALSE );

    WNDCLASSEX wcex;
    wcex.cbSize        = sizeof(WNDCLASSEX);
    wcex.style        = 0;
    wcex.lpfnWndProc    = DialogProc;
    wcex.cbClsExtra        = 0;
    wcex.cbWndExtra        = 0;
    wcex.hInstance        = m_hInst;
    wcex.hIcon        = NULL;
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName    = NULL;
    wcex.lpszClassName    = L"Dialog";
    wcex.hIconSm        = NULL;

    RegisterClassEx(&wcex);
 
    m_hWnd = CreateWindowEx( 0,
        L"Dialog",
        L"Dialog",
        WS_CHILD,
        0,
        0,
        200,
        130,
        m_hParentWnd,
        (HMENU)0,
        m_hInst,
        0);

    ShowWindow( m_hWnd, SW_SHOW );
    UpdateWindow( m_hWnd );

    int e = IsWindowEnabled( m_hWnd );
    char buf[128];
    sprintf( buf, "%d\n", e );
    OutputDebugStringA( buf );

    while( 1 ){
        MSG msg;
        GetMessage( &msg, m_hWnd, 0, 0 );
        TranslateMessage( &msg );
        DispatchMessage( &msg );
        if( msg.message == WM_LBUTTONDOWN ) break;
    }
    UnregisterClass( L"Dialog", m_hInst );
    EnableWindow( m_hParentWnd, TRUE );
    SetActiveWindow( m_hParentWnd );
}

仲澤@失業者 2010/05/25(火) 13:22:36
あるウインドウを無効にすると、その子ウインドウも無効になるからでは
ないでしょうか。子の無効化はWM_ENABLEを送付せずに実行されるため、
フラグ上は有効になっていると思います。IsWindowEnabled()は、対象
HWNDのWS_DISABLEDフラグを参照するだけです。

サウロ 2010/05/25(火) 13:41:30
回答ありがとうございます。

それではモーダルウィンドウはどのように実現されているのでしょうか?
いろいろ検索してみましたが、どれも EnableWindow を使えとしか書いておらず困ってい
ます。

サウロ 2010/05/25(火) 13:47:59
親子関係にしないで、メインウィンドウをディセイブルにすれば一応いけるみたいですね。

しかしこうするとタスクバーに両方のウィンドウが表示されるのが少し気になります。
表示されても特に問題はないのですし、ひょっとしたら消す方法もあるのかもしれません
が、あまり美しくない気がします。

仲澤@失業者 2010/05/25(火) 15:28:59
なぜ自作でモーダルDLGもどきを作ろうとしているのかが理解できません。
対象画像をDLGの背景にするのも、対象画像を表示するコントロールを
貼り付けるのも、通常のモーダルDLGでできるはずなのですが。
以前のスレにも書きましたがモーダルDLGもどきの実装は「大変」です。
コストに見合う後かがあるとは思えないのですが・・・。

仲澤@失業者 2010/05/25(火) 16:03:36
誤)コストに見合う後かがあるとは思えないのですが・・・。
正)コストに見合う効果があるとは思えないのですが・・・。
に訂正します。

サウロ 2010/05/25(火) 16:17:50
半分は勉強というか興味本位です。

ただ、画像の隅のほうが透明色なので、普通に貼り付けるとその部分はダイアログの背景
が描画されてしまいます。

SetClassLong で HOLLOW_BRUSHを指定してもうまくいかないようですね。
もどきを作らずにうまくやる方法をご存知でしたらご教授ください。

maru 2010/05/25(火) 16:24:11
> なぜ自作でモーダルDLGもどきを作ろうとしているのかが理解できません。
仲澤さんの意見に全面的に賛成します。あえて困難な道を歩もうとするなら別ですが。

# 最近MFCなしでウィンドウプログラムを組んでないので、サウロさんのコードでは
# 現象を再現できず、問題解決のヒントを差し上げることが出来ません。
# あしからず。

サウロ 2010/05/25(火) 16:35:44
[[解決]]
ダイアログプロシージャに下記を追加することで解決しました。
ありがとうございます。

case WM_CTLCOLORDLG:
        return (BOOL)GetStockObject( HOLLOW_BRUSH );

古いスレッドには追加発言できません。