Визуальное программирование и MFC

       

Добавление свойств


В процессе проектирования OCX-объекта можно добавлять два вида свойств: базовые и пользовательские. Несколько базовых свойств (другое название - стандартные свойства) определены и поддерживаются в базовом классе COleControl. Это общие свойства, пригодные для большинства проектируемых OLE-элементов управления: Appearance - внешний вид (например, 3-мерный или плоский); BackColor - цвет фона; BorderStyle - тиль рамки; Caption - заголовок элемента; Enabled - состояние доступен/недоступен; Font - шрифт при печати заголовка и других сообщений, связанных с элементом управления; ForeColor - цвет переднего плана; hWnd - маркер (дескриптор) окна; ReadyState - состояние готовности; Text - текст, другое название свойства Caption.

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

Member Variable - реализация свойства предполагает введение в созданный класс элемента управления переменной, видимой в контейнере. Это простейший способ реализации. Однако чаще применяются три следующих, когда наряду с переменной создаются и другие элементы класса;

Member Variable With Notification - наряду с переменной создается специальная функция уведомления. Она автоматически вызывается в каркасе приложения всякий раз при изменении значения свойства, что позволяет элементу управления должным образом отреагировать на изменение своего свойства - например, организовать свою перерисовку;

Set/Get Methods - предполагает защищенный доступ к переменной класса, задающей свойство. Хотя сама переменная будет не видима в контейнере, здесь будут доступны автоматически построенные методы Get и Set. Первый позволяет прочитать значение, второй - задать новое значение свойства. Кроме защищенности свойства, этот способ удобен тем, что позволяет организовывать дополнительные вычисления, например, в методе Set можно произвести проверку, разрещающую или запрещающую изменение свойств;




Parameterized
- параметризированная реализация применяется, когда переменная класса должна быть массивом и свойство задается не единственным скалярным значением, а совокупностью значений. Эта реализация предполагает построение методов Get и Set. Автоматически эти методы создаются с параметром, включающим индексы элемента массива.

Все свойства имеют определенный тип. Так как OLE не является частью языка Visual C++, то типы OLE отличаются от привычных типов C++. Рассмотрим основные типы OLE: BSTR - строка, каждый символ которой занимает 2 байта; I2 - целое длиной 2 байта; I4 - целое длиной 4 байта; UI4 - целое без знака длиной 4 байта; R4 - вещественное с плавающей точкой длиной 4 байта; R8 - вещественное с плавающей точкой длиной 8 байта; BOOL - булевское значение (целое длиной 2 байта); VARIANT - для переменных, тип значений которых может варьироваться; PTR - указатель на объект; OLE_COLOR - тип (UI4), введенный для переменных, задающих цвет.

Тип свойства выбирается из списка “Type” при добавлении нового свойства при помощи средства ClassWizard. В этом списке, как правило, указываются не типы OLE, а совместимые с ними типы, например тип short, который автоматически транслируется в тип I2. Однако в списке “Type” есть и OLE-типы, например, типы BSTR и OLE_COLOR.



Процедура добавления свойства





Для этого необходимо вызвать ClassWizard и выбрать вкладку OLE Autonation, а затем:

  • В поле “Class name” необходимо выбрать имя класса элемента управления, производного от COleControl. Напомним, что производные классы наследуют от базового класса его данные и методы. Так все OLE-элементы управления могут использовать открытые для них методы базового класса COleControl.


  • При помощи кнопки “Add Property” вызвать диалоговое окно для добавления свойств.


  • Для пользовательских свойств в окно комбинированного списка “External Name” ввести его имя, а для базовых - выбрать имя из этого списка.


  • В группе “Implementation” для пользовательских свойств включить один из переключателей: “Member Variable” или “Get/Set”.


    Для базового свойства будет автоматически выбран переключатель “Stock”. Выбор “Member Variable” задает два первых способа реализации свойства. По умолчанию предлагается второй способ с построением функции уведомления. Если отказаться от нее, то реализуется первый способ. Выбор переключателя “Get/Set” задает третий и четвертый способы реализации свойства. Ввод информации в окне “Parameter List” означает выбор параметризированного свойства, и тогда параметры методов Get и Set будут включать индексы элемента массива, задающего свойство.


  • Из списка “Type” следует выбрать тип свойства. Для базовых свойств тип задается автоматически.


  • Задав все характеристики, следует подтвердить создание нового свойства, выбрав кнопку “Ok”.




  • Действия, выполняемые ClassWizard, при добавлении свойства



    Для пользовательского свойства, при добавлении которого был включен переключатель “Member Variable”, ClassWizard вставит в файл CNameCtl.h описание переменной класса и заголовок функции уведомления (если не было отказа). Созданная переменная, кстати, будет видима в контейнере, который будет содержать OLE-элемент управления. Остов функции уведомления создается и вставляется в файл CNameCtl.cpp. Тело функции содержит единственный вызов SetModifiedFlag().

    Когда контейнер сохраняет свое состояние, сохраняется и свойство встроенного OLE-элемента управления. Поэтому всякий раз, когда меняется свойство, необходимо включить флаг модификации состояния документа. Это и делает функция уведомления. Все остальные возможные действия, связанные с изменением состояния, программист должен добавить сам.

    Для пользовательского свойства, при добавлении которого был включен переключатель “Get/Set methods”, ClassWizard создаст и добавит в h- и cpp-файлы заголовки и остовы этих методов. В процессе добавления свойств можно отказаться от одного из этих методов, и тогда свойство будет предназначаться “только для чтения” или “только для записи”.

    Хотя ClassWizard создает остовы методов Get и Set, пользоваться ими без доработки нельзя, так как он не создает переменной класса.


    Ее нужно добавить вручную и соответственно откорректировать тела методов. Следует заметить, что сама переменная не будет видима в контейнере - она скрыта от него, доступны лишь методы Get и Set.



    Следующая важная часть работы ClassWizard - формирование раздела DISPATCH_MAP (раздела схемы диспетчеризации) в файле NameCtl.cpp. Для каждого пользовательского или базового свойства добавляется соответствующий макрос. Для базовых свойств добавляется один из макросов с префиксом DISP_STOCKPROP_ в соответствии с задаваемым базовым свойством. Для пользовательских свойств добавляемый макрос зависит от способа реализации свойства. Каждому из четырех способов реализации соответствует свой макрос: DISP_PROPERTY(), DISP_PROPERTY_NOTIFY(), DISP_PROPERTY_EX(), DISP_PROPERTY_PARAM(). Параметрами макросов являются имя класса и свойства, тип свойства, и, в зависимости от типа макроса, имена переменной класса и функции уведомления или имена Get и Set методов.

    С каждым свойством ClassWizard связывает идентификатор диспетчеризации ID и добавляет информацию о нем в файл Name.odl.



    “Постоянные” свойства и их инициализация



    В классе CNameCtrl построен остов метода DoDropExchange - аналог метода DoDataExchange класса диалоговых окон. Этот метод вызывается всякий раз, когда OLE-элемент управления создается, читается или записывается в файл на диск. В ее тело для каждого свойства можно добавить вызов метода с префиксом PX (Propertiy eXchange) - аналог DDX-метода.

    Свойство, для которого добавлен вызов PX-метода, называется постоянным (persistent). PX-метод позволяет задать значение постоянного свойства по умолчанию. Для каждого типа свойства применяется свой PX-метод.


    Содержание раздела