Поделиться через


Изменение кода отрисовки (учебник ATL, часть 4)

По умолчанию код документа элемента управления отображается квадрат и текст PolyCtl. На данном этапе изменить код для отображения более выделения. Включены следующие задачи:

  • Изменение файла заголовка

  • Изменяя функцию OnDraw

  • Добавление метода для вычисления точки многоугольников

  • Инициализация цвет заливки

Изменение файла заголовка

Начните с добавить поддержку функции sin математические и cos, которые будут использоваться вычисляют точки многоугольника, создав массив для хранения позиции.

Изменить файл заголовка

  1. Добавить линию #include <math.h> в верхней части PolyCtl.h. Верхняя часть файла может выглядеть следующим образом:

    #include <math.h>
    #include "resource.h"        // main symbols
    
  2. После точки многоугольника, вычисляются, они будут сохраняться в массиве типа POINT, поэтому добавьте массив после определения m_nSides в PolyCtl.h:

    POINT m_arrPoint[100];
    

Изменение метода OnDraw

Теперь необходимо изменить метод OnDraw в PolyCtl.h. Код добавлении создает новую перо и кисть, которой рисуется свой многоугольник, а затем вызывает Ellipse и функции api-интерфейса Win32 Polygon выполнение фактического документа.

Изменить функцию OnDraw

  • Замените существующий метод OnDraw в PolyCtl.h следующим кодом:

    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 к шагу IPolyCtl public класса CPolyCtl в PolyCtl.h:

    void CalcPoints(const RECT& rc);
    

    Последняя часть открытого раздела класса CPolyCtl будет выглядеть следующим образом:

       void FinalRelease()
       {
       }
    public:
       STDMETHOD(get_Sides)(short* pVal);
       STDMETHOD(put_Sides)(short newVal);
       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 по умолчанию цветом.

Инициализация цвет заливки

  • Используйте зеленый цвет по умолчанию - цвет путем добавления к конструктору эта линия CPolyCtl в PolyCtl.h:

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

Конструктор теперь выглядит следующим образом:

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

Построение и тестирование элемента управления

Перестройте элемент управления. Убедитесь, что файл PolyCtl.htm, чтобы закрыть, если он еще открыт, а затем нажмите кнопку Постройте многоугольник в меню Построение. Можно просмотреть элемент управления еще раз с веб-страницы PolyCtl.htm, но эта использование времени тестовый контейнер элементов управления ActiveX.

Использовать тестовый контейнер элементов управления ActiveX

  1. Постройте и запустите тестовый контейнер элементов управления ActiveX. Дополнительные сведения см. в разделе Образец TSTCON: Тестовый контейнер элементов управления ActiveX.

  2. В тестовом контейнере, в меню Изменить нажмите кнопку Вставьте новый элемент управления.

  3. Найдите элемент управления, который будет вызывать PolyCtl Class и нажмите кнопку ОК. Отобразится зеленый треугольник внутри цикла.

Попробуйте изменить число его сторон с помощью следующей процедуры. Чтобы изменить свойства двойном интерфейсе, используйте Invoke Methods из тестового контейнера.

Изменить свойство элемента управления из тестового контейнера

  1. В тестовом контейнере, щелкните Вызовите методы в меню Управление.

    Диалоговое окно Invoke - метод.

  2. Выберите версию PropPut свойства Sides из раскрывающегося списка Имя метода.

  3. Введите 5 в окне Значение параметра нажмите кнопку Задано значение и нажмите кнопку Invoke.

Обратите внимание, что элемент управления не изменяется. Хотя изменении число его сторон внутренне путем установки переменной m_nSides это не привело к элементу управления обновления. При переключении в другое приложение, а затем переключаться обратно на тестовый контейнер, обнаружится, что элемент управления обновляется и имеет правильное число его сторон.

Чтобы устранить эту проблему, добавьте вызов функции FireViewChange, указанной в IViewObjectExImpl после набора число его сторон. Если элемент управления работает в собственном окне, будут вызывать FireViewChange метод InvalidateRect напрямую. Если элемент управления выполнять безоконный, то метод InvalidateRect будет вызвана применительно к интерфейсу сайта контейнера. Это заставит элемент управления обновления.

Добавить вызов FireViewChange

  • Обновление PolyCtl.cpp путем добавления вызов FireViewChange методу put_Sides. После завершения метода 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 на

См. также

Задачи

Тестирование свойств и событий с использованием тестового контейнера

Ссылки

Учебник по активной библиотеке шаблонных классов (ATL)