سؤال

هل قام أي شخص بتطبيق تعتيم الخلفية بنمط Lightbox في مربع حوار مشروط في تطبيق MFC/non .net.
أعتقد أن الإجراء يجب أن يكون مثل:

خطوات:

  1. الحصول على الحوار الأصلي HWND أو CWnd*

  2. احصل على مستطيل النافذة الرئيسية وارسم تراكبًا بشفافية فوق تلك النافذة

  3. السماح لمربع الحوار بإجراء روتين الرسم المشروط، على سبيل المثال DoModal()

هل توجد أي مكتبات/أطر عمل موجودة للقيام بذلك، أو ما هي أفضل طريقة لإسقاط التراكب الشفاف في MFC؟
يحرر إليك نموذج بالحجم الطبيعي لما أحاول تحقيقه إذا كنت لا تعرف معنى "نمط العرض المبسط".
بعض التطبيقات:
alt text

مع مربع حوار العرض المبسط
alt text

هل كانت مفيدة؟

المحلول

إليك ما فعلته* بناءً على روابط براين
قم أولاً بإنشاء مورد حوار يحتوي على الخصائص:

  • حدود خطأ شنيع
  • نظرة ثلاثية الأبعاد خطأ شنيع
  • حافة العميل خطأ شنيع
  • النمط المنبثق
  • حافة ثابتة خطأ شنيع
  • شفاف حقيقي
  • شريط العنوان خطأ شنيع

ويجب أن ينتهي بك الأمر مع نافذة حوار بدون إطار أو أي شيء، مجرد مربع رمادي.تجاوز وظيفة الإنشاء لتبدو كما يلي:

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;
}

ثم قم بإنشاء صورة نقطية سوداء صغيرة في محرر الصور (على سبيل المثال 48 × 48) وقم باستيرادها كمورد للصور النقطية (في هذا المثال 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 لمربع الحوار المطلوب، وقم بإنشائه مثل مربع حوار مشروط، على سبيل المثال.على المكدس (أو الكومة إذا رغبت في ذلك)، اتصل بها "إنشاء" يدويًا، وأظهرها ثم أنشئ مربع حوار مشروط فعليًا فوقها:

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;
}

وهذا يؤدي إلى شيء ما بالضبط مثل نموذجي أعلاه

*لا تزال هناك أماكن للتحسين، مثل القيام بذلك دون إنشاء مربع حوار للبدء به وبعض عمليات الترتيب العامة الأخرى.

نصائح أخرى

أعتقد أنك تحتاج فقط إلى إنشاء نافذة وتعيين الشفافية.هناك MFC نموذج CGlassDialog على CodeProject قد يساعدك ذلك.هناك أيضا شرط حول كيفية القيام بذلك باستخدام Win32 APIs.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top