none
SetLayeredWindowAttributes()でマウス透過が逆転する RRS feed

  • 質問

  • SetLayeredWindowAttributes()でマウス透過が逆転する

    環境:Vista。Visual Studio 2008。MFCを使用。ダイアログベースWindowを開発中

    SetLayeredWindowAttributes()の第3番目の引数をLWA_COLORKEYにして、
    赤色0x000000ff(又は青色0x00ff0000)を透明に設定した場合、赤色(又は青色)は透明になります(当たり前)。
    しかし、その透明の箇所をマウスでクリックしても、裏にある別のアプリケーションを触ることができません。、
    そして、何故か、青色(又は赤色)をクリックすると、裏にある別のアプリケーションを触れてしまいます。
    透明ではない個所(青色(又は赤色))をクリックすると、その裏のAPを触ってしまえるのは変です。
    白、黒及び緑色を透明に設定した場合には、上記問題は発生しません。
    また、Windows XP で実行させると、上記問題は発生しません。
    VistaとWindows7でこの問題が発生します。

    VistaやWindows7では、SetLayeredWindowAttributes()の描画は正常なのですが、
    マウス関連が青色と赤色で反転しているようです。
    どのようにすれば、VistaやWindows7で、青色及び赤色を正常に透明にできるのでしょうか。

    再現のための手順は下記のとおりです。
    赤(0x000000ff)、緑(0x0000ff00)、青(0x00ff0000)、白(0x00ffffff)及び黒(0x00000000)の計5色を
    1枚の画像内に描き、BMP画像ファイルとして保存します。
    これをダイアログベースWindowに正常に描画するようプログラミングします。
    OnInitDialog()内で下記のように書きます。

    	//MFCを使用。OnInitDialog()で下記を実行
    
    	BOOL b;
    
    	COLORREF crKey;
    
    	b = ModifyStyleEx(0, WS_EX_LAYERED);//正常終了
    
    	//crKey = 0x00ffffff;//白色が完全な透明色になる。問題なし。
    
    	//crKey = 0x00000000;//黒色が完全な透明色になる。問題なし。
    
    	//crKey = 0x0000ff00;//緑色が完全な透明色になる。問題なし。
    
    	crKey = 0x000000ff;//赤色が完全な透明色になる。
    
    	//しかし、青色(0x00ff0000)でマウスが透過し、赤色でマウスが透過しない。
    
    	//crKey = 0x00ff0000;//青色が完全な透明色になる。上記のような問題あり。
    
    	b = SetLayeredWindowAttributes(crKey, 0, LWA_COLORKEY);//正常終了
    
    
    
    

    再現状況の追加
    先程は、画像ファイルを作成し、それを読み込み表示するように書きましたが、
    ダイアログボックスにPicture Controlを貼り付け、それを青色や赤色で塗ってもよいです。
    OnPaint()で次のように書きます。
    	//m_Pic及びm_Pic2はPicture Controlです。
    	CRect rect;
    	CDC *pCDC;
    
    	CBrush RedBrush(0x000000ff);
    	CBrush BlueBrush(0x00ff0000);
    
    	m_Pic.GetClientRect(&rect);
    	pCDC = m_Pic.GetDC();
    	pCDC->FillRect(rect, &RedBrush);
    	m_Pic.ReleaseDC(pCDC);
    
    	m_Pic2.GetClientRect(&rect);
    	pCDC = m_Pic2.GetDC();
    	pCDC->FillRect(rect, &BlueBrush);
    	m_Pic2.ReleaseDC(pCDC);




    2010年2月14日 17:16

回答

すべての返信

  • DWMが有効の場合だけ発生する現象ですね。
    MFCを使わずにAPIだけで確認しても発生します。

    DWMの不具合のような挙動です。

    古い話ですが、以下のような投稿があります。

    [Layered Windows mouse event bug]
      http://social.msdn.microsoft.com/Forums/en-US/windowsuidevelopment/thread/7f44efaf-afc3-435a-8dd0-1c0146a6ee52
      最後の投稿が参考になりますでしょうか。

    望みは薄いですが、UpdateLayeredWindowIndirectを試してみるか、
    Direct 2Dに移行してみては如何でしょうか。

    [UpdateLayeredWindowIndirect]
      http://msdn.microsoft.com/en-us/library/ms633557(VS.85).aspx

    [Layered Windows with Direct2D]
      http://msdn.microsoft.com/en-us/magazine/ee819134.aspx

    2010年2月16日 23:33
  • 貴重な回答を頂きありがとうございました。
    私の環境だけが、このような問題を発生させているのではないことが分り助かりました。

    ご指摘のURLの質問者は顧客からの指摘を受けたようですね。最後の回答者のbeBoyさんの
    This is probably an intended feature.(これは、多分意図された特徴でしょう。)
    という回答のとおりかもしれません。確かに、2006年から起こっていた現象ですからね。
    何故このような不都合を意図したのかという疑問は残りますが(笑)

    私は、アプリケーション利用者に任意の色を選択してもらって、それを透明色にするプログラムを開発中でした。
    そのためにはSetLayeredWindowAttributes()はとても有益な関数でした。
    「青と赤は選択するな」という注意書きを添えて出荷するという方法もあるかもです(笑)。

    CRngとSetWindowRgn()を使っても実現はできますが、これは大昔の技術です。

    UpdateLayeredWindowIndirect()とかDirect 2Dとかを検討してみます。

    ありがとうございました。

    2010年2月17日 19:04