Справочник по математике. Справочное_пособие_Visual C++. Программа на C, типы данных и их размер Адресация в С
Скачать 0.66 Mb.
|
3. Сообщение WM_TIMER Параметр wParam сообщения WM_TIMER содержит идентификатор таймера, который был указан или получен от функции SetTimer при создании таймера. С помощью параметра lParam можно определить адрес функции, которая обрабатывает сообщения таймера. После обработки этого сообщения приложение должно возвратить нулевое значение. Заметим, что сообщение WM_TIMER является низкоприоритетным. Это означает, что функция DispatchMessage посылает это сообщение приложению только в том случае, если в очереди приложения нет других сообщений. В этом отличие таймера Windows от аналогичных средств MS- DOS, реализованных с помощью перехвата прерывания INT 8h. Выполнение программы MS-DOS прерывается синхронно с приходом аппаратного прерывания таймера и программа MS-DOS, перехватившая это прерывание, немедленно оповещается о нем. Выполнение приложения Windows тоже, разумеется, прерывается по аппаратному прерыванию таймера, но оповещение об этом событии приходит не всегда, и как правило, позже, вместе с сообщением WM_TIMER. 4. Первый способ использования таймера В этом разделе мы рассмотрим первый способ работы с таймером - подключение таймера к окну. В этом случае функция окна, к которому подключен таймер, будет получать сообщения от таймера с кодом WM_TIMER. Этот способ самый простой. Вначале вам надо вызывать функцию SetTimer, указав ей в качестве параметров идентификатор окна, идентификатор таймера и период, с которым от таймера должны приходить сообщения: #define FIRST_TIMER 1 int nTimerID; nTimerID = SetTimer(hwnd, FIRST_TIMER, 1000, NULL); В данном примере создается таймер с идентификатором FIRST_TIMER, который будет посылать сообщения примерно раз в секунду. Для уничтожения таймера, созданного этим способом, следует вызвать функцию KillTimer, указав параметры следующим образом: KillTimer(hwnd, FIRST_TIMER); Для изменения интервала посылки сообщений вам следует вначале уничтожить таймер, а потом создать новый, работающий с другим периодом времени: KillTimer(hwnd, FIRST_TIMER); nTimerID = SetTimer(hwnd, FIRST_TIMER, 100, NULL); 5. Второй способ использования таймера Второй способ работы с таймером заключается в использовании для таймера специальной функции, которая будет получать сообщения WM_TIMER. Эта функция является функцией обратного вызова, определяется с ключевым словом _export и, так же как и функция окна, имеет специальный пролог и эпилог: void CALLBACK _export TimerProc(HWND hwnd, UINT msg, UINT idTimer, DWORD dwTime); Как и для функции окна, для функции таймера можно выбрать любое имя. При создании таймера вам надо указать адрес функции таймера, а имя не имеет никакого значения. Первый параметр функции таймера - идентификатор окна, с которым связан таймер. Если при создании таймера в качестве идентификатора было указано значение NULL, это же значение будет передано функции таймера. Второй параметр представляет собой идентификатор сообщения WM_TIMER. Третий параметр является идентификатором таймера, пославшего сообщение WM_TIMER. И наконец, последний параметр - текущее время по системным часам компьютера. Это время выражается в количестве тиков таймера с момента запуска Windows. Вы можете узнать текущее системное время в любой момент, если воспользуетесь функцией GetCurrentTime или GetTickCount: DWORD WINAPI GetCurrentTime(void); DWORD WINAPI GetTickCount(void); Эти функции совершенно аналогичны, однако название функции GetTickCount более точно отражает выполняемое ей действие. Если для создания приложения вы пользуетесь современными средствами разработки, такими, как Borland C++ версии 3.1, Microsoft С++ версии 7.0, Microsoft Visual C++, для определения функции обратного вызова достаточно использовать ключевое слово _export. В этом случае вы можете создать таймер, например, так: nTimerID = SetTimer(hwnd, 0, 1000, (TIMERPROC)TimerProc); Для удаления таймера в этом случае необходимо использовать идентификатор, возвращенный функцией SetTimer: KillTimer(hwnd, nTimerID ); Если же используемые вами средства разработки не позволяют указать ключевое слово _export, для подключения функции таймера придется использовать более сложный способ. Когда вы не можете ограничиться использованием ключевого слова _export, для работы с функциями обратного вызова нужно сделать специальный переходник (thunk), вызвав функцию MakeProcInstance: FARPROC WINAPI MakeProcInstance(FARPROC lpProc, HINSTANCE hinst); В качестве первого параметра функции (lpProc) необходимо передать адрес функции, для которой создается переходник, а в качестве второго (hinst) - идентификатор приложения hInstance, полученный функцией WinMain при запуске приложения. Функция MakeProcInstance для указанной функции создает функцию-переходник, возвращая ее адрес, а также обеспечивает функции доступ к сегменту данных приложения, загружая соответствующим образом сегментные регистры. Процедура создания таймера с использованием функции MakeProcInstance может выглядеть следующим образом: TIMERPROC lpfnTimerProc; lpfnTimerProc = (TIMERPROC)MakeProcInstance((FARPROC)TimerProc, hInstance); nTimerID = SetTimer(hwnd, 0, 1000, (TIMERPROC)lpfnTimerProc); После уничтожения таймера следует уничтожить созданный функцией MakeProcInstance переходник, для чего следует вызвать функцию FreeProcInstance: void WINAPI FreeProcInstance(FARPROC lpProc); Этой функции необходимо передать адрес уничтожаемой функции-переходника: FreeProcInstance(lpfnTimerProc); Функции MakeProcInstance и FreeProcInstance можно использовать совместно с современными средствами разработки, понимающими ключевое слово _export. Это не приведет к неправильной работе приложения. Старые средства разработки приложений Windows требуют, чтобы все функции обратного вызова, такие, как функции окон и функции таймеров, были описаны в файле определения модуля, имеющем расширение .def, при помощи оператора EXPORTS, например: EXPORTS WndProc TimerProc Транслятор Borland C++ версии 3.1 распознает ключевое слово _export и автоматически формирует нужный пролог и эпилог для функций обратного вызова. То же самое относится и к трансляторам Microsoft C++ версии 7.0 и Microsoft Visual C++. Поэтому в наших примерах функции MakeProcInstance и FreeProcInstance, а также оператор файла определения модуля EXPORTS не используются. 11. Работа со стандартными ресурсами. 1. Методы класса CButton 2. Методы класса CEdit 3. Методы класса CListBox 4. Методы класса CComboBox 5. Методы класса CProgressCtrl 6. Методы класса CSliderCtrl 7. Методы класса CSpinButtonCtrl 8. Пример Windows-приложения, использующего стандартные ресурсы 1. Методы класса CButton HBITMAP GetBitmap() const; Возвращает дескриптор растрового изображения, сопоставленного кнопке. Если такового не существует, то возвращается NULL. HBITMAP SetBitmap(HBITMAP hBitmap); Сопоставляет кнопке растровое изображение. Значением параметра должен быть дескриптор растрового изображения. Правила размещения растрового изображения такие же, как и у значка. HCURSOR GetCursor(); Возвращает дескриптор курсора, сопоставленного кнопке методом SetCursor. Если у кнопки нет сопоставленного курсора, то возвращается NULL. HCURSOR SetCursor(HCURSOR hCursot); Сопоставляет кнопке курсор, изображение которого будет помещено на поверхность кнопки аналогично значку и растровому изображению. UINT GetState() const; Возвращает описание набора текущих состояний кнопки. Чтобы выделить из этого описания значения конкретных типов состояния, можно использовать маски: · 0х0003 - выделяет собственное состояние кнопки. Применимо только к флажку или переключателю. Если результат побитового умножения дает 0, значит кнопка находится в невыбранном состоянии, 1 - в выбранном, 2 - в неопределенном. · 0х0004 - выделяет состояние первого типа. Ненулевой вариант означает, что кнопка "нажата", нулевой - кнопка свободна. · 0х0008 - выделяет положение фокуса. Ненулевой вариант - кнопка в фокусе клавиатуры. int GetCheck() const; Возвращает собственное состояние флажка или переключателя. Возвращаемое значение может принимать одно из значений: 0 - кнопка не выбрана; 1 - кнопка выбрана; 2 - кнопка в неопределенном состоянии. Если кнопка не является ни переключателем, ни флажком, возвращается 0. void SetCheck(int nCheck); Устанавливает собственное состояние флажка или переключателя. Значения задаются из набора: 0 - невыбранное; 1 - выбранное; 2 - неопределенное. Значение 2 применимо только к флажку со свойством 3State. UINT GetButtonStyle() const; Возвращает стиль кнопки. void SetButtonStyle(UINT nStyle, BOOL bRedraw=TRUE); Устанавливает стиль кнопки. Если параметр bRedraw равен TRUE, кнопка перерисовывается. HICON GetIcon() const; Возвращает дескриптор пиктограммы, сопоставленной кнопке. Если у кнопки нет сопоставленной пиктограммы, возвращает NULL. HICON SetIcon(HICON hIcon); Сопоставляет кнопке пиктограмму. Значением параметра при вызове должен быть дескриптор пиктограммы. Пиктограмма автоматически помешается на поверхность кнопки и сдвигается в ее центр. Если поверхность кнопки меньше пиктограммы, она обрезается со всех сторон до размеров кнопки. Положение пиктограммы может быть выровнено и не по центру. Для этого нужно, чтобы кнопка имела одно из следующих свойств: BS_LEFT, BS_RIGHT, BS_CENTER, BS_TOP, BS_BOTTOM, BS_VCENTER Данный метод устанавливает для кнопки только одну пиктограмму, которая будет наравне с текстом присутствовать при любом ее состоянии. Не надо путать ее с растровым изображением у растровой кнопки. 2. Методы класса CEdit Окна редактирования могут работать в режимах однострочного и многострочного редакторов. Приведем сначала методы, общие для обоих режимов, а затем методы для многострочного редактора. Общие методы : DWORD GetSel() const; void GetSel(int& nStartChar, int& nEndChar) const; Получает первую и последнюю позиции выделенного текста. Для значения типа DWORD младшее слово содержит позицию первого, старшее - последнего символа. void SetSel(DWORD dwSelection, BOOL bNoScroll=FALSE); void SetSel(int nStartChar, int nEndChar, BOOL bNoScroll=FALSE); Устанавливает новое выделение текста, задавая первый и последний выделенный символ. Значение FALSE параметра bNoScroll должно отключать перемещение курсора в область видимости. void ReplaceSel(LPCTSTR lpszNewText); Заменяет выделенный текст на строку, передаваемую в параметре lpszNewText. void Clear(); Удаляет выделенный текст. void Copy(); Копирует выделенный текст в буфер. void Cut(); Переносит (копирует и удаляет) выделенный текст в буфер обмена. void Paste(); Вставляет текст из буфера обмена, начиная с позиции, в которой находится курсор. BOOL Undo(); Отмена последней операции, выполненной редактором. Если редактор однострочный, возвращается всегда неотрицательное значение, иначе неотрицательное значение возвращается лишь в случае успешной замены. BOOL CanUndo() const; Определяет, можно ли отменить последнюю операцию редактора. void EmptyUndoBuffer(); Сбрасывает флаг undo, сигнализирующий о возможности отмены последней операции редактора, и тем самым делает невозможным отмену. Этот флаг сбрасывается автоматически при выполнении методов SetWindowText и SetHandle. BOOL GetModify() const; Возвращает неотрицательное значение, если содержимое окна редактирования не модифицировалось. Информация о модификации поддерживается в специальном флаге, обнуляемом при создании окна редактирования и при вызове метода: void SetModify(BOOL bModified=TRUE); Устанавливает или сбрасывает флаг модификации (см. предыдущий метод). Флаг сбрасывается при вызове метода с параметром FALSE и устанавливается при модификации содержимого окна редактирования или при вызове SetModify с параметром TRUE. BOOL SetReadOnly(BOOL bReadOnly=TRUE); Устанавливает режим просмотра (bReadOnly=TRUE) или редактирования (bReadOnly=FALSE). TCHAR GetPasswordChar() const; Возвращает символ, который при выводе пароля будет появляться на экране вместо символов, набираемых пользователем. Если такой символ не определен, возвращается 0. Устанавливается этот символ методом (по умолчанию используется "*"): void SetPasswordChar(TCHAR ch); void LimitText(int nChars=0); Устанавливает максимальную длину в байтах текста, который может ввести пользователь. Если значение параметра равно 0, длина текста устанавливается равной UINT_MAX. Методы работы с многострочным редактором : 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. 3. Методы класса CListBox void ResetContent(); Очищает содержимое списка, делая его пустым. int AddString( LPCSTR lpszItem); Добавляет строку lpszItem в список и сортирует его, если при создании включено свойство Sort. В противном случае элемент добавляется в конец списка. int DeleteString( UINT nIndex); Удаляет из списка элемент с индексом nIndex. Индексация элементов начинается с 0. int GetCurSel() const; Получает индекс элемента, выбранного пользователем. int SetCurSel( int nSelect); Отмечает элемент с индексом nSelect как выбранный элемент списка. Если значение параметра равно -1, список не будет содержать отмеченных элементов. int GetText( int nIndex, LPSTR lpszBuffer) const; void GetText( int nIndex, CString& rString) const; Копирует элемент с индексом nIndex в буфер. int SetTopIndex( int nIndex); Организует прокрутку списка в окне так, чтобы элемент с индексом nIndex был видимым. int FindString( int nStartAfter, LPCSTR lpszItem) const; Организует поиск в списке и возвращает в качестве результата индекс элемента списка, префикс которого совпадает со строкой lpszItem. Результат не зависит от регистра, в котором набирались символы сравниваемых строк. Параметр nStartAfter задает начало поиска, но поиск идет по всему списку. Он начинается от элемента, следующего за nStartAfter, до конца списка и затем продолжается от начала списка до элемента с индексом nStartAfter. В качестве результата выдается первый найденный элемент, удовлетворяющий условиям поиска. Если такого нет, результат получает значение LB_ERR. int FindStringExact( int nIndexStart, LPCSTR lpszFind) const; Этот метод отличается от предыдущего тем, что теперь не префикс элемента должен совпадать со строкой lpszFind, а сам элемент. Поиск по-прежнему не чувствителен к регистру, в котором набираются символы. 4. Методы класса CComboBox int GetCurSel() const; Возвращает целочисленный указатель выбранной строчки. int SetCurSel(int nSelect);; Ставит указатель на строчку с номером nSelect. int GetLBText(int nIndex, LPTSTR lpszText) const; void GetLBText(int nIndex, CString& rString) const; Записывает содержимое строчки с индексом nIndex в переменные LPTSTR lpszText или CString& rString. int GetLBTextLen(int nIndex) const; Возвращает длину строчки с индексом nIndex. int AddString(LPCTSTR lpszString); Добавляет строчку в список. int DeleteString(UINT nIndex); Удаление строчки с индексом nIndex. int InsertString(int nIndex, LPCTSTR lpszString); Заменяет строчку с индексом nIndex содержимым переменной LPCTSTR lpszString. 5. Методы класса CProgressCtrl void SetRange(short nLower, short nUpper); void SetRange32(int nLower, int nUpper); Устанавливает минимальное ( nLower ) и максимальное значение ( nUpper ). void GetRange(int& nLower, int& nUpper); Записывает в переменные nLower и nUpper минимальное и максимальное значение. int GetPos(); Возвращает текущее значение. int SetPos(int nPos); Устанавливает текущее значение в nPos. int SetStep(int nStep); Устанавливает шаг ( nStep ) вывода. 6. Методы класса CSliderCtrl int GetRangeMax() const; int GetRangeMin() const; void GetRange(int& nMin, int& nMax) const; Первые две функции возвращают максимальное и минимальное знанение, а третья - записывает эти значения в nMax и nMin соответственно. |