Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лекции / prima

.html
Скачиваний:
11
Добавлен:
28.06.2014
Размер:
52.01 Кб
Скачать

Использование Microsoft Visual Studio 2008. Часть 1 Использование Microsoft Visual Studio 2008.

Часть 1 1. Создание проекта с помощью MFC Application Wizard Выберите File – New – Project..., в дереве типов проектов раскройте Visual C++, выберите MFC, а в поле Templates – MFC Application, в поле Name наберите имя проекта FirstProgram.Снимите флажок Create directory for solution. Нажмите ОК. Нажмите кнопку Next. В окне Application Type нам необходимо выбрать Multiple Documents – этот тип используется по умолчанию. Нажмите кнопку Next два раза. В окне Document Template Strings можно задать ряд свойств приложения, а именно: заголовок приложения, расширение для открываемых файлов и т.п. Нажмите кнопку Next ещё два раза. В окне User Interface Features можно задать размер окна приложения, наличие системного меню, кнопок изменения размера окна и т.д. Ещё раз дважды нажмите кнопку Next. В окне Generated Classes в качестве Base Class задайте CFormView. В этом случае вид документа будет основан на диалоге. Нажмите кнопку Finish и ответьте Yes на предложение No printing support. 2. Создание формы для документа Слева вы должны видеть дерево файлов, автоматически сгенерированных для вашего проекта. Под этим деревом видны ярлыки вкладок для просмотра классов, ресурсов и свойств приложения. Перейдите на вкладку Resource View, раскройте дерево ресурсов и найдите диалог с идентификатором IDD_FIRSTPROGRAM_FORM. Этот диалог будет использоваться для отображения открываемых в приложении документов. Дважды щелкните по идентификатору диалога, чтобы открыть окно редактирования диалога. Необходимо сменить язык диалога на русский. Для этого щёлкните правой кнопкой мыши по идентификатору диалога в дереве ресурсов, в появившемся контекстном меню выберите пункт Properties и в появивщемся справа окне свойств в поле Language выберите Русский. У правого края окна приложения Microsoft Visual Studio есть ярлык Toolbox, при наведении курсора на который появляется окно с элементами для создания диалога. Используя это окно, нарисуйте следующий диалог. Пункт меню Format позволяет выравнивать элементы диалога, делать их одинаковыми по размеру, центрировать и т.д.

