Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Уроки по программированию. Visual C++, MFC, VB, ActiveX


Служба Рассылок Subscribe.Ru

Программирование на Visual C++ с использованием MFC. Каркас MFC-приложения.

Уроки по программированию от Алексеева Игоря

Урок 1. Каркас MFC-приложения.
Урок 2. Добавление библиотеки MFC к проекту.
Урок 3. Код заготовки MFC.
Урок 4. Что такое MFC?
Урок 5. Обработка сообщений.
Урок 6. Рисуем в окне.
Урок 7. Работа с таймером.
Урок 8. Добавляем второй таймер.
Урок 9. Изменяем интервал у таймера.

Visual C++. MFC. Урок 1. Каркас MFC-приложения

Сейчас мы с вами посмотрим, как делается MFC-приложение ручками, т. е. без использования разных мастеров.

Запускаем Visual C++. Затем выбираем File->New.

В появившемся окошке New обращаем внимание, что активна вкладка Projects (т. е. мы сейчас создаем именно проект).

Диалог New

Выбираем тип проекта Win32 Application. Этот тип - приложение под Windows, но без использования MFC. MFC же мы подсоединим позже.

Проект Win32 Application

Даем проекту имя (например mfc). Вы можете дать любое.

Диалог New

В последующих диалоговых окнах отвечайте по умолчанию. После этого у вас возникнет пустой проект.

Теперь нам в него надо добавить файлы. Для этого снова выбираем File->New. Сейчас уже активна вкладка Files. В списке файлов выберете Source file

Диалог New

Впечатайте имя файла и убедитесь, что галочка Add to Project стоит.

Галочка Add to Project

Теперь можно идти дальше.

Наверх

Visual C++. MFC. Урок 2. Добавление библиотеки MFC к проекту

Сейчас наш проект не использует MFC (такой мы выбрали тип проекта). Нам надо указать явно, что мы хотим использовать MFC. Для этого заходим в меню Project и далее Settings.

Выбор настроек

В диалоге Project Settings выбираем Use MFC in a Shared DLL. Теперь наш проект будет использовать MFC.

Подключение MFC

Закройте диалог, нажав OK.

Теперь можно приступать непоследственно к коду.

Наверх

Visual C++. MFC. Урок 3. Код заготовки MFC

Вставьте в файл вашего проекта следующий код:

#include <afxwin.h>
class CMyMainWnd : public CFrameWnd{
public:
 CMyMainWnd(){ // конструктор
  Create(NULL,"My title");
 }
};
class CMyApp : public CWinApp{
public:
 CMyApp(){}; // конструктор
 virtual BOOL InitInstance(){
  m_pMainWnd=new CMyMainWnd();
  m_pMainWnd->ShowWindow(SW_SHOW);
  return TRUE;
 }
};
CMyApp theApp;

Запустите программу нажав Ctrl-F5 или кнопочку

Запуск программы

Должно появиться окно с заголовком "My title".

Пустое окно

Приступаем к разбору кода. Сначала мы includ'ом подключаем нужный заголовочный файл - afxwin.h.

Затем мы делаем два класса - CMyMainWnd и CMyApp. Первый из них (CMyMainWnd) задаёт главное окно нашего приложения. Второй (CMyApp) - само приложение. Обратите внимание, что в конце нашего кода мы в строке

CMyApp theApp;

создаём экземпляр нашего приложения. Надо понимать, что приложение и его главное окно - это разные веши.

В классе главного окна ничего кроме контруктора нет. В конструкторе мы вызываем метод Create. Откуда он взялся? От родительского класса. Обратите внимание, что класс нашего окна потомок от класса CFrameWnd из библиотеки MFC. Это видно из строчки

class CMyMainWnd : public CFrameWnd

Так вот в родительском классе и есть метод create. Он принимает много параметров, но большинство из них можно не указывать, так как они задаются по умолчанию. Мы указали только первые два. Первый NULL означает, что параметры окна мы берём стандартные. Второй отвечает за заголовок окна.

Переходим к классу CMyApp. Внутри него переопределяется функция InitInstance родительского класса. В ней в строке

m_pMainWnd=new CMyMainWnd();

динамически создается новый экземпляр нашего главного окна. Но создание ещё не есть показ на экране. В следующей строке

m_pMainWnd->ShowWindow(SW_SHOW);

наше созданное окно показывается на экране.

С создание пустого окна всё.

Наверх

Visual C++. MFC. Урок 4. Что такое MFC?

MFC расшифровывается как Microsoft Foundations Classes. Это библиотека, которая используется в для программирования под Windows на Visual C++. Сам язык C/C++ хотя и позволяет программировать под Windows, но с большими трудностями. Так, для создания простейшего приложения (окно, которое можно двигать по крану, минимизировать и максимизировать) надо написать несколько десятков строчек кода. С помощью MFC вы это сделаете существено быстрее. MFC инкапсулирует в себя многие рутинные операции, с которыми сталкивается программист при создании программ по Windows.

