次の方法で共有


描画コードの変更 (ATL チュートリアル、パート 4)

既定では、コントロールの描画コードによって、四角形とテキスト PolyCtl が表示されます。 この手順では、さらに興味深いものを表示するようにコードを変更します。 次のタスクが含まれます。

  • ヘッダー ファイルの変更

  • OnDraw 関数の変更

  • 多角形のポイントを計算するメソッドの追加

  • 塗りつぶしの色の初期化

ヘッダー ファイルの変更

まず、多角形のポイントの計算に使用される数値演算関数 sincos のサポートを追加し、位置を格納するための配列を作成します。

ヘッダー ファイルを変更するには

  1. PolyCtl.h の先頭に行 #include <math.h> を追加します。 ファイルの先頭は次のようになります。

    #include <math.h>
    #include "resource.h"       // main symbols
    
  2. IProvideClassInfo インターフェイスを実装し、次のコードを PolyCtl.h に追加することで、コントロールのメソッド情報を提供します。 CPolyCtl クラスで、次のように行を置き換えます。

    public CComControl<CPolyCtl>
    

    with

    public CComControl<CPolyCtl>,
    public IProvideClassInfo2Impl<&CLSID_PolyCtl, &DIID__IPolyCtlEvents, &LIBID_PolygonLib>
    

    また、BEGIN_COM_MAP(CPolyCtl) には次の行を追加します。

    COM_INTERFACE_ENTRY(IProvideClassInfo)
    COM_INTERFACE_ENTRY(IProvideClassInfo2)
    
  3. 多角形のポイントが計算されると、それらは POINT 型の配列に格納されます。そのため、PolyCtl.h の定義ステートメント short m_nSides; の後に配列を追加します。

    POINT m_arrPoint[100];
    

OnDraw メソッドの変更

ここで、PolyCtl.h の OnDraw メソッドを変更する必要があります。 追加するコードで、多角形の描画に使用する新しいペンとブラシを作成します。次に、Win32 API 関数 Ellipse および Polygon を呼び出して、実際の描画を実行します。

OnDraw 関数を変更するには

  1. PolyCtl.h の既存の OnDraw メソッドを次のコードに置き換えます。

    HRESULT CPolyCtl::OnDraw(ATL_DRAWINFO& di)
    {
       RECT& rc = *(RECT*)di.prcBounds;
       HDC hdc  = di.hdcDraw;
    
       COLORREF    colFore;
       HBRUSH      hOldBrush, hBrush;
       HPEN        hOldPen, hPen;
    
       // Translate m_colFore into a COLORREF type
       OleTranslateColor(m_clrFillColor, NULL, &colFore);
    
       // Create and select the colors to draw the circle
       hPen = (HPEN)GetStockObject(BLACK_PEN);
       hOldPen = (HPEN)SelectObject(hdc, hPen);
       hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);
       hOldBrush = (HBRUSH)SelectObject(hdc, hBrush);
    
       Ellipse(hdc, rc.left, rc.top, rc.right, rc.bottom);
    
       // Create and select the brush that will be used to fill the polygon
       hBrush    = CreateSolidBrush(colFore);
       SelectObject(hdc, hBrush);
    
       CalcPoints(rc);
       Polygon(hdc, &m_arrPoint[0], m_nSides);
    
       // Select back the old pen and brush and delete the brush we created
       SelectObject(hdc, hOldPen);
       SelectObject(hdc, hOldBrush);
       DeleteObject(hBrush);
    
       return S_OK;
    }
    

多角形のポイントを計算するメソッドの追加

多角形の周囲を構成するポイントの座標を計算する、CalcPoints というメソッドを追加します。 これらの計算は、関数に渡される RECT 変数に基づいて行われます。

CalcPoints メソッドを追加するには

  1. CalcPoints の宣言を PolyCtl.h 内の CPolyCtl クラスの IPolyCtl パブリック セクションに追加します。

    void CalcPoints(const RECT& rc);
    

    CPolyCtl クラスのパブリック セクションの最後の部分は次のようになります。

       void FinalRelease()
       {
       }
    public:
       void CalcPoints(const RECT& rc);
    
  2. CalcPoints 関数のこの実装を PolyCtl.cpp の最後に追加します。

    void CPolyCtl::CalcPoints(const RECT& rc)
    {
       const double pi = 3.14159265358979;
       POINT   ptCenter;
       double  dblRadiusx = (rc.right - rc.left) / 2;
       double  dblRadiusy = (rc.bottom - rc.top) / 2;
       double  dblAngle = 3 * pi / 2;          // Start at the top
       double  dblDiff  = 2 * pi / m_nSides;   // Angle each side will make
       ptCenter.x = (rc.left + rc.right) / 2;
       ptCenter.y = (rc.top + rc.bottom) / 2;
    
       // Calculate the points for each side
       for (int i = 0; i < m_nSides; i++)
       {
          m_arrPoint[i].x = (long)(dblRadiusx * cos(dblAngle) + ptCenter.x + 0.5);
          m_arrPoint[i].y = (long)(dblRadiusy * sin(dblAngle) + ptCenter.y + 0.5);
          dblAngle += dblDiff;
       }
    }
    

