0

CButtonを継承し、uxtheme.dll(BP_PUSHBUTTONを使用したDrawThemeBackground)を使用して描画するカスタムボタンを実装しました。

すべて正常に動作しますが、ホットステータスが同じである2つのステータス(通常とプレス済み)があります。これは、ユーザーがボタンの上にカーソルを置くと、ボタンのステータス(押されているかどうか)に関係なく、同じように描画されることを意味します。

これはユーザーを少し混乱させるので、Pressed&Hotステータスでのボタンの描画方法を変更したいと思います。誰かが方法を知っていますか?

絵全体をカスタマイズすることも考えましたが、ボタンはグラデーション、ボーダー、シャドウなどを使用しているので、自分ですべてを描いて同じルック&フィールを実現するのは簡単ではありません。dllのソースコードを見つける方法やその方法を知る方法はありますか?

前もって感謝します。

ハビエル

注:CMFCButtonを使用し、OnDrawメソッドをオーバーライドすることで、やりたいことを達成できると思います。コントロールにOnDrawBorderにボタンを描画させてから、内側のボタンを自分で描画させます。しかし、押されたときにコントロールが内側のボタンをどのように描画するかを知る必要があります。これはグラデーションであり、どのように行われるかは推測できません。誰か手がかりがありますか?

4

3 に答える 3

1

2番目の質問への回答として、の代わりに派生する場合CMFCButtonは、通常のの代わりにCButtonオーバーライドできOnDraw()ます。これにより、デフォルトのボタンの背景が描画され、描画コードが実行されます。OnDrawText()DrawItem()

于 2010-05-04T13:52:41.427 に答える
1

これに実際に取り組むために私が知っている唯一の方法は、「所有者の描画」ではなく「カスタムの描画」を使用することです。カスタム描画はWindows2000に付属していますが、comctrl32 6.0(つまり、Windows XP以降)のボタンコントロールでのみ使用され、明確に文書化されておらず、MFCがサポートするのに邪魔になるものではありません。

とにかく、カスタム描画の良いところは、所有者の描画とは異なり、描画プロセスのさまざまなポイントでフックできることです。これにより、すべてを処理できます。MSDNでNM_CUSTOMDRAW通知メッセージを確認してください。

問題の他の部分である「ホット」状態の検出については、これを行う最も簡単な方法は、WM_MOUSEMOVEメッセージとTrackMouseEvent()関数を使用して、マウスがボタンの上にあるかどうかを追跡することです。

残念ながら、これは少し漠然とした答えです。カスタム描画を使用するボタンを示すために必要なコードの量は、これらの回答ボックスに入力するには少し多すぎます。ボタンに小さな矢印を追加するカスタム描画ボタン(古いWindowsバージョンでは所有者の描画にフォールバック)を使用して、そのような手法を示すプロジェクトがあります。あなたは取得することによってソースコードを見ることができます

Windows_UI_source.zip

それを開いて、「DropArrowButton」クラスを見てください。重要なビットは、OnCustomDraw()ハンドラーとそのヘルパー関数DrawControl()です。これらはさまざまなボタン描画フェーズで呼び出され、UxThemeを使用してコントロールを適切に描画します。

于 2010-05-11T15:19:12.470 に答える
1

私はついに自分がやりたいことを達成する方法を見つけました。実に簡単です。

DrawThemeBackgroundを2回呼び出します。1つ目はPBS_PRESSEDで、2つ目は状態PBS_HOTです。次に、ボタンの中央に描画されないようにExcludeClipRectを作成します。

このようなもの:

        DrawThemeBackground(    hTheme,
                                pCustomDraw->hdc, 
                                BP_PUSHBUTTON,
                                PBS_PRESSED,
                                &pCustomDraw->rc, 
                                NULL);

        CDC *pDC = CDC::FromHandle(pCustomDraw->hdc);

        CRect rectClient;
        GetClientRect(rectClient);
        CRect rectInternal = rectClient;

        rectInternal.DeflateRect(4,4);
        pDC->SelectClipRgn(NULL);
        pDC->ExcludeClipRect(&rectInternal);

        DrawThemeBackground(    hTheme,
                                pCustomDraw->hdc, 
                                BP_PUSHBUTTON,
                                PBS_HOT,
                                &pCustomDraw->rc, 
                                NULL);

        pDC->SelectClipRgn(NULL);

もちろん、これはコード全体ではありませんが、私の主張を理解するには十分だと思います。

ありがとう。

于 2010-05-12T06:35:07.890 に答える