2012-11-14 8 views
5

私は、32ビットの深さでアルファチャンネル(ARGB)を使用するDIBセクションのオフスクリーンビットマップにテキストを描画しています。私はピクセルを直接メモリに描画します。次に、Gdiplus Graphicsオブジェクトを作成し、メモリDCを渡し、Graphics :: DrawStringを使用してテキストを描画します。通常の状況下では正常に動作します。ただし、リモートデスクトップでは、レンダリングされるテキストは完全に透明です。すなわち、任意のカラーピクセルを描画する代わりに、テキストがどこにあるかを見ることができます。誰がなぜこれがそうであるか、それを修正する方法を知っていますか?ここでGdiplus DrawStringは、リモートデスクトップ上で透明なテキストを描画します

は私の巾着ルーチンです:

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を作成する方法は次のとおりです。

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... 
    } 

DIBにテキストを描画した後、私は

gfx.Flush (Gdiplus::FlushIntentionSync); 

EDITを実行します。それ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セッションを開始する前に表示タブで設定)をテストしました。これらすべての設定で同じ問題が発生します。 (実際には、32bitは32bitに見えません。おそらくRDPが不正行為をしているのでしょうか?) –

+0

永続的なビットマップキャッシュを無効にする方法はありますか? –

答えて

3

。 gdi32で描画するとアルファ情報が失われます。わかっているように、gdi32を使用した32ビットDIBの描画では、DIBのアルファ情報は未定義です。この場合、GDI +をgdi32に渡す必要があります。なぜなら、HDCを渡したからです。その後、GDI +を使用してRGBA DIBに描画するために

、あなたが(例えばthis oneとしての画素データポインタをとるコンストラクタを使用して、)正しいピクセル形式を使用してDIBのメモリに裏打ちされたGDI +ビットマップオブジェクトを作成する必要があり、create a Graphics object from your Bitmap。これにより、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

もちろん私は私たちのアプリケーションの唯一のユーザーではないので、私はこれを行うことはできません。ユーザーがリモートデスクトップで設定を変更することは期待できません。むしろ、アプリケーションはどちらの環境でも動作する必要があります。 –

関連する問題