콤보박스를 투명하게 만들일이야 없겠지만, 한번 도전해봤습니다.
하지만 불완전한 구현이 되고 말았습니다.
리스트박스가 보일경우 리스트의 스크롤바 무브 이벤트를 처리하지 못하겠더군요.. -_-;

스크롤바를 드래그해서 움직일 경우 잔상이 남습니다.

[요 부분에 대한 아이디어가 있으신 분은.. 메시지좀 남겨주시와요 ^^]

기본적인 아이디어:
리스트 박스가 그려질 영역만큼, 보여지기 전에 미리 화면을 캡처 해놓은 다음에..
드롭된 리스트의 배경에 캡처된 화면을 그려주면 투명한 것처럼 보일 것이다.


//
윈도우 화면에서 주어진 사격형 만큼을 캡처해서 비트맵으로 넘겨준다.
//
저 콤보박스의 리스트 영역의 배경을 직접 그려주어 투명한것 처럼 보여주는
//
꽁수를 쓰기 위해서 필요한 함수.

BOOL Capture(CRect rc, CBitmap& m_Bitmap)
{
    //
화면 사이즈를 읽어온다.
    int cx = GetSystemMetrics(SM_CXSCREEN);
    int cy = GetSystemMetrics(SM_CYSCREEN);
   
    //
스크린 캡처를 위한 DC를 맹근다.
    CDC ScreenDC;
    ScreenDC.CreateDC("DISPLAY", NULL, NULL, NULL);
   
    //
비트맵을 로딩할 임시 DC를 만든다.
    CDC memDC;
    memDC.CreateCompatibleDC(&ScreenDC);
   
    //
비트맵이 살아있으면, 살짝 날려준다.
    if(m_Bitmap.m_hObject)
        m_Bitmap.DeleteObject();

    //
스크린 호환용 비트맵을 주어진 크기만큼 만든다.
    m_Bitmap.CreateCompatibleBitmap(&ScreenDC, rc.Width(), rc.Height());
   
    //
비트맵에 캡처된 화면을 그린다.
    memDC.SelectObject(&m_Bitmap);
    memDC.BitBlt(0,0,rc.Width(), rc.Height(),&ScreenDC,rc.left,rc.top, SRCCOPY);
   
    return TRUE;
}

 

HBRUSH CSssDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
 
    switch(nCtlColor)
    {
    case CTLCOLOR_STATIC:
    case CTLCOLOR_EDIT:
            pDC->SetTextColor(RGB(0, 0, 255));
            pDC->SetBkMode(TRANSPARENT);
            return (HBRUSH)GetStockObject(NULL_BRUSH);
    case CTLCOLOR_LISTBOX:
        {
            pDC->SetTextColor(RGB(255, 0, 0));
            pDC->SetBkMode(TRANSPARENT);

             // 리스트 영역의 크기를 구한다.
            CRect rc;
            pWnd->GetClientRect(rc);

            //
임시 DC를 하나 만든다.
            CDC mdc;
            mdc.CreateCompatibleDC(pDC);
            mdc.SelectObject(&m_bmp);

            //
아까 캡처해두었던 배경을 리스트의 바탕에 그려준다.
            pDC->BitBlt(0, 0, rc.Width(), rc.Height(), &mdc, 0, 0, SRCCOPY);
            return (HBRUSH)GetStockObject(NULL_BRUSH);
        }
    }

  return hbr;
}

BOOL CSssDlg::PreTranslateMessage(MSG* pMsg)
{
    if(m_combo2.GetDroppedState())
    {
        //
리스트가 보여지고 있을 때 마우스 무브 이벤트시 리스트를 갱신해준다.
        if(pMsg->message == WM_MOUSEMOVE && ::GetDlgCtrlID(pMsg->hwnd) == 1000)
            CWnd::FromHandle(pMsg->hwnd)->Invalidate();
    }

  return CDialog::PreTranslateMessage(pMsg);
}

 

// 콤보박스의 리스트가 드롭될 때 발생하는 이벤트.
void CSssDlg::OnDropdownCombo2()
{
    //
현재 콤보박스의 위치를 읽어온 후..
    CRect rc;
    m_combo2.GetWindowRect(rc);

    //
대략 오프셑을 넣은 후, 드롭된 리스트의 크기를 예상하여 넣는다.
    //
실제 드롭이 되기 전까지는 크기를 알수 없어, 적당하게 높이를 200으로 주었다.
    //
만든 사람은 본인이 높이를 아니, 적당하게 값을 주면 된다.

    rc.left += 1;
    rc.top = rc.bottom+1;
    rc.bottom += 200;

     Capture(rc, m_bmp);
}

원하는 만큼 깔끔한 코드가 나오지는 못했지만, 드롭리스트에 스크롤바만 않생기면..
그럭저럭 설렁 설렁 넘어갈만 하다고.. 생각만 해봅니다. ㅜㅜ

105.zip
0.03MB

 



+ Recent posts