Студопедия

КАТЕГОРИИ:

АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Методы работы с многострочным редактором





Метод для осуществления прокрутки текста в области редактирования:

void LineScroll(int nLines, int nChars=0);

Параметр nLimes задает число строк для вертикальной прокрутки. Окно редактирования не прокручивает текст дальше последней строки. При положительном значении параметра область редактирования сдвигается вдоль текста к последней строке, при отрицательной - к первой.

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

Метод для определения номера первой видимой строки в области редактирования:

int GetFirstVisibleLine() const;

Метод для определения числа строк текста, находящегося в области редактирования:

int GetLineCount() const;

Если текст не вводился, возвращает 1.

Методы для копирования содержимого определенной строки в буфер:

int GetLine(int nIndex, LPTSTR lpszBuffer) const;

или

int GetLine(int nIndex, LPTSTR lpszBuffer, int nMaxLength) const;

Копирует строку с номером, равным значению параметра nIndex, в буфер, заданный параметром lpszBuffer. Первое слово в буфере должно задавать его размер. При вызове второго варианта метода значение параметра nMaxLength копируется в первое слово буфера.

Метод возвращает число в действительности скопированных байтов. Если номер строки больше или равен числу строк в буфере окна редактирования, возвращает 0. Текст копируется без каких-либо изменений, нуль-символ не добавляется.

Метод для определения номера первого символа определенной строки:

int LineIndex(int nLine=-1) const;

Неотрицательное значение параметра принимается в качестве номера строки. Значение -1 задает текущую строку. Если номер строки больше или равен числу строк в буфере окна редактирования (строки нумеруются с 0), возвращается 0.




Обработка сообщений. Карты сообщений.

Обработка сообщений. Циклы обработки сообщений

Если и существует некоторая особенность, отличающая программирование в Windows от других областей программирования, то это сообщения. Сообщения являются тем средством, с помощью которого операционная система может дать знать приложению, что что-то произошло, например пользователь нажал клавишу на клавиатуре или щелкнул кнопкой мыши, или передвинул мышь, или подготовил принтер к выводу информации. Окно, а каждый информационный элемент на экране есть своего рода окно, также может посылать сообщения другому окну и, как правило, большинство окон реагирует на полученное сообщение тем, что пересылает его дальше, третьему окну, слегка видоизменив. Значительную помощь в организации работы с сообщениями оказывает MFC, скрывая от программиста многие подробности процесса.

Хотя операционная система и использует целые числа для идентификации событий, в тексте программы мы будем иметь дело с символьными идентификаторами. Огромное количество директив #define связывает символьные идентификаторы с соответствующими числами и позволяет программистам в разговоре между собой в кругу посвященных манипулировать словечками вроде WM_PAINT и WM_SIZE. Префикс WM означает Window Message (сообщение Windows). Фрагмент перечня сообщений представлен в листинге 3.1.


#define WM_SETFOCUS                0x0007

#define WM_KILLFOCUS               0x0008

#define WM_ENABLE                  0x000A

#define WM_SETREDRAW               0x000B

#define WM_SETTEXT                 0x000C

#define WM_GETTEXT                 0x000D

#define WM_GETTEXTLENGTH           0x000E

#define WM_PAINT                   0x000F

#define WM_CLOSE                   0x0010

#define WM_QUERYENDSESSION         0x0011

#define WM_QUIT                    0x0012

#define WM_QUERYOPEN               0x0013

#define WM_ERASEBKGND              0x0014

#define WM_SYSCOLORCHANGE          0x0015

#define WM_ENDSESSION              0x0016


Сообщению известно, для какого окна оно предназначено. Оно может иметь до двух параметров. Часто в эти два параметра упаковывается несколько совершенно различных величин.

Обработка разных сообщений выполняется разными компонентами операционной системы и приложения. Например, когда пользователь передвигает мышь по полю окна, формируется сообщение WM_MOUSEMOVE, которое передается окну, а окно, в свою очередь, передает это сообщение операционной системе. И уже последняя перерисовывает указатель мыши в новом месте. Когда пользователь щелкает левой кнопкой мыши на экранной кнопке, кнопка, которая также есть особый вид окна, получает сообщение WM_LBUTTONDOWN. В процессе обработки этого сообщения кнопка часто формирует новое сообщение для окна, в котором она находится, причем это сообщение гласит: "Ой, на мне щелкнули!".