Используемые элементы: Static Text, Edit Box, Spin, Combo Box. Идентификаторы элементов диалога: IDC_STATIC, IDC_EDIT_DAY, IDC_EDIT_MONTH, IDC_EDIT_YEAR, IDC_SPIN_DAY, IDC_SPIN_MONTH, IDC_SPIN_YEAR, IDC_COMBO_EVENTS, IDC_EDIT_COMMENTS. У правого края окна приложения Microsoft Visual Studio рядом с ярлыком Toolbox есть ярлык Properties, при наведении курсора на который появляется окно свойств выделенного элементов. Идентификаторы элементов диалога и прочие свойства элементов задаются именно в этом окне. Для элемента Combo Box установите значение Drop List для свойства Type, в свойство Data добавьте следующие данные: Встреча, Звонок, День рождения, Другое (для разделения элементов используйте точку с запятой). Щёлкните на кнопке со стрелкой, Находящейся у правого края элемента, чтобы увидеть область выпадающего списка и изменить её размер. Для последнего элемента Edit Box (IDC_EDIT_COMMENTS) установите значение True для свойства Disabled. Для элементов Spin установите значение True для свойств Auto buddy и Set buddy integer (эти параметры позволяют автоматически связать элемент Spin с соседним с ним Edit Box) и значение Right Align для свойства Alignment. Для того, чтобы элементы Spin оказались связаны с нужными элементами Edit Box, необходимо, чтобы каждый элемент Spin следовал за соответствующим элементом Edit Box в так называемом «порядке обхода». Для того, чтобы изменить порядок обхода элементов диалога, в меню Format выберите команду Tab Order. Теперь возле каждого элемента диалога отображается число, задающее его порядковый номер. Для изменения порядка обхода щёлкайте левой кнопкой мыши по элементам диалога, начиная с первого. Для выхода из режима изменения порадка обхода щелкните в любом свободном месте окна. Для запуска программы используйте команду Start Without Debugging или команду Start Debugging из меню Debugg. У вас готова оболочка и внешнее представление приложения, однако, оно ещё не делает ничего существенного. 3. Работа с элементами диалога и данными, отображаемыми в диалоге Для работы с элементами диалога и отображаемыми в них данными элементам диалога надо сопоставлять переменные, которые могут быть двух категорий: Value и Control. Переменные категории Value используются для работы с данными, а переменные категории Control – для работы с самими элементами. Иногда одному элементу могут быть сопоставлены переменные категории Value разных типов, например, для Edit Box такая переменная может быть строковой или целочисленной. Щёлкните правой кнопкой мыши на любом элементе диалога, в появивiемся контекстном меню выберите пункт Add Variable... и в появившемся диалоговом окне задайте имя и свойства переменной. Нажмите кнопку Finish для завершения и повторите эти действия для всех переменных. Вам необходимо создать следующие переменные: Идентификатор элемента диалога Категория переменной Тип переменной Имя переменной IDC_COMBO_EVENTS Value int m_Event IDC_EDIT_COMMENTS Value CString m_Comments IDC_EDIT_COMMENTS Control CEdit m_EditComments IDC_EDIT_DAY Value int m_Day IDC_EDIT_DAY Control CEdit m_EditDay IDC_EDIT_MONTH Value int m_Month IDC_EDIT_MONTH Control CEdit m_EditMonth IDC_EDIT_YEAR Value int m_Year IDC_EDIT_YEAR Control CEdit m_EditYear IDC_SPIN_DAY Control CSpinButtonCtrl m_SpinDay IDC_SPIN_MONTH Control CSpinButtonCtrl m_SpinMonth IDC_SPIN_YEAR Control CSpinButtonCtrl m_SpinYear Теперь нам надо инициализировать отображаемые данные. За отображение документа отвечает класс CFirstProgramView, в котором, в частности, существует функция OnInitialUpdate, которой и надо воспользоваться в данном случае. Рядом с ярлыком вкладки Resource View найдите ярлык вкладки ClassView, который используется для отображения дерева классов. В дереве классов выберите класс CFirstProgramView, в нижней половине окна найдите функцию этого класса OnInitialUpdate и дважды щёлкните левой кнопкой мыши по имени функции для её редактирования. В функцию добавьте описания необходимых переменных и после существующих в ней операторов необходимые действия (жирным шрифтом выделено то, что добавляется): void CFirstProgramView::OnInitialUpdate()