Наряду с MFC существуют и другие библиотеки для Windows-програмирования. Например VCL (Visual Component Library) от Borland. Она используется в продуктах Borland'а - C++ Builder и Delphi (несомнемный плюс всего этого - изучив VCL, вы сможете работать и в Delphi, и в C++ Builder).

Но сейчас стандарт это всё-таки MFC. И даже в C++ Builder вы можете использовать MFC.

Наверх

Visual C++. MFC. Урок 5. Обработка сообщений

Давайте теперь сделаем так, что бы наша программа обращала внимание на наши действия. Например, что бы при щелчке мышкой выскакивал MessageBox.

Для этого в наш класс вставьте следующий строчки:

class CMyMainWnd : public CFrameWnd{
public:
    CMyMainWnd(){
        Create(NULL,"My title");
    }
    afx_msg void OnLButtonDown(UINT, CPoint);
    DECLARE_MESSAGE_MAP()
};

Далее после класса напишите

BEGIN_MESSAGE_MAP(CMyMainWnd, CFrameWnd)
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()

И, наконец, в конце файла добавьте строки

CMyApp theApp;
void CMyMainWnd::OnLButtonDown(UINT, CPoint){
    AfxMessageBox("Левая кнопка мыши");
}

Откомпилируйте приложение. При нажатии левой кнопки мыши в окне должен выскочить MessageBox с надписью "Левая кнопка мыши".

Давайте теперь обсудим код. Для того, чтобы наш класс обращал внимание на наши действия, мы должны сделать следующие действия.

Первое. Мы должны вставить в конец нашего класса макрос DECLARE_MESSAGE_MAP(). Это достаточно сделать один раз. Этат макрос в классе и означает, что этот класс будет реагировать на некоторые сообщения.

Второе. Мы должны где-то после класса добавить два макроса BEGIN_MESSAGE_MAP(...,...) и END_MESSAGE_MAP(). Это тоже достаточно сделать только один раз. Это так называемая карта сообщений. В первый макрос первым параметром вы должны вставить имя вашего класса, вторым - имя родительского класса. Первый параметр показывает, для какого класса мы пишем нашу карту сообщений, а второй - кто должен обрабатывать то или иное сообщение, если наш класс не может.

Теперь мы должны написать код для конкретного сообщения. Для этого делаем следующий шаги.

Третий шаг. В классе пишем метод для обработки конкретного сообщения. Для стандартных сообщений имена методов стандартны. Образуются они так: пишем новый префикс On, после которого пишем нужное сообщение Windows без префикса WM_, причем в нем прописными буквами пишем только первые буквы в каждом слове. Например, сообщение WM_ONLBUTTONDOWN превратится в OnLButtonDown. Параметры и возвращаемое значение берём из подсказок. Перед названием метода не забудем написать afx_msg. В нашем примере это

afx_msg void OnLButtonDown(UINT, CPoint);

Четвёртый шаг. В карту сообщений пишем макрос для нашего сообщения. В нашем примере это строка ON_WM_LBUTTONDOWN()

BEGIN_MESSAGE_MAP(CMyMainWnd, CFrameWnd)
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()

Его имя - это ON_ плюс имя сообщения.

Пятый шаг. Пишем, что же конкретно делает наш метод. Здесь мы для примера написали

void CMyMainWnd::OnLButtonDown(UINT, CPoint){
 AfxMessageBox("Левая кнопка мыши");
}

Функции с префиксом Afx определены в MFC глобально. Они не принадлежат конкретному классу.

Наверх

Visual C++. MFC. Урок 6. Рисуем в окне

Давайте теперь посмотрим, как можно в нашем окне что-нибудь нарисовать. В Windows все рисование происходит на так называемом контексте устройства (Device context по-английски). При этом рисование происходит одинаково и для экрана, и для принтера, и для плоттера и т. п. Вы можете полагать, что контекст устройства - это как бы холст. На нём вы рисуете, применяя кисти, перья, шрифты и другие объекты.

Когда окну надо что-либо перерисовать, оно получает сообщение WM_PAINT. Для рисования нам надо написать обработчик для этого события. Для этого мы должны сделать шаги 3-5 из предыдущего урока. Напомним их.

Итак, вносим объяление функции в класс:

class CMyMainWnd : public CFrameWnd{
 ...
 afx_msg void OnLButtonDown(UINT, CPoint);
    afx_msg void OnPaint();
    DECLARE_MESSAGE_MAP()
};

Затем добавляем макрос в карту сообщений:

BEGIN_MESSAGE_MAP(CMyMainWnd, CFrameWnd)
 ...
ON_WM_PAINT()
END_MESSAGE_MAP()

И, наконец, пишем реализацию нашей функции:

void CMyMainWnd::OnPaint(){
    CPaintDC* pDC=new CPaintDC(this);
    pDC->Rectangle(1,1,10,10);
}

В реализации мы делаем следующее - заводим контекст устройства для рисования в строке

CPaintDC* pDC=new CPaintDC(this);

