4

MFC/非.netアプリのモーダルダイアログボックスにライトボックススタイルの背景調光を実装した人はいますか?
手順は次のようにする必要があると思います。

手順:

  1. ダイアログの親 HWND または CWnd を取得*

  2. 親ウィンドウの四角形を取得し、そのウィンドウの上に半透明のオーバーレイを描画します

  3. ダイアログがモーダル描画ルーチンを実行できるようにします。例: DoModal()

これを行うための既存のライブラリ/フレームワークはありますか、または MFC で半透明のオーバーレイをドロップする最良の方法は何ですか?
編集「ライトボックススタイル」が何を意味するのかわからない場合に達成しようとしているもののモックアップです
Some App
代替テキスト

ライトボックス ダイアログ ボックスで
代替テキスト

4

2 に答える 2

4

ブライアンのリンクに基づいて私がやったことは次のとおりです*
まず、プロパティを使用してダイアログリソースを作成します。

  • ボーダーFALSE
  • 3D ルックFALSE
  • クライアント エッジFALSE
  • ポップアップスタイル
  • 静的エッジFALSE
  • 透過TRUE
  • タイトルバーFALSE

フレームも何もなく、灰色のボックスだけのダイアログ ウィンドウが表示されます。Create 関数を次のようにオーバーライドします。

BOOL LightBoxDlg::Create(UINT nIDTemplate, CWnd* pParentWnd)
{

    if(!CDialog::Create(nIDTemplate, pParentWnd))
        return false;
    RECT rect;
    RECT size;

    GetParent()->GetWindowRect(&rect);
    size.top = 0;
    size.left = 0;
    size.right = rect.right - rect.left;
    size.bottom = rect.bottom - rect.top;
    SetWindowPos(m_pParentWnd,rect.left,rect.top,size.right,size.bottom,NULL);

    HWND hWnd=m_hWnd;  
    SetWindowLong (hWnd , GWL_EXSTYLE ,GetWindowLong (hWnd , GWL_EXSTYLE ) | WS_EX_LAYERED ) ;
    typedef DWORD (WINAPI *PSLWA)(HWND, DWORD, BYTE, DWORD);
    PSLWA pSetLayeredWindowAttributes;
    HMODULE hDLL = LoadLibrary (_T("user32"));
    pSetLayeredWindowAttributes = 
        (PSLWA) GetProcAddress(hDLL,"SetLayeredWindowAttributes");
    if (pSetLayeredWindowAttributes != NULL) 
    {
        /*
        * Second parameter RGB(255,255,255) sets the colorkey 
        * to white LWA_COLORKEY flag indicates that color key 
        * is valid LWA_ALPHA indicates that ALphablend parameter 
        * is valid - here 100 is used
        */
        pSetLayeredWindowAttributes (hWnd, 
            RGB(255,255,255), 100, LWA_COLORKEY|LWA_ALPHA);
    }


    return true;
}

次に、画像エディターで小さな黒いビットマップ (48x48 など) を作成し、それをビットマップ リソース (この例では IDB_BITMAP1) としてインポートし
ます。WM_ERASEBKGND メッセージを次のようにオーバーライドします。

BOOL LightBoxDlg::OnEraseBkgnd(CDC* pDC)
{

    BOOL bRet = CDialog::OnEraseBkgnd(pDC);

    RECT rect;
    RECT size;
    m_pParentWnd->GetWindowRect(&rect);
    size.top = 0;
    size.left = 0;
    size.right = rect.right - rect.left;
    size.bottom = rect.bottom - rect.top;

    CBitmap cbmp;
    cbmp.LoadBitmapW(IDB_BITMAP1);
    BITMAP bmp;
    cbmp.GetBitmap(&bmp);
    CDC memDc;
    memDc.CreateCompatibleDC(pDC);
    memDc.SelectObject(&cbmp);
    pDC->StretchBlt(0,0,size.right,size.bottom,&memDc,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);

    return bRet;
}

目的のダイアログの DoModal でインスタンス化し、モーダル ダイアログのようにスタック (または必要に応じてヒープ) に作成し、Create を手動で呼び出して表示し、その上に実際のモーダル ダイアログを作成します。

INT_PTR CAboutDlg::DoModal()
{
    LightBoxDlg Dlg(m_pParentWnd);//make sure to pass in the parent of the new dialog
    Dlg.Create(LightBoxDlg::IDD);
    Dlg.ShowWindow(SW_SHOW);

    BOOL ret = CDialog::DoModal();

    Dlg.ShowWindow(SW_HIDE);
    return ret;
}

これにより、上記のモックアップ とまったく同じ結果が得られます

※最初からダイアログボックスを作らずにやったり、その他全般的な整理をしたりと、まだまだ改善の余地があります。

于 2008-09-10T15:13:03.387 に答える
2

ウィンドウを作成して透明度を設定するだけでよいと思います。CodeProjectに MFC CGlassDialog サンプルがあり、参考になるかもしれません。Win32 API でこれを行う方法に関する記事もあります。

于 2008-09-09T14:13:24.007 に答える