{ CTime time = CTime::GetCurrentTime();

  int   year = time.GetYear();

  CFormView::OnInitialUpdate();

  ResizeParentToFit();

    m_SpinDay.SetRange(1, 31); // Установка верхней и нижней границы   m_SpinMonth.SetRange(1, 12); // изменения данных для элемента Spin   m_SpinYear.SetRange(year, year + 5);

  m_Day   = time.GetDay();

  m_Month = time.GetMonth();

  m_Year  = year;

    m_Event = -1;

// В элементе Combo Box ничего не выбрано   UpdateData(0); // Модификация диалога в соответствие со значениями переменных }   Теперь сделаем так, чтобы при выборе одного из вариантов с помощью элемента IDC_COMBO_EVENTS, элемент IDC_EDIT_COMMENTS становился бы доступен, и можно было бы ввести туда текст. Для этого надо написать функцию, которая будет вызываться, когда произойдет событие «Изменение выбранной строки» для элемента IDC_COMBO_EVENTS.

Перейдите к окну редактирования диалога, щёлкните правой кнопкой мыши по элементу IDC_COMBO_EVENTS и в появившемся контекстном меню выберите Add Event Handler... – это позволит создать функцию, которая вызывается при наступлении определённого события. В появивщемся диалоговом окне в поле Message Type выберите CBN_SELCHANGE и нажмите кнопку Add and Edit для перехода к новой функции. Вставьте в неё следующие операторы:

UpdateData(1); // Модифицируем значения переменных в соответствии с изменениями, сделанными пользователем в диалоге if (m_Event != -1) // Номер строки, выбранной в элементе Combo Box - начинается с 0, -1 означает, что ничего не выбрано  { m_EditComments.EnableWindow(1); // Делаем элемент IDC_EDIT_COMMENTS доступным    m_EditComments.SetFocus(); // и переносим на него фокус ввода   }

else

 m_EditComments.EnableWindow(0);   4. Открытие и сохранение За открытие и сохранение, а также за создание нового документа, отвечает класс CFirstProgramDoc. В этот класс необходимо добавить переменные, в которых будут храниться данные. В нашем случае они продублируют переменные, которые мы создали в классе CFirstProgramView, однако в более сложных случаях связь между данными и их отображением может быть не такая однозначная. В классе CFirstProgramDoc существуют функции OnNewDocument, OnOpenDocument, OnSaveDocument, которые вызываются при соответствующих событиях, однако, обратите внимание, что в эти функции нужно добавлять только вспомогательные действия, производимые при вводе и выводе, например, установку начальных значений при создании нового документа, проверку правильности данных при выводе, проверку правильности ввода/вывода. Сам ввод/вывод осуществляется в функции Serialize того же класса CFirstProgramDoc! При этом вызов диалогов для выбора файла, а также открытие и закрытие файлов берёт на себя та часть приложения, которая генерируется автоматически, и вам не нужно заботиться об этом. Добавьте в класс CFirstProgramDoc переменные _day, _month, _year, _event и _comments соответствующих типов. Для этого нужно нажатием правой кнопкой мыши вызвать контекстное меню для этого класса и выбрать Add – Add Variable… Функция OnNewDocument должна инициализировать эти переменные при создании нового документа: BOOL CFirstProgramDoc::OnNewDocument()

{ CTime time = CTime::GetCurrentTime();

  if (!CDocument::OnNewDocument())

   return FALSE;

  // TODO: add reinitialization code here

  // (SDI documents will reuse this document)

  _day   = time.GetDay();

  _month = time.GetMonth();

  _year  = time.GetYear();

  _event = -1;

  _comments = "";

  return TRUE;

 }

Однако нам теперь надо изменить функцию OnInitialUpdate так, чтобы она ссылалась на эти переменные: void CFirstProgramView::OnInitialUpdate()   { int year = GetDocument()->_year; // Функция GetDocument позволяет получить указатель на документ,

// к которому присоединён данный объект класса CFirstProgramView   CFormView::OnInitialUpdate();

  ResizeParentToFit();

  m_SpinDay.SetRange(1, 31);

  m_SpinMonth.SetRange(1, 12);

  m_SpinYear.SetRange(year, year + 5);

  m_Day   = GetDocument()->_day;

  m_Month = GetDocument()->_month;

  m_Year  = year;

  m_Event = GetDocument()->_event;

  m_Comments = GetDocument()->_comments;

  UpdateData(0);

  if (m_Event != -1)

   m_EditComments.EnableWindow(1);

 }   Напишем ввод и вывод. Как было сказано ранее, это делается в функции Serialize: void CFirstProgramDoc::Serialize(CArchive& ar)

{     if (ar.IsStoring()) // Вывод    { ar.Write(&_day,   sizeof(int));

     ar.Write(&_month, sizeof(int));

     ar.Write(&_year,  sizeof(int));

     ar.Write(&_event, sizeof(int));

     ar.Write(_comments, 256);

    }

    else // Ввод    { ok = 1; // В класс CFirstProgramDoc надо также добавить переменную ok типа int,

// которая будет использоваться для хранения признака ошибки      if (ar.Read(&_day,   sizeof(int)) == 0) ok = 0;

     if (ar.Read(&_month, sizeof(int)) == 0) ok = 0;

     if (ar.Read(&_year,  sizeof(int)) == 0) ok = 0;

     if (ar.Read(&_event, sizeof(int)) == 0) ok = 0;

     ar.Read(_comments.GetBuffer(255), 256);

    }

 }   Однако если теперь попробовать сохранить файл, а потом открыть его, мы не увидим тех же данных. Это связано с тем, что перед сохранением файла надо модифицировать переменные класса CFirstProgramDoc. Мы сделаем это в функции OnSaveDocument. Сначала надо добавить эту функцию в класс CFirstProgramDoc. Выделите этот класс в дереве классов и откройте окно свойств класса. Под именем класса находится панель, на которой надо нажать вторую справа кнопку (Overrides). В списке событий найдите OnSaveDocument, поставьте курсор в пустое поле справа, и для того, чтобы создать функцию со стандартным именем нажмите стрелочку и выберите строку <Add> OnSaveDocument. Добавьте в функцию необходимые действия. BOOL CFirstProgramDoc::OnSaveDocument(LPCTSTR lpszPathName)