Здесь контест устройства мы создаём динамически. Слово this означает, что мы его тут же прикрепляем к нашему окну (так как сейчас мы находимся в классе CMyMainWnd). У контекста устройства много разных методов. Один из них - это рисование прямоугольника, который мы и используем. Его параметры - это координаты верхнего левого и правого нижнего углов. Есть и множество других методов - для рисования круга и эллипса - Circle и т. д.

Запускаем прграмму. В левом углу должен появится квадратик.

Квадратик
Наверх

Visual C++. MFC. Урок 7. Работа с таймером

Продолжим развитие нашей программы.

Прежде всего обсудим, что делает таймер. После установки таймер начинает "тикать". Это означает, что ваша программа получает через определённый промежуток времени сообщение WM_TIMER. В обработчике этого сообщения можно написать любой код. Важно, что код обработчика будет выполняться через определённые промежутки времени.

Сейчас мы с вами посмотрим, как можно в нашей программе запустить таймер. Прежде всего мы должны его создать. Для этого конструктор нашего класса CMyMainWnd добавите следующий код:

CMyMainWnd(){
    Create(NULL,"My title");
    SetTimer(1, 1000, NULL);
}

Функция SetTimer имеет несколько параметров. Первый (у нас он равен 1) - это идентификатор таймера. Второй (1000 в нашем случае) - это через сколько миллисекунд таймер тикает. 1000 означает что раз в секунду, 500 - что два раза в секунду. Третий параметр ставим в NULL. Это означает, что мы будем обрабатывать сообщение WM_TIMER для нашего таймера в функции OnTimer нашего оконного класса. Но в принципе третий параметр - это адрес функции-обработчика.

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

Добавляем метод в класс:

    ...
    afx_msg void OnPaint();
    afx_msg void OnTimer(UINT);
    DECLARE_MESSAGE_MAP()

Пишем реализацию данного метода:

void CMyMainWnd::OnTimer(UINT){
    MessageBeep(-1);
}

Здесь мы методом

MessageBeep(-1);

говорим, что должен издаваться стандартный звук.

И, наконец, третий шаг - добавление макроса:

...
ON_WM_PAINT()
ON_WM_TIMER()
END_MESSAGE_MAP()

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

~CMyMainWnd(){
    KillTimer(1);
}

У метода KillTimer один параметр - это идентификатор таймера. Ставим тут 1 (ведь наш таймер имеет именно такой идентификатор).

Наверх

Visual C++. MFC. Урок 8. Добавляем второй таймер

Давайте теперь посмотрим, что мы должны сделать, если нам надо работать одновременно с двумя таймерами. Проблема здесь в том, что обработчик для таймера у нас один, но мы хотим производить разные действия при тиканьи одного таймера и при тиканьи другого. Для этого мы должны их как-то различать. Но у нас для этого служит идентификатор таймера (первый параметр в методе SetTimer). Его-то мы и используем.

Добавляем в программу ещё один таймер и сразу пишем код в деструкторе класса для уничтожения нового таймера:

CMyMainWnd(){
    Create(NULL,"My title");
    SetTimer(1, 1000, NULL);
    SetTimer(2, 3000, NULL);
}
~CMyMainWnd(){
    KillTimer(1);
    KillTimer(2);
}

Идентификатор нового таймера 2 , и он тикает раз в три секунды. Отдельный обработчик для второго таймера писать не надо. А надо изменить наш старый обработчик для таймера следующим образом:

void CMyMainWnd::OnTimer(UINT nIDEvent){
    if(nIDEvent==1)
        MessageBeep(-1);
    else
        SetWindowText("Title");
}

У метода OnTimer есть параметр типа UINT. Мы его раньше не использовали, а теперь используем. Это и есть идентификатор таймера, для которого мы обрабатываем сообщение WM_TIMER. Если сообщение от первого таймера, то издаём сигнал, а если от второго, то меняем заголовок окна на "Title".

Запускаем программу. Звук раздаётся раз в секунду, и через три секунды заголовок окна меняется.

Новый проект

С этим занятием всё.

Наверх

Visual C++. MFC. Урок 9. Изменяем интервал у таймера

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

Принцип здесь простой - сначала мы убиваем старый таймер, а затем создаём новый с таким же идентификатором.

Пришем код для обработчика правой кнопки мыши.

Добавляем метод в класс:

    ...
    afx_msg void OnLButtonDown(UINT, CPoint);
    afx_msg void OnRButtonDown(UINT, CPoint);
    afx_msg void OnPaint();
    ...

Добавляем макрос:

...
ON_WM_LBUTTONDOWN()
ON_WM_RBUTTONDOWN()
ON_WM_PAINT()
 ...

Пишем обработчик:

afx_msg void CMyMainWnd::OnRButtonDown(UINT, CPoint){
    KillTimer(1);   //Убиваем старый таймер
    SetTimer(1,2000, NULL); //Создаем новый
}

У нового таймера такой же идентификатор и другой интервал. Теперь при запуске программы при щелчке правой кнопкой мыши таймер будет тикать через две секунды.

Наверх

http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу
Рейтингуется SpyLog

В избранное