2013-03-06 11 views
2

Я хотел бы создать приложение Direct2D с прозрачным фоном, на котором размещены несколько непрозрачных сложных элементов управления. Проблема может быть разбита на несколько подрешений:Direct2D: непрозрачные дочерние окна над прозрачным родительским окном

Архитектура: Должны ли элементы управления быть реализованы как дочерние окна? Я считаю, что это правильный подход, а именно создание многоугольников Direct2D, реализующих функциональность дочернего окна.

Я пытался осуществить это путем инициализации родительского окна:

SetWindowLong(m_hwnd, GWL_EXSTYLE, GetWindowLong(m_hwnd, GWL_EXSTYLE) | WS_EX_LAYERED); 
SetLayeredWindowAttributes(m_hwnd, 0, (255 * 50)/100, LWA_ALPHA); 

И создать дочернее окно, как WS_CHILD. Это привело к тому, что ребенок, на котором все дроны D2D, включая фон, прозрачен. Я не мог найти способ сделать ребенка непрозрачным. Когда я создаю дочернее окно как WS_POPUP или WS_OVERLAPPED проблема непрозрачности решена, но дочернее окно находится на рабочем столе, не имеющем отношения к родительскому объекту.

Многослойное окно? Я решил работать с многослойными окнами, но поскольку я нацелен на VistaSP2 и выше, могут быть лучшие решения. Я пробовал предлагаемое решение here, но я тоже не смог его реализовать.

ответ

1

Вы хотите создать окно размером 32 бит на пиксель? (Извините за то, что вы не можете комментировать, недостаточно перепечатать здесь)

В этом случае вы FORCED используете UpdateLayeredWindow (и вызов CreateDIBSection во время инициализации), независимо от того, каждый раз, когда вы закончили рисовать сцену , после того, как вы закончили рисовать сцены, как:

// Draw to your D2D1 RenderTarget here 
RECT rcWin = {0}; 
GetWindowRect(hWnd,&rcWin); 
POINT ptw = {rcWin.left,rcWin.top}; 
SIZE pts = {rcWin.right-rcWin.left,rcWin.bottom-rcWin.top}; 
POINT ptsrc = {0}; 
HDC ScreenDC = GetDC(0); 
UpdateLayeredWindow(hWnd, ScreenDC, &ptw, &pts, MemDC, &ptsrc, 0, &bf, ULW_ALPHA); 
ReleaseDC(0,ScreenDC); 

о инициализации:

RECT r = {0}; 
GetWindowRect(hWnd,&r); 
HDC scrDC = GetDC(0); 
MemDC = CreateCompatibleDC(scrDC); 
ReleaseDC(0,scrDC); 
if(!MemDC) 
    { FailInit(); } 
BITMAPINFO bmi = {0}; 
bmi.bmiHeader.biBitCount = 32; 
bmi.bmiHeader.biCompression = BI_RGB; 
bmi.bmiHeader.biPlanes = 1; 
bmi.bmiHeader.biWidth = r.right-r.left; 
bmi.bmiHeader.biHeight = r.bottom-r.top; 
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); 
DIBSectionBitmap = CreateDIBSection(MemDC,&bmi,DIB_RGB_COLORS,0,0,0); 
if(!DIBSectionBitmap) 
    return 0; 
OldBmp = (HBITMAP)SelectObject(MemDC,DIBSectionBitmap); 
// Now create the HWND D2D1 RenderTarget. 

Об освобождении ресурсов:

// Free the D2D1 RenderTarget here 
if(MemDC && OldBmp) 
    SelectObject(MemDC,OldBmp); 
if(DIBSectionBitmap) 
    DeleteObject(DIBSectionBitmap); 
if(MemDC) 
    DeleteDC(MemDC); 
MemDC = 0; 
OldBmp = 0; 
DIBSectionBitmap = 0; 

EDIT: MemDC, OldBmp и DIBSectionBitmap являются Per-Window. MemDC - это HDC. OldBmp - это HBITMAP. DIBSectionBitmap - это HBITMAP. На этом этапе вы можете нарисовать дочерние окна, как если бы они были частью вашего собственного главного окна с точностью до пикселя альфа, но вам придется обрабатывать фокусировку и обмен сообщениями самостоятельно.