2011-12-04 3 views
2

바탕 화면 위에 투명한 창을 만들고 싶습니다.
그 목적을 위해 데스크톱의 배경 (데스크톱의 HBITMAP 생성 및 HDC에 적용)으로 HDC를 만들고 UpdateLayeredWindow을 호출했습니다.바탕 화면 배경으로 기존 HBITMAP 재설정 (Win32)

지금까지 그렇게 좋았습니다. 성능 문제에 대해서는
영구 GDI + 개체를 유지해야하므로 내 HDC 및 HBITMAP은 그림간에 동일한 핸들을 유지해야합니다 (데스크톱 DC는 변경되지 않았다고 가정). this question과 동일합니다.

처음 페인팅 반복에서 모두 잘됩니다. 두 번째 페인팅 반복에서 HDC와 HBITMAP는 변경되지 않았기 때문에 기존 HDC에서 다시 칠합니다. 이중 이미지 (배경이 지워지지 않음)를 얻음을 의미합니다.

bool SomeUI::Draw() 
{ 
    BLENDFUNCTION blend = {0}; 
    POINT ptPos = {0}; 
    SIZE sizeWnd = {0}; 
    POINT ptSrc = {0}; 
    BOOL bUpdate = FALSE; 

    // Get the client rect 
    RECT rctWindow; 
    bool bGot = GetWindowRect(rctWindow); 
    if (!bGot) 
     return false; 

    // Get the desktop's device context 
    HDC hDCDesktop = GetDC(NULL); 
    if (!hDCDesktop) 
     return false; 

    int nWidth = abs(rctWindow.right - rctWindow.left); 
    int nHeight = abs(rctWindow.bottom - rctWindow.top); 

    // Create 32Bit bitmap to apply PNG transparency 
    VOID *ppvBits = NULL; 
    BITMAPINFO BitmapInfo = {0}; 
    BitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
    BitmapInfo.bmiHeader.biWidth = nWidth; 
    BitmapInfo.bmiHeader.biHeight = nHeight; 
    BitmapInfo.bmiHeader.biPlanes = 1; 
    BitmapInfo.bmiHeader.biBitCount = 32; 
    BitmapInfo.bmiHeader.biCompression = BI_RGB; 

    HBITMAP hBmp = CreateDIBSection(hDCDesktop, &BitmapInfo, DIB_RGB_COLORS, &ppvBits, NULL, 0); 
    if (!hBmp || hBmp==(HBITMAP)ERROR_INVALID_PARAMETER) 
     goto releaseHandles; 

    // Create a compatible DC and select the newly created bitmap 
    if (!m_hDC) 
    { 
     m_hDC = CreateCompatibleDC(hDCDesktop); 
     if (!m_hDC) 
      goto releaseHandles; 

     SelectObject(m_hDC, hBmp); 
    } 
    else 
    { 
     /////////////////////////////////////////////////////////////////////// 
     // 
     // The problem lies here, this is where I need to reset the HBITMAP 
     // according to the desktop here (to have a transparent DC to work on) 
     // 
     /////////////////////////////////////////////////////////////////////// 
    } 

    // The drawing logic 
    bool bInnerDraw = Draw(m_hDC); 
    if (!bInnerDraw) 
     goto releaseHandles; 

    // Call UpdateLayeredWindow 
    blend.BlendOp = AC_SRC_OVER; 
    blend.SourceConstantAlpha = 255; 
    blend.AlphaFormat = AC_SRC_ALPHA; 
    sizeWnd.cx = nWidth; 
    sizeWnd.cy = nHeight; 
    ptPos.x = rctWindow.left; 
    ptPos.y = rctWindow.top; 
    bUpdate = UpdateLayeredWindow(m_hWnd, hDCDesktop, &ptPos, &sizeWnd, m_hDC, &ptSrc, 0, &blend, ULW_ALPHA); 
    if (!bUpdate) 
     goto releaseHandles; 

releaseHandles: 
    // releasing handles 
} 

어떤 아이디어 :

여기에 내가 뭘하는지의 코드 예제가? 영구 HBITMAP을 재설정하기 위해

는, (미리 알림 :이 같은 핸들을 유지 필요), 우리는 임시 HBITMAP으로 그 지역의 바탕 화면 배경을 설정하고에 복사합니다

답변

2

는 대답 발견 영구 HBITMAP.
, 우리는 임시 HDC를 작성하고 임시 HBITMAP을 선택하고 지속적인 HDC에 임시 HDC를 복사 할 수 있습니다 그 (다른 하나 HBITMAP에서 복사)을 달성하기 위해, USINT 비트 블리트

은 여기입니다 코드 :

 hBmpTemp = CreateDIBSection(hDCDesktop, &BitmapInfo, DIB_RGB_COLORS, &ppvBits, NULL, 0); 
     if (!hBmpTemp || hBmpTemp==(HBITMAP)ERROR_INVALID_PARAMETER) 
      goto releaseHandles; 

     HDC hTempDC = CreateCompatibleDC(NULL); 
     if (!hTempDC) 
      goto releaseHandles; 

     SelectObject(hTempDC, hBmpTemp); 

     ::BitBlt(m_hPersistentDC, 0, 0, nWidth, nHeight, hTempDC, rctWindow.left, rctWindow.top, SRCCOPY); 

     ::DeleteDC(hTempDC);