塗りつぶしの色の初期化

既定の色で m_clrFillColor を初期化します。

塗りつぶしの色を初期化するには

  1. この行を PolyCtl.h の CPolyCtl コンストラクターに追加して、既定の色として緑色を使用します。

    m_clrFillColor = RGB(0, 0xFF, 0);
    

これでコンストラクターは次のようになります。

CPolyCtl()
{
   m_nSides = 3;
   m_clrFillColor = RGB(0, 0xFF, 0);
}

コントロールのビルドとテスト

コントロールをリビルドします。 PolyCtl.htm ファイルがまだ開いている場合は閉じたことを確認してから、[ビルド]メニューの [Build Polygon]\(多角形のビルド\) をクリックします。 PolyCtl.htm ページで再度コントロールを表示することもできますが、ここでは、ActiveX コントロール テスト コンテナーを使用します。

ActiveX コントロール テスト コンテナーを使用するには

  1. ActiveX コントロール テスト コンテナーをビルドして開始します。 TSTCON サンプル: ActiveX コントロール テスト コンテナーは、GitHub にあります。

    Note

    ATL::CW2AEX に関連するエラーが発生した場合、Script.Cpp の行 TRACE( "XActiveScriptSite::GetItemInfo( %s )\n", pszNameT );TRACE( "XActiveScriptSite::GetItemInfo( %s )\n", pszNameT.m_psz ); に、行 TRACE( "Source Text: %s\n", COLE2CT( bstrSourceLineText ) );TRACE( "Source Text: %s\n", bstrSourceLineText ); に置き換えます。
    HMONITOR に関連するエラーが発生した場合は、TCProps プロジェクトの StdAfx.h を開いて、次のように置き換えます。

    #ifndef WINVER
    #define WINVER 0x0400
    #endif
    

    with

    #ifndef WINVER
    #define WINVER 0x0500
    #define _WIN32_WINNT 0x0500
    #endif
    
  2. テスト コンテナー[編集] メニューで、[新しいコントロールを挿入] をクリックします。

  3. PolyCtl class という名前のコントロールを探し、[OK] をクリックします。 円の中に緑色の三角形が表示されます。

次の手順に従って、辺の数を変更します。 テスト コンテナー内でデュアル インターフェイスのプロパティを変更するには、[メソッドの呼び出し] を使用します。

テスト コンテナー内でコントロールのプロパティを変更するには

  1. テスト コンテナーで、[コントロール] メニューの [メソッドの呼び出し] をクリックします。

    [メソッドの呼び出し] ダイアログ ボックスが表示されます。

  2. [メソッド名] ボックスの一覧から、[辺] プロパティの [PropPut] バージョンを選択します。

  3. [パラメーター値] ボックスに 5 を入力し、[値の設定] をクリックし、[呼び出し] をクリックします。

コントロールは変更されないことに注意してください。 m_nSides 変数を設定することで、辺の数を内部で変更しましたが、これではコントロールは再描画されません。 別のアプリケーションに切り替えてからテスト コンテナーに戻ると、コントロールが再描画されて、正しい辺の数になっていることを確認できます。

この問題を修正するには、辺の数を設定した後で、IViewObjectExImpl に定義された FireViewChange 関数の呼び出しを追加します。 コントロールがそれ自体のウィンドウで実行されている場合、FireViewChangeInvalidateRect メソッドを直接呼び出します。 コントロールがウィンドウなしで実行されている場合、InvalidateRect メソッドはコンテナーのサイト インターフェイス上で呼び出されます。 これにより、コントロールが強制的に自動で再描画されます。

FireViewChange への呼び出しを追加するには

  1. FireViewChange への呼び出しを put_Sides メソッドに追加して PolyCtl.cpp を更新します。 終了すると、put_Sides メソッドは次のようになります。

    STDMETHODIMP CPolyCtl::put_Sides(short newVal)
    {
       if (2 < newVal && newVal < 101)
       {
          m_nSides = newVal;
          FireViewChange();
          return S_OK;
       }
       else
       {
          return Error(_T("Shape must have between 3 and 100 sides"));
       }
    }
    

FireViewChange を追加した後で、ActiveX コントロール テスト コンテナーでコントロールをリビルドして再試行します。 今回は、辺の数を変更して Invoke をクリックすると、コントロールの変更がすぐに表示されます。

次の手順では、イベントを追加します。

手順 3 に戻る | 手順 5 に進む

関連項目

チュートリアル
テスト コンテナーでのプロパティとイベントのテスト