{ POSITION pos;

  CFirstProgramView *view;

    pos  = GetFirstViewPosition();

  view = (CFirstProgramView *)GetNextView(pos);

// Эти операторы используются для доступа

// к объекту класса CFirstProgramView данного документа   view->UpdateData(1);

  _day   = view->m_Day;

  _month = view->m_Month;

  _year  = view->m_Year;

  _event = view->m_Event;

  _comments = view->m_Comments;

  if (_event == -1)

   { view->MessageBox(_T("Выберите событие"),

                _T("Внимание"), MB_OK | MB_ICONWARNING);

     return FALSE;

    }

  if (_comments == "")

   if (view->MessageBox(_T("Вы уверены, что не хотите добавить комментарии?"),

                  _T("Внимание"), MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2) == IDNO)

    return FALSE;

  return CDocument::OnSaveDocument(lpszPathName);

 }   Однако прежде чем компилировать программу надо в начало файла добавить следующую строку: #include "FirstProgramView.h" // Необходимо включить данный заголовочный файл для того,

// чтобы сослаться на класс CFirstProgramView Аналогично добавьте функцию OnOpenDocument и вставьте в неё код, который выводит сообщение в случае ошибок при вводе: BOOL CFirstProgramDoc::OnOpenDocument(LPCTSTR lpszPathName)

{

  if (!CDocument::OnOpenDocument(lpszPathName))

   return FALSE;

  // TODO: Add your specialized creation code here

  if (!ok)

   { CString str;

     POSITION pos;

     CFirstProgramView *view;

     pos = GetFirstViewPosition();

     view = (CFirstProgramView *)GetNextView(pos);

     str = "Произошли ошибки при чтении файла '";

     str += lpszPathName; str += "'";

     view->MessageBox(str, _T("Ошибка"), MB_OK | MB_ICONSTOP);

     return FALSE;

    }

  return TRUE;

 }

5. Работа с меню Если вы откроете окно ресурсов, то увидите, что ресурсы вашей программы содержат два меню: IDR_MAINFRAME и IDR_FirstProgramTYPE. Первое меню отображается только тогда, когда нет ни одного открытого документа. В остальных случаях отображается второе меню. Необходимо сменить язык меню на русский.

Добавьте в меню IDR_FirstProgramTYPE пункт «Параметры». По умолчанию он отмечается как Pop-up (т.е. меню, содержащее подменю) и не имеет идентификатора. Если вы хотите, то можете перетащить этот пункт в любое место меню. Добавьте в этот пункт подпункт «Дополнительные параметры». Откройте окно свойств и задайте ему идентификатор ID_PARAM. В поле Prompt задается строка подсказки, которая может состоять из двух частей, разделенных символом перевода строки \n. Первая часть содержит текст, который отображается в строке состояния (строка внизу вашего приложения), а вторая часть (обычно не очень длинная) отображается в виде всплывающей подсказки. Если вы теперь запустите вашу программу, то увидите, что пункт меню «Дополнительные параметры» отображается, но он не доступен. Это происходит потому, что мы не написали функцию, которая будет выполняться при выборе данного пункта меню. Щёлкните правой кнопкой мыше на пункте меню «Дополнительные параметры» и из появившегося контекстного меню выберите пункт Add Event Handler.... В появившемся диалоговом окне в поле Message Type выберите COMMAND, а в поле Class List – CChildFrame и нажмите кнопку Add and Edit для добавления соответствующей функции. Даже если она будет пустая, пункт меню «Дополнительные параметры» станет доступным. 6. Создание диалога Откройте окно ресурсов. Для добавления диалога выберите Insert Dialog из меню элемента Dialog. Нарисуйте следующий диалог:

Используемые элементы: Group Box, Radio Button, Check Box. Идентификаторы элементов диалога: IDC_STATIC, IDC_RADIO_THE_DAY, IDC_RADIO_DAY_BEFORE, IDC_RADIO_2DAYS_BEFORE, IDC_RADIO_WEEK_BEFORE, IDC_CHECK_SHOW, IDC_CHECK_DEL. Для кнопок используются идентификаторы, задаваемые по умолчанию. Для первой радио-кнопки необходимо установить параметр Group. Для первого элемента Check Box «Показывать каждый день» задайте значение TRUE для свойства Disabled. Для диалога будем использовать идентификатор IDD_DIALOG_PARAM. Также необходимо сменить язык диалога на русский. Щёлкните правой кнопкой мыши на свободной области диалога и из появившегося контекстного меню выберите Add Class.... Задайте имя нового класса для диалога CDialogParam. В качестве базового класса оставьте заданный по умолчанию CDialog. Создайте следующие переменные для элементов диалога: Идентификатор элемента Категория переменной Тип переменной Имя переменной IDC_CHECK_DEL Value BOOL m_Del IDC_CHECK_SHOW Value BOOL m_Show IDC_CHECK_SHOW Control CButton m_CheckShow IDC_RADIO_THE_DAY Value int m_Before

