2011-12-04 16 views
2

私はデスクトップ上に透明なウィンドウを作成したいと思う。
そのために、デスクトップの背景(デスクトップのHBITMAPを作成してHDCに適用したHDC)を作成し、UpdateLayeredWindowを呼び出しました。デスクトップの背景(Win32)として既存のHBITMAPをリセットする

これまでのところ、とても良いです。
パフォーマンスの問題については、持続的なGDI +オブジェクトを保持する必要があります。これは、HDCとHBITMAPが絵の間で同じハンドルを維持する必要があることを意味します(デスクトップDCは変更されないと仮定します)。this questionと同じです。

最初のペインティングでは、すべてがうまくいっています。 2回目の絵画反復では、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をリセットするために

答えて

2

は答えを見つけることが、我々は一時的なHBITMAPにその領域のデスクトップの背景を設定し、それをコピーします永続的なHBITMAP
(1つのHBITMAPから他にコピーする)ことを達成するために、我々は一時的なHDCを作成して、一時的なHBITMAPを選択して、持続的なHDCに一時的HDCをコピーします、USINT のBitBlt

ここですコード:

 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); 
関連する問題