Библиотека MFC позволяет программистам в подавляющем большинстве случаев полностью отстраниться от сообщений нижнего уровня, таких как WM_MOUSEMOVE и WM_LBUTTONOOWN. Программист может полностью сосредоточиться на сообщениях более высокого уровня, которые гласят что-нибудь вроде "Выбран третий элемент такого-то списка" или "Произошел щелчок на кнопке Move". Поступают такого рода сообщения в те программы, которые пишет программист, и в компоненты операционной системы точно так же, как и сообщения нижнего уровня. Единственная разница в том, что MFC берет на себя значительную часть работы по обработке сообщений низкого уровня и позволяет заметно облегчить распределение сообщений между разными классами объектов, на уровне которых и будет производиться их обработка.



Циклы обработки сообщений

Сердцем любой Windows-программы является цикл обработки сообщений (Message Loop), который практически всегда находится в функции WinMain(). Эта функция в Windows-приложениях играет ту же роль, что и функция Main () в DOS-приложениях,— ее вызывает операционная система сразу же после загрузки приложения в память. Текст типичной функции WinMain() Представлен в листинге 3.2.

 

Листинг 3.2.Tипичнaя функцияWinMain()

int АРIENTRY WinMain(HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPSTR IpCmdLine,

int nCmdShow) {

MSG msg;

if( !InitAppIication( hInstance))

return (FALSE);

if( !Initlnstance( hInstance,nCmdShow))

return (FALSE);

while( GetMessage( &msg, NULL, 0, 0)) {

TranslateMessage( &msg);

DispatchMessage( &msg):

} return (msg.wParam);}

В С-программах для Windows, похожих на эту, функция InitApplication() вызывает RegisterWindow(), a InitInstance() — CreateWindow(). Затем наступает очередь цикла обработки сообщений. Он представляет собой типичную циклическую конструкцию С на базе оператора whi1е, внутри которой вызывается функция GetMessage(). Эта функция API заполняет msg кодом сообщения, которое операционная система распределила для этого приложения, и почти всегда возвращает TRUE. Таким образом, цикл повторяется снова и снова до тех пор, пока работает приложение. Единственный вариант, при котором GetMessage() возвращает FALSE, — получение сообщения WM_QUIT.

При работе с сообщениями, поступающими с клавиатуры, некоторую часть предварительной обработки берет на себя функция API TranslateMessage(). Ее назначение состоит в следующем. Прикладной части программы нет дела до сообщений наподобие "Нажата клавиша <А>" и «Отпущена клавиша <А>". Прикладную часть интересует только то, какую литеру (символ) ввел пользователь, т.е. ее вполне удовлетворит сообщение "Введен символ А". Вот это преобразование — нескольких сообщений о деталях процесса в одно сообщение о его сути — и выполняет функция TranslateMessage(). Она перехватывает сообщения WM_KEYDOWN и WM_KEYUP и вместо них посылает сообщение WM_CHAR. Если пользоваться библиотекой MFC, то такие мелочи, как ввод символа А, проходят, как правило, мимо вас. Пользователь вводит текст в текстовое поле или в другой элемент управления, и забота программиста— извлечь введенный текст из этого объекта после того, как пользователь щелкнет на ОК.

Функция API DispatchMessage() вызывает, в свою очередь, функцию WndProc() того окна, для которого предназначено сообщение. Типичная функция WndProc() в С-программе для Windows представляет собой огромный оператор switch с отдельными case для каждого сообщения, которое приложение намеревается самостоятельно обрабатывать. Текст ее приведен в листинге 3.3.

Листинг 3.3. Типичная функция WndProc()

LONG APIENTRY MainWndProc( HWND hwnd, // Дескриптоо окна.

UINT msg,  //Тип сообщения.

UINT wParam, //' Дополнительная информация.

LONG IParam) //Дополнительная информация.

{

switch(msg) {

case WM_MOUSEMOVE:

// Обработка перемещения мыши.

break;

 

case WM_LBUTTONDOWN:

// Обработка щелчка левой кнопки мыши.

break;

case WM_ RBUTTONDOWN:

// Обработка щелчка правой кнопки мыши.

break;

case WM_PAINT :

/,/ Перерисовать окно. break;

case WM_DESTROY : // Сообщение: окно будет уничтожено.

PostQuitMessage( 0);

return 0;

break;

defauIt:

return (DefWindowProc( hwnd, msg, wParam, IParam));}

return (0);}