Для каждой группы радио-кнопок создаётся только одна переменная, которая имеет значение -1, если ни одна радио-кнопка не выбрана, значение 0 – если выбрана первая радио-кнопка, значение 1 – если выбрана вторая радио-кнопка и т.д. Создайте в классе CFirstProgramDoc соответствующие переменные _before, _show и _del. Добавьте в функцию OnNewDocument операторы для инициализации этих переменных (например, значениями 0, 0 и 1), а в функцию Serialize – операторы для ввода/вывода этих переменных. Теперь можно попробовать вызвать новый диалог. Для вызова диалога необходимо, в первую очередь, объявить переменную соответствующего класса. Затем инициализируются внутренние переменные класса. Для вызова диалога используется функция DoModal. После этого, если пользователь нажал ОК, необходимо переменным _before, _show и _del задать новые значения. В функцию, которая вызывается для пункта меню «Дополнительные параметры» добавьте действия для работы с диалогом: void CChildFrame::OnParam()   { CDialogParam dp; // Объявление переменной для диалога   CFirstProgramDoc  *doc;     CFirstProgramView *view;

    // TODO: Add your command handler code here     view = (CFirstProgramView *)GetActiveView(); // Получаем указатель на документ   doc  = view->GetDocument();     dp.m_Before = doc->_before; // Инициализируем переменные диалога   dp.m_Show   = doc->_show;     dp.m_Del    = doc->_del;     if (dp.DoModal() == IDOK) // Вызов диалога и проверка ответа    { doc->_before = dp.m_Before; // Меняем переменные документа      doc->_show   = dp.m_Show;        doc->_del    = dp.m_Del;       }    }   Для корректной работы программы необходимо в файл ChildFrame.cpp добавить следующие директивы препроцессора: #include "FirstProgramView.h"

#include "FirstProgramDoc.h"

#include "DialogParam.h"

Теперь нужно сделать так, чтобы элемент IDC_CHECK_SHOW («Показывать каждый день») был доступен, когда выбран показ сообщения раньше назначенного дня.

Перейдите в окно редактирования диалога, щёлкните правой кнопкой мыши по первой радио-кнопки и в появившемся контекстном меню выберите Add Event Handler.... В появившемся диалоговом окне в поле Message Type выберите событие BN_CLICKED. Нажмите Add and Edit для того, чтобы добавить функцию, вызываемую при нажатии первой из радио-кнопок. В неё необходимо добавить один оператор m_CheckShow.EnableWindow(0);, который сделает соответствующий элемент недоступным. Аналогично создайте функции, вызываемые при нажатии остальных радио-кнопок. В них надо добавить тот же оператор, только параметр функции должен быть 1 для того, чтобы сделать элемент доступным. 7. Работа с панелью инструментов Для добавления панель в строку инструментов откройте через окно дерева ресурсов панель инструментов (Toolbar), имеющую идентификатор IDR_MAINFRAME. На пустой кнопке нарисуйте подходящую иконку. Дважды щелкните на кнопке и в параметрах в поле ID выберите идентификатор того пункта меню, с которым вы хотите связать кнопку, – ID_PARAM. 8. Запрос на сохранение Запрос на сохранение закрываемого файла выдаётся приложением автоматически в том случае, если известно, что документ был изменен. Для того, чтобы зафиксировать изменение документа, в классе CFirstProgramDoc существует функция SetModifiedFlag. Если эта функция вызывается без параметров или с параметром TRUE, то фиксируется произошедшее изменение документа, и при закрытии выдаётся запрос на сохранение. Если же эту функцию вызвать с параметром FALSE, документ считается неизменённым. Мы уже вставляли в класс CFirstProgramView функцию, которая вызывается при изменении значения, выбранного в элементе Combo Box (см. пункт 16). Добавьте в эту функцию следующую строку и убедитесь, что при попытке закрыть документ после изменения значения, выбранного в элементе Combo Box, выдаётся запрос на сохранение документа. GetDocument()->SetModifiedFlag(); Для каждого элемента Edit Box добавьте функцию, которая вызывается при наступлении события EN_CHANGE, вставьте в эти функции вызов функции SetModifiedFlag и проверьте работу программы. Добавьте этот оператор в функцию CChildFrame::OnParam(), чтобы установить, что документ был изменён, если пользователь изменил дополнительные параметры (если, конечно, он нажал кнопку ОК!). 9. Создание всплывающего меню Всплывающее меню, которое вызывается нажатием правой кнопки мыши на нужном элементе, – очень удобная для пользователя возможность, поэтому в хорошей программе обязательно должны быть такие меню. Создать его не сложно – объявляется соответствующая переменная, добавляются нужные пункты меню и пишутся действия для каждого пункта. Откройте окно редактирования диалога IDD_FIRSTPROGRAM_FORM, в панели окна свойств диалога нажмите вторую справа кнопку (Messages), найдите сообщение WM_RBUTTONUP и добавьте функцию, которая будет вызываться при получении приложением данного сообщения. В эту функцию добавьте действия по созданию меню и работе с ним:

void CFirstProgramView::OnRButtonUp(UINT nFlags, CPoint point)   { CMenu menu;

// Переменная для меню   // TODO: Add your message handler code here and/or call default     ClientToScreen(&point); // Преобразуем координаты для отображения меню в нужном месте   menu.CreatePopupMenu(); // Создание меню   menu.AppendMenu(MF_STRING, ID_PARAM, _T("Дополнительные параметры")); // Добавление пунктов меню   menu.AppendMenu(MF_SEPARATOR);     menu.AppendMenu(MF_STRING, ID_CLEAR, _T("Очистить"));     menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, point.x, point.y, this, NULL); // Функция отображения меню   menu.DestroyMenu();

// Уничтожение меню   CFormView::OnRButtonUp(nFlags, point);    }   Перейдите к дереву ресурсов, откройте ресурс String Table и добавьте новую строку. Задайте следующий значения для свойств новой строки: ID – ID_CLEAR, Value – 32772, Caption – любой. Это необходимо для определения идентификатора ID_CLEAR (предыдущие идентификаторы создавались автоматически). Теперь меню отображается при нажатии правой кнопки мыши, но ещё ничего не делает. Обработка команд, получаемых от меню, происходит в функции OnCommand. В дереве классов выделите класс CFirstProgramView, откройте окно свойств класса, в панели этого окна нажмите вторую справа кнопку (Overrides). В списке событий найдите событие OnCommand. Добавьте соответствующую функцию и отредактируйте её код:

#include "DialogParam.h"

... // Вставляем заголовочный файл, чтобы можно было использовать диалог задания параметров BOOL CFirstProgramView::OnCommand(WPARAM wParam, LPARAM lParam)

{ CDialogParam dp;

  CFirstProgramDoc *doc = GetDocument();

  CTime time = CTime::GetCurrentTime();

  // TODO: Add your specialized code here and/or call the base class

    switch (LOWORD(wParam)) // Определяем, какой пункт меню был выбран    { case ID_PARAM:

      dp.m_Before = doc->_before;

      dp.m_Show   = doc->_show;

      dp.m_Del    = doc->_del;

      if (dp.DoModal() == IDOK)

       { doc->_before = dp.m_Before;

         doc->_show   = dp.m_Show;

         doc->_del    = dp.m_Del;

         doc->SetModifiedFlag(1);

        }

      break;

     case ID_CLEAR:

      m_Day      = time.GetDay();

      m_Month    = time.GetMonth();

      m_Year     = time.GetYear();

      m_Event    = -1;

      m_Comments = "";

      doc->_before = 0;

      doc->_show   = 0;

      doc->_del    = 1;

      UpdateData(0);

      m_EditComments.EnableWindow(0);

      doc->SetModifiedFlag(1);

      break;

    }

  return CFormView::OnCommand(wParam, lParam);

 }   10. Включение и отключение пунктов меню Иногда бывает необходимо, чтобы некоторые пункты меню были доступны только при определённых условиях. Давайте сделаем так, чтобы пункт меню (а также кнопка панели инструментов) «Дополнительные параметры» были доступны только если выбрано некоторое событие. Для этого необходимо обрабатывать сообщение UPDATE_COMMAND_UI. Откройте меню, щёлкните правой кнопкой мыши по пункту «Дополнительные параметры» и в появившемся контекствном меню выберите Add Event Handler....В появившемся диалоговом окне в поле Class list выберите CChildFrame, в поле Message type – UPDATE_COMMAND_UI. Добавьте соответствующую функцию и отредактируйте её код: void CChildFrame::OnUpdateParam(CCmdUI* pCmdUI)

{ CFirstProgramView *view;

  // TODO: Add your command update UI handler code here

  view = (CFirstProgramView *)GetActiveView();

  if (view->m_Event == -1)

   pCmdUI->Enable(0);

  else>

   pCmdUI->Enable(1);

}

11. Операции «Отменить», «Вырезать», «Копировать», «Вставить» Данные пункты меню автоматически вставляются в генерируемое по умолчанию меню. Однако для того чтобы они работали, надо написать соответствующие функции. Функции Undo(), Cut(), Copy() и Paste() являются членами класса CEdit, который отвечает за работы элемента Edit Box, поэтому написание функций для соответствующих пунктов меню не представляет особого труда. Откройте меню, щёлкните правой кнопкой мыши по пункту «Отменить» и в появившемся контекстном меню выберите Add Event Handler....В появившемся диалоговом окне в поле Class list выберите CMainFrame, в поле Message type – COMMAND. Добавьте соответствующую функцию и отредактируйте её код: void CMainFrame::OnEditUndo()   {     // TODO: Add your command handler code here     CEdit *edit = dynamic_cast<CEdit*>(GetFocus()); // Функция GetFocus() возвращает указатель на окно, куда в данный момент производится ввод.

// Операция dynamic_cast позволяет во время работы программы преобразовать полученный

// указатель в указатель на класс CEdit, отвечающий за работу элемента Edit Box.

// Это, однако, возможно только в том случае, если элемент действительно является

// элементом Edit Box. В противном случае результатом преобразования будет 0.   if (edit) // Если элемент является элементом Edit Box    edit->Undo(); // Отменяем последнее действие  }   Аналогично напишите функции для остальных действий. Теперь надо написать функции, которые отключают и соответствующие пункты меню. Для каждого пункта меню «Отменить», «Вырезать», «Копировать», «Вставить» добавьте функцию для обработки сообщения UPDATE_COMMAND_UI (см. пункт 45). Отредактируйте функцию для пункта меню «Отменить»: void CMainFrame::OnUpdateEditUndo(CCmdUI* pCmdUI)   {     // TODO: Add your command handler code here     CEdit *edit = dynamic_cast<CEdit*>(GetFocus());     if (edit && edit->CanUndo()) // Функция CanUndo проверяет, можно ли отменить последнюю операцию    pCmdUI->Enable(1);     else      pCmdUI->Enable(0);    }   Отредактируйте функцию для пункта меню «Вырезать»:

void CMainFrame::OnUpdateEditCut(CCmdUI* pCmdUI)   {     // TODO: Add your command handler code here     CEdit *edit = dynamic_cast<CEdit*>(GetFocus());     if (edit && !(edit->GetStyle() & ES_READONLY)) // Функция GetStyle возвращает характеристики текущего окна. Вырезать выделенный текст

// возможно только, если у элемента Edit Box не установлен атрибут «Только чтение»,

// что мы и проверяем в данном выражении    { int start, end;        edit->GetSel(start, end); // Функция GetStyle возвращает номер первого и последнего символа в выделенном фрагменте      pCmdUI->Enable(start != end);       }     else      pCmdUI->Enable(0);    }   Скопировать выделенный фрагмент текса возможно в любом случае, поэтому функция для пункта меню «Копировать» пишется практически так же, как и для пункта меню «Вырезать», но в ней должна отсутствовать проверка атрибута «Только чтение». Отредактируйте функцию для пункта меню «Вставить»: void CMainFrame::OnUpdateEditPaste(CCmdUI* pCmdUI)   {     // TODO: Add your command handler code here     CEdit *edit = dynamic_cast<CEdit*>(GetFocus());     if (edit && !(edit->GetStyle() & ES_READONLY))      pCmdUI->Enable(::IsClipboardFormatAvailable(CF_TEXT)); // Функция IsClipboardFormatAvailable проверяет, что буфер обмена содержит данные

// определённого типа (в нашем случае - текстового)   else      pCmdUI->Enable(0);    }  

Файл в формате Word

См. также «Использование Microsoft Visual Studio 2008. Часть 2»

Содержание

Соседние файлы в папке Лекции