콤보박스를 투명하게 만들일이야 없겠지만, 한번 도전해봤습니다.
하지만 불완전한 구현이 되고 말았습니다.
리스트박스가 보일경우 리스트의 스크롤바 무브 이벤트를 처리하지 못하겠더군요.. -_-;
스크롤바를 드래그해서 움직일 경우 잔상이 남습니다.
[요 부분에 대한 아이디어가 있으신 분은.. 메시지좀 남겨주시와요 ^^]
기본적인 아이디어:
리스트 박스가 그려질 영역만큼, 보여지기 전에 미리 화면을 캡처 해놓은 다음에..
드롭된 리스트의 배경에 캡처된 화면을 그려주면 투명한 것처럼 보일 것이다.
// 윈도우 화면에서 주어진 사격형 만큼을 캡처해서 비트맵으로 넘겨준다.
// 저 콤보박스의 리스트 영역의 배경을 직접 그려주어 투명한것 처럼 보여주는
// 꽁수를 쓰기 위해서 필요한 함수.
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);
}
원하는 만큼 깔끔한 코드가 나오지는 못했지만, 드롭리스트에 스크롤바만 않생기면..
그럭저럭 설렁 설렁 넘어갈만 하다고.. 생각만 해봅니다. ㅜㅜ