Вы, конечно, можете себе представить, какой длины достигает подобная функция в более или менее порядочном приложении. MFC решает проблему следующим образом—информация о сообщениях, которые должны обрабатываться, расположена поближе к функциям. которые и должны выполнять обработку. Таким образом, отпадает необходимость в огромных операторах switch, в которых сосредоточено распределение сообщений.

Карты сообщений

Использование карты сообщений (Message maps) лежит в основе подхода, который реализуется в MFC для программирования Windows-приложений. Суть его состоит в том, что от разработчика требуется только написать функции обработки сообщений и включить в свой класс карту сообщений, которая фактически скажет: "Я буду обрабатывать такое-то сообщение". После этого главная программа будет отвечать за то, чтобы сообщение было передано именно той функции, которая будет его обрабатывать.

Карта сообщений состоит из двух частей: одна— в файле заголовка для класса .h, а другая — в соответствующем файле реализации .срр. Они, как правило, формируются мастерами, хотя в некоторых случаях вы можете сделать это (или частично отредактировать их) и самостоятельно. В листинге 3.4 представлена часть текста файла заголовка одного из классов простого приложения ShowString.

Листинг 3.4. Карта сообщений из файла ShowString h

//{{AFX_MSG(CShowStringApp)

arx_msg void OnAppAbout();

// ВНИМАНИЕ!! Здесь ClassWizard будет добавлять и

// удалять функции-члены.

//НЕ РЕДАКТИРУЙТЕ текст в этих блоках!

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

Карта сообщений для приложения Employee класса CEmployeeView:

- В файле EmployeeView.h

//{{AFX_MSG(CEmployeeView)

afx_msg void OnRecordAdd();

afx_msg void OnRecordDelete();

afx_msg void OnSortId();

afx_msg void OnSortName();

afx_msg void OnSortRate();

afx_msg void OnSortDepartment();

afx_msg void OnFilterDepartment();

afx_msg void OnFilterId();

afx_msg void OnFilterName();

afx_msg void OnFilterRate();

afx_msg void OnFileSaveAs();

afx_msg void OnRecordFind();

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

Здесь объявляется функция OnAppAbout(). Специальным образом оформленный комментарий позволяет ClassWizard определить, какие именно сообщения перехватываются этим классом. DECLARE_MESSAGE_MAP — это макрос, расширяемый препроцессором компилятора Visual C++, в котором объявляются переменные и функции, принимающие участие в этом фокусе с перехватом сообщений.

Карта сообщений в файле . срр, как показано в листинге 3.5, также достаточно проста.

BEGIN_MESSAGE_MAP(CShowStringApp, CwinApp)

//{{AFX_MSG_MAP(CshowStringApp)

ON_COMMAND(ID_APP_ABOUT, OnAppAbout)

//}}AFX_MSG_MAP

// Стандартные команды для файловых документов.

ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)

ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)

// Стандартные команды настройки принтера.

ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)

END_MESSAGE_MAP()

 

Карта сообщений для приложения Employee класса CEmployeeView:

- в файле EmployeeView.cpp

 

BEGIN_MESSAGE_MAP(CEmployeeView, CRecordView)

//{{AFX_MSG_MAP(CEmployeeView)

ON_COMMAND(ID_RECORD_ADD, OnRecordAdd)

ON_COMMAND(ID_RECORD_DELETE, OnRecordDelete)

ON_COMMAND(ID_SORT_ID, OnSortId)

ON_COMMAND(ID_SORT_NAME, OnSortName)

ON_COMMAND(ID_SORT_RATE, OnSortRate)

ON_COMMAND(ID_SORT_DEPARTMENT, OnSortDepartment)

ON_COMMAND(ID_FILTER_DEPARTMENT, OnFilterDepartment)

ON_COMMAND(ID_FILTER_ID, OnFilterId)

ON_COMMAND(ID_FILTER_NAME, OnFilterName)

ON_COMMAND(ID_FILTER_RATE, OnFilterRate)

ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs)

ON_COMMAND(ID_RECORD_FIND, OnRecordFind)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()










Последнее изменение этой страницы: 2018-04-12; просмотров: 263.

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