2012-11-14 1 views
5

나는 깊이가 32 비트이고 알파 채널 (ARGB)을 사용하는 DIB 섹션의 화면 비트 맵에 텍스트를 그립니다. 픽셀을 메모리에 직접 그립니다. 그런 다음 Gdiplus Graphics 객체를 만들고, 메모리 DC를 전달하고 Graphics :: DrawString을 사용하여 텍스트를 그립니다. 정상적인 상황에서는 정상적으로 작동합니다. 그러나 원격 데스크톱에서는 렌더링 된 텍스트가 완전히 투명하게 표시됩니다. 즉, 색상 픽셀을 그리는 대신 텍스트의 위치를 ​​볼 수 있습니다. 아무도 왜 이렇게, 그리고 그것을 고칠 방법을 알고 있습니까 ?? 나는Gdiplus DrawString은 원격 데스크톱을 통해 투명 텍스트를 그립니다.

gfx.Flush (Gdiplus::FlushIntentionSync); 

편집을 수행 DIB에 텍스트를 그린 후

BITMAPV5HEADER bhd; 
memset (&bhd, 0, sizeof (bhd)); 
bhd.bV5Size = sizeof (BITMAPV5HEADER); 
bhd.bV5Width = nWidth; 
bhd.bV5Height = -nHeight; // negative height indicates top-down DIB 
bhd.bV5Planes = 1; 
bhd.bV5BitCount = 32; 
bhd.bV5Compression = BI_BITFIELDS; 
bhd.bV5RedMask = 0x00FF0000; 
bhd.bV5GreenMask = 0x0000FF00; 
bhd.bV5BlueMask = 0x000000FF; 
bhd.bV5AlphaMask = 0xFF000000; 
m_pBuf = NULL; 
m_hBmp = ::CreateDIBSection (m_hDC, (BITMAPINFO *) &bhd, DIB_RGB_COLORS, 
    (void **) &m_pBuf, NULL, 0); 
if (m_hBmp == NULL || m_pBuf == NULL) 
    { 
    // error... 
    } 
HGDIOBJ oldObj = ::SelectObject (m_hDC, m_hBmp); 
if (oldObj == NULL) 
    { 
    // error... 
    } 

:

여기 내 졸라 매는 끈 루틴입니다 :

void SplashScreen::drawString (MyString &ivText, Gdiplus::RectF &r, 
    Gdiplus::ARGB c, Gdiplus::StringAlignment align, Gdiplus::Font &fnt, 
    Gdiplus::Graphics &gfx) 
    { 
    Gdiplus::StringFormat fmt; 
    fmt.SetAlignment (align); 
    Gdiplus::SolidBrush brush (c); 
    wchar_t *wstr = new wchar_t [ivText.length()+1]; 
    std::mbstowcs (wstr, ivText.cstr(), ivText.length()+1); 
    gfx.DrawString (wstr, ivText.length(), &fnt, r, &fmt, &brush); 
    delete wstr; 
    } 

그리고 내가 DIB를 만드는 방법이 DIB가 마지막으로 그려진 창은 WS_EX_LAYERED 창입니다. 이 응용 프로그램이 시작될 때 표시하는 시작 화면, 그리고 천천히 그리고 타이머 다음과 같은 방법을 사용하여 페이드 아웃 :이 이제까지 작동 놀랐어요

void SplashScreen::setWindowTransparency (int nAlpha) 
    // @param nAlpha: 255 is opaque, 0 is fully transparent. 
    { 
    HWND hwnd = getHwnd(); 
    BLENDFUNCTION blend; 
    blend.BlendOp = AC_SRC_OVER; 
    blend.BlendFlags = 0; 
    blend.SourceConstantAlpha = nAlpha; 
    blend.AlphaFormat = AC_SRC_ALPHA; 
    BOOL bResult = ::UpdateLayeredWindow (hwnd, NULL, NULL, NULL, NULL, 
    NULL, RGB (0, 0, 0), &blend, ULW_ALPHA); 
    } 
+0

RDP 세션의 색 농도 설정을 변경하면 어떻게됩니까? –

+0

나는 15 비트, 16 비트, 24 비트, 32 비트 (RDP 세션이 시작되기 전에 디스플레이 탭에서 설정)를 테스트했다. 이러한 모든 설정에서 동일한 문제가 발생합니다. (실제로, 32 비트는 32 비트를 나에게 보이지 않습니다. 아마 RDP가 바람을 피고 있습니까?) –

+0

영구 비트 맵 캐싱을 비활성화하는 방법은 어떻습니까? –

답변

3

. gdi32를 사용하여 그리기하면 알파 정보가 손실되고 gDi32가있는 32 비트 DIB의 모든 그림은 DIB의 알파 정보가 정의되지 않은 상태로 유지됩니다. 당신이 HDC를 주었기 때문에 GDI +는 gdi32를 거쳐야합니다.

당신은 (예 : this one로, 픽셀 데이터 포인터를 사용하는 생성자를 사용하여) 올바른 픽셀 형식으로 DIB의 메모리를 기본으로하는 GDI + 비트 맵 객체, 다음 create a Graphics object from your Bitmap를 작성해야, GDI를 사용하여 RGBA DIB에 그릴 +합니다. 이를 통해 GDI +는 직접 DIB의 메모리로 그릴 수 있으며 gdi32를 통하지 않고 알파 채널을 올바르게 처리 할 수 ​​있습니다.

물론 픽셀 당 알파가 필요하지 않은 경우 혼합 함수에서 AlphaFormat 0을 사용하여 DIB의 알파 채널을 무시하면 작업을 단순화 할 수 있습니다.

+0

이것은 대답 일지 모르지만 응용 프로그램 시작시 스플래시 화면에서만이 작업을 수행하기 때문에 응용 프로그램이 원격 데스크톱에서 실행 중인지 여부를 단순히 감지하여 문제를 "해결"하고, 그렇다면 스플래시 화면을 표시하지 않습니다 전혀 ... 싸구려, 알아. –

0

나는 당신을위한 해결책을 가지고있다. 연결할 Windows 버전을 모르지만 원격 컴퓨터에서 터미널 서비스를 위해 32 비트 색상 모드를 활성화해야 할 수 있습니다. 그렇지 않으면 클라이언트가 16 비트 모드로 제한 될 수 있습니다.

서버에서 gpedit.msc를 사용하여 "최대 색 농도 제한"옵션을 32 비트로 구성하십시오. Windows 2008/2012에서 이것은 관리 템플릿 - Windows 구성 요소 - 원격 데스크톱 서비스 - 원격 세션 환경에 있습니다.

Windows XP/Vista/7/8 컴퓨터에 연결하는 경우이 gpedit 설정을 사용할 수 있는지 확실하지 않습니다.

+0

물론 우리 응용 프로그램을 사용하는 유일한 사용자가 아니기 때문에이 작업을 수행 할 수 없습니다. 사용자가 원격 데스크톱에서 설정을 변경할 것으로 기대할 수는 없습니다. 오히려 응용 프로그램은 어느 환경에서도 작동해야합니다. –

관련 문제