5

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

これが私の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);

編集: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);
  }
4

2 に答える 2

4

これがうまくいくことに驚いています。gdi32を使用して描画すると、アルファ情報が失われます。私が理解しているように、gdi32を使用して32ビットDIBで描画すると、DIBのアルファ情報が未定義のままになります。この場合、GDI +はHDCを指定したため、gdi32を経由する必要があります。

GDI+を使用してRGBADIBに描画するには、DIBのメモリに裏打ちされたGDI +ビットマップオブジェクトを正しいピクセル形式で作成し(このようなピクセルデータポインターを取得するコンストラクターを使用)、次の場所からグラフィックスオブジェクトを作成する必要があります。あなたのビットマップ。これにより、GDI +はDIBのメモリに直接描画し、gdi32を経由せずにアルファチャネルを正しく処理できます。

もちろん、ピクセルごとのアルファが必要ない場合は、ブレンド関数でAlphaFormat 0を使用して、DIBのアルファチャネルを無視することで、作業を簡素化できます。

于 2012-11-15T20:39:28.420 に答える
0

私はあなたのために可能な解決策を持っています。接続しているWindowsのバージョンはわかりませんが、リモートコンピューターでは、ターミナルサービスに対して32ビットカラーモードを有効にする必要がある場合があります。そうしないと、クライアントが16ビットモードに制限される可能性があります。

サーバーで、gpedit.mscを使用して、[最大色深度を制限する]オプションを32ビットに構成します。Windows 2008/2012では、これは管理用テンプレート-Windowsコンポーネント-リモートデスクトップサービス-リモートセッション環境にあります。

Windows XP / Vista / 7/8コンピュータに接続している場合、このgpedit設定が使用可能かどうかはわかりません。

于 2013-02-26T23:20:02.440 に答える