Работа с таймером в Windows

 

Оглавление


Введение

Теоретические сведения о таймерах Windows

Описание используемых WinAPI функций

Текст программы

Результат выполнения программы

Выводы


Введение


Большинство операционных систем написаны преимущественно на языке ассемблера. Поэтому операционную систему Windows нагляднее изучать, используя именно этот язык.

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

Что касается операционной системы Windows, то здесь, как ни странно это прозвучит для уха некоторых программистов, программировать на ассемблере гораздо легче, чем в операционной системе MS DOS. Программировать на ассемблере в Windows ничуть не сложнее чем на Си, и при этом получается компактный, эффективный и быстрый код. Работая с языками высокого уровня, мы теряем определенные алгоритмические навыки. И процесс заходит все дальше. Только ради повышения своего профессионального уровня стоит заниматься программированием на ассемблере.

Цель работы

Курсовая работа заключается в получении практических навыков по работе с таймером в условиях WinAPI, самостоятельном изучении 32-битного программирования на ассемблере под Windows и в конечном итоге написание программы, демонстрирующей усвоение полученных знаний.

1 Теоретические сведения о таймерах Windows


Таймер в Windows является устройством ввода информации, которое периодически извещает приложение о том, что истек заданный интервал времени. Ваша программа задает Windows интервал, как бы говоря системе:"Подталкивай меня каждые 10 секунд." Тогда Windows посылает вашей программе периодические сообщения WM_TIMER, сигнализируя об истечении интервала времени.

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

При решении некоторых задач программа должна отслеживать текущее время или выполнять какие-либо действия с определенной периодичностью. Например, эта проблема возникает в приложениях, имитирующих аппаратуру, работающую в реальном масштабе времени, в игровых или мультимедийных приложениях, а также при проведении различных тестов. Кроме того, иногда требуется отладить критичные по времени исполнения фрагменты кода, для чего нужен «хронометр» с высокой разрешающей способностью.

Win32 API содержит как функции для измерения текущего времени, так и функции для создания виртуальных таймеров - устройств, извещающих приложение об истечении заданного интервала времени. Для успешного применения этих программных средств необходимо учитывать разрешающую способность и потенциальную точность измерения.

Важно понимать, что многозадачная операционная система Windows не является системой реального времени, поэтому любой виртуальный таймер в Windows не может гарантировать какой бы то ни было фактической точности отсчета временного интервала. Ведь в любой момент времени система может прервать выполнение вашего приложения, чтобы дать возможность поработать другому приложению(простой, вызванный прерыванием, чаще всего длится от 1 до 30 мс). Вероятность таких прерываний тем ниже, чем меньше рассматриваемый временной интервал и чем меньше других программ работает одновременно с вашим приложением. В то же время, как показывают эксперименты, мультимедийный таймер Windows обеспечивает вполне приемлемую фактическую точность отсчета временных интервалов для многих задач.

Таймер является одним из мощных инструментов, предоставляемых операционной системой и позволяющих решать самые разнообразные задачи.

Вот те задачи, которые можно решить с помощью таймера:

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

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

.Периодический вывод на экран обновленной информации.

.Автосохранение - функция особенно полезная для редакторов.

.Задание темпа изменения каких-либо объектов на экране.

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

Кроме того, таймеры часто применяются в коммуникационных протоколах. Например, если клиент делает запрос серверу и тот не отвечает в течение определенного времени, клиент считает, что сервер не доступен. Сегодня клиентские машины взаимодействуют, как правило, со множеством серверов одновременно. Если бы объект ядра «таймер» создавался для каждого запроса, производительность системы снизилась бы весьмазаметно. В большинстве приложений можно создавать единственный объект-таймер и по мере необходимости просто изменять время его срабатывания.

Постоянное отслеживание параметров таймера и его перенастройка довольно утомительны, из-за чего реализованы лишь в немногих приложениях

Любой, мало-мальски опытный Windows-программист непременно поинтересуется различиями ожидаемых таймеров и таймеров User (настраиваемых через функцию SetTimer). Так вот, главное отличие в том, что ожидаемые таймеры реализованы в ядре, а значит, не столь тяжеловесны, как таймеры User. Кроме того, это означает, что ожидаемые таймеры - объекты защищенные. Таймеры User генерируют сообщения WM_TIMER, посылаемые тому потоку, который вызвал SetTimer (в случае таймеров с обратной связью) или создал определенное окно (в случае оконных таймеров). Таким образом, о срабатывании таймера User уведомляется только один поток. А ожидаемый таймер позволяет ждать любому числу

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

структурировать код под таймеры User, поскольку применение ожидаемых таймеров требует от потоков ожидания не только сообщений, но и объектов ядра. Наконец, в случае ожидаемых таймеров Вы с большей вероятностью будете получать уведомления именно по истечении заданного интервала. Сообщения WM_TIMER всегда имеют наименьший приоритет и принимаются, только когда в очереди потока нет других сообщений. Но ожидаемый таймер обрабатывается так же, как и любой другой объект ядра: если он сработал, ждущий поток немедленно пробуждается. У сообщения таймера есть еще одна особенность. Если система посылает сообщение приложению, а предыдущее сообщение еще стоит в очереди, то система объединяет эти два сообщения. Таким образом, "вынужденный простой" не приводит к приходу на приложение подряд нескольких сообщений таймера.

Таймер в Windows является относительно простым расширением таймерной логики, встроенной в аппаратуру PC и ROM BIOS. ROM BIOS компьютера инициализирует микросхему таймера так, чтобы она генерировала аппаратное прерывание. Это прерывание иногда называют "тиком таймера". Эти прерывания генерируются каждые 54.925 миллисекунды или примерно 18,2 раза в секунду. Некоторые программы, написанные для MS-DOS, сами обрабатывают это аппаратное прерывание для реализации часов и таймеров.

В программах, сделанных для Windows, так не делается. Windows сама обрабатывает аппаратные прерывания и приложения их не получают. Для каждой программы, где в данный момент установлен таймер, Windows обрабатывает таймерное прерывание путем уменьшения на 1 значения счетчика, изначально переданного вызовом функции SetTimer. Когда это значение становится равным 0, Windows помещает сообщение WM_TIMER в очередь сообщений соответствующего приложения и восстанавливает начальное значение счетчика.

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

Таймер в Windows имеет ту же самую разрешающую способность 54.925 миллисекунды, что и встроенный таймер PC. Отсюда следуют два важных вывода:

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

. Временной интервал, который вы задаете при вызове функции SetTimer всегда округляется вниз до целого числа кратного частоте срабатываний таймера. Например, интервал в 1000 миллисекунд, разделенный на 54.925 миллисекунды равен 18.207 срабатываниям таймера, которые округляются вниз до 18 срабатываний, что фактически составляет интервал в 989, а не 1000 миллисекунд. Для интервалов, меньших 55 миллисекунд, каждое срабатывание таймера генерирует одно сообщение WM_TIMER.

Как уже упоминалось, программы под DOS, написанные для IBM PC и совместимых компьютеров, могут использовать аппаратные срабатывания таймера, перехватывая аппаратное прерывание. Когда происходит аппаратное прерывание, выполнение текущей программы приостанавливается и управление передается обработчику прерываний. Когда прерывание обработано, управление возвращается прерванной программе.

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

Хотя Windows тоже обрабатывает асинхронные таймерные прерывания, сообщения WM_TIMER, которые Windows посылает приложению, не являются асинхронными. Сообщения Windows ставятся в обычную очередь сообщений и обрабатываются как все остальные сообщения. Поэтому, если вы задаете функции SetTimer 1000 миллисекунд, то вашей программе не гарантируется получение сообщения WM_TIMER каждую секунду или даже (как уже упоминалось выше) каждые 989 миллисекунд. Если ваше приложение занято больше, чем секунду, то оно вообще не получит ни одного сообщения WM_TIMER в течение этого времени.

Таймер является одним из мощных инструментов, предоставляемых операционной системой и позволяющих решать самые разнообразные задачи. С таймером Вы познакомились, когда занимались консольными приложениями. Там мы пользовались функциями timeSetEvent и timeKillEvent. Для консольных приложений это очень удобные функции. В оконных приложениях чаще используют функции SetTimer и KillTimer. Особенность таймера, создаваемого функцией SetTimer, заключается в том, что сообщение WM_TIMER, которое начинает посылать система приложению после выполнения функции SetTimer, приходит со всеми другими сообщениями наравне, на общих основаниях. Следовательно, интервал между двумя приходами сообщения WM_TIMER может несколько варьироваться. В большинстве случаев это не существенно. У сообщения таймера есть еще одна особенность. Если система посылает сообщение приложению, а предыдущее сообщение еще стоит в очереди, то система объединяет эти два сообщения. Таким образом, "вынужденный простой" не приводит к приходу на приложение подряд нескольких сообщений таймера.

Вот те задачи, которые можно решить с помощью таймера.

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

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

.Периодический вывод на экран обновленной информации.

.Автосохранение - функция особенно полезная для редакторов.

.Задание темпа изменения каких-либо объектов на экране.

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

Рассмотрим, как нужно обращаться с функцией SetTimer. Вот параметры этой функции.

·1-й параметр - дескриптор окна, с которым ассоциируется таймер. Если этот параметр сделать равным NULL (0), то будет проигнорирован и второй параметр.

·2-й параметр - определяет идентификатор таймера.

·3-й параметр - определяет интервал посылки сообщения WM_TIMER.

·4-й параметр - определяет адрес функции, на которую будет приходить сообщение WM_TIMER. Если параметр равен NULL, то сообщение будет приходить на функцию окна.

Если функция выполнилась успешно, то возвращаемым значением будет являться идентификатор таймера, который, естественно, будет совпадать со вторым параметром, если первый параметр будет отличным от NULL. В случае неудачи функция возвратит ноль.

Из сказанного следует, что функция может быть вызвана тремя способами:

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

2.Задан дескриптор окна, а четвертый параметр определяет функцию, на которую будет приходить сообщение WM_TIMER.

.Дескриптор окна равен NULL, а четвертый параметр определяет функцию, на которую будет приходить сообщение WM_TIMER. Идентификатор таймера в этом случае будет определяться по возвращаемому функцией значению.

Функция, на которую приходит сообщение WM_TIMER, имеет следующие параметры:

·1-й параметр - дескриптор окна, с которым ассоциирован таймер.

·2-й параметр - сообщение WM_T1MER.

·3-й параметр - идентификатор таймера.

·4-й параметр - время в миллисекундах, которое прошло с момента запуска Windows.

Функция KillTimer удаляет созданный параметр и имеет следующие параметры:

·1-й параметр - дескриптор окна.

·2-й параметр - идентификатор таймера.


2 Описание используемых WinAPI функций

таймер windows программирование

При написании программы использовались следующие функции WinAPI:

ReleaseDC

Функция ReleaseDC

Функция ReleaseDC освобождает контекст устройства (DC) для использования другими приложениями. Действие функции ReleaseDC зависит от типа контекста устройства (DC). Она освобождает только общий и контекст устройства (DC) окна. Она не имеет никакого действия на контексты устройства класса или частный DC.

Синтаксис :

int ReleaseDC(

HWND hWnd, // дескриптор окнаhDC // дескриптор контекста устройства (DC)

);

Параметры:

[in] Дескриптор окна, контекст устройства (DC) которого должен быть освобожден.

[in] Дескриптор контекста устройства (DC), который будет освобожден.

Возвращаемые значения:

Возвращаемое значение указывает, был ли контекст устройства (DC) освобожден. Если контекст устройства был освобожден, возвращаемое значение равно 1.

Если контекст устройства (DC) не был освобожден, величина возвращаемого значения - ноль.

Замечания:

Приложение должно вызывать функцию ReleaseDC для каждого вызова функции GetWindowDC и для каждого вызова функции GetDC <#"justify">Функция GetDC

Функция GetDC извлекает дескриптор дисплейного контекста устройства (DC) для рабочей области заданного окна или для всего экрана. Вы можете использовать возвращенный дескриптор в последующих функциях GDI, чтобы рисовать в контексте устройства.

Функция GetDCEx <#"justify">HDC GetDC(hWnd // дескриптор окна

);

Параметры:

hWnd

[in] Дескриптор окна, контекст устройства (DC) которого должен извлечься. Если это значение - ПУСТО (NULL), GetDC извлекает контекст устройства (DC) для всего экрана.

Windows 98/Me, Windows 2000/XP: Чтобы получить контекст устройства (DC) для конкретного экранного монитора, используйте функцию EnumDisplayMonitors и CreateDC <#"justify">Возвращаемые значения

Если функция завершается успешно, возвращаемое значение - дескриптор контекста устройства (DC) для рабочей области заданного окна.

Если функция завершается ошибкой, возвращаемое значение - ПУСТО (NULL).

Windows NT/2000/XP: Чтобы получать дополнительные сведения об ошибке, вызовите GetLastError <#"justify">Замечания:

Функция GetDC извлекает общий, для класса, или частный контекст устройства (DC) в зависимости от стиля класса заданного окна. Для класса и частного контекстов устройства (DC), функция GetDC оставляет предварительно назначенные атрибуты неизменными. Однако, для общих контекстов устройства (DC), GetDC назначает атрибуты контексту устройства (DC) по умолчанию, каждый раз, когда он извлекается. Например, заданный по умолчанию шрифт System, который является растровым шрифтом. Поскольку это так, дескриптор общего контекста устройства (DC), возвращенный при помощи GetDC, не говорит Вам, какой шрифт, цвет или кисть были использованы, когда выводилось окно. Чтобы определить шрифт, вызовите функцию GetTextFace <#"justify">Функция TextOut

Функция TextOut записывает строку символов в заданном месте, используя текущий выбранный шрифт, цвет фона и цвет текста.

Синтаксис:

BOOL TextOut(

HDC hdc, // дескриптор DCnXStart, // x-координата начальной позицииnYStart, // y-координата начальной позицииlpString, // строка символовcbString // число символов

);

Параметры:

[in] Дескриптор контекста устройства.

[in] Устанавливает x-координату, в логических координатах, контрольной точки, которую система использует для выравнивания строки.

[in] Устанавливает y-координату, в логических координатах, контрольной точки, которую система использует для выравнивания строки.

[in] Указатель на строку, которую нужно написать. Строка не должна завершаться нуль-терминатором, так как параметр cbString задает длину строки.

[in] Устанавливает длину строки. Для функции ANSI, это количество BYTE (байтов), а для функции Unicode, это является количеством WORD (слов).

Обратите внимание!, что для функции ANSI, символы в кодовых страницах SBCS (Набора однобайтовых символов) занимают один байт каждый, в то время как большинство символов в кодовых страницах DBCS (Набора двухбайтовых символов) занимают два байта; для функций Unicode большинство текущих заданных символов Unicode (которые в формате Basic Multilingual Plane (BMP) занимают одно слово (WORD), в то время как заменители символа Unicode - два слова (WORD).95/98/Me: Это значение не может превышать 8192.

Возвращаемые значения :

Если функция завершается успешно, величина возвращаемого значения - не ноль.

Если функция завершается с ошибкой, величина возвращаемого значения - ноль.

Windows NT/2000/XP: Чтобы получать расширенные данные об ошибках, вызовите функцию GetLastError <#"justify">TCHAR text[ ] = "Defenestration can be hazardous";(hdc,r.left,r.top,text, ARRAYSIZE(text));

// Заключим квадратной скобкой путь(hdc);

// Получим регион из этого пути(hdc, RGN_AND);

// Это создает тот же самый результат, что и SelectClipPath()

// SelectClipRgn(hdc, PathToRegion(hdc));

// Заполните регион градациями серого цвета

FillRect(hdc, &r, GetStockObject(GRAY_BRUSH));

Функция MessageBox

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

Синтаксис:

int MessageBox(hWnd,lpText,lpCaption,uType

);

Параметры:

hWnd

[in] Дескриптор окна владельца, которое создает окно сообщения. Если этот параметр - ПУСТО (NULL), окно сообщения не имеет окна владельца.

[in] Указатель на символьную строку с нулем в конце, которая содержит сообщение показываемое на экране.

[in] Указатель на символьную строку с нулем в конце, которая содержит заголовок диалогового окна (окна сообщения). Если этот параметр - ПУСТО (NULL), используется заданный по умолчанию заголовок Error (Ошибка).

[in] Устанавливает содержание и режим работы диалогового окна. Этим параметром может быть комбинация флажков из ниже перечисленных групп флажков.

Чтобы обозначить кнопки, показываемые на экране в окне сообщения, задайте одно из ниже перечисленных значений.


ЗначениеПредназначениеMB_ABORTRETRYIGNORE Окно сообщения содержит три командных кнопки: Прекратить (Abort), Поторить (Retry) и Пропустить (Ignore).MB_CANCELTRYCONTINUE Microsoft® Windows® 2000/XP: Окно сообщения содержит три командных кнопки: Отменить (Cancel), Попытаться снова (Try Again), Продолжить (Continue). Используйте этот тип окна сообщения вместо типа MB_ABORTRETRYIGNORE. MB_HELP Windows 95/98/Me, Windows NT® 4.0 и выше: Добавляет в окно сообщения кнопку Справка (Help). Когда пользователь щелкает по кнопке Справка (Help) или нажимает клавишу F1, система отправляет владельцу сообщение WM_HELP. MB_OK Окно сообщения содержит одну командную кнопку: OK. Это - значение по умолчанию.MB_OKCANCEL Окно сообщения содержит две командных кнопки: OK и Отменить (Cancel).MB_RETRYCANCEL Окно сообщения содержит две командных кнопки: Поторить (Retry) и Отменить (Cancel).MB_YESNO Окно сообщения содержит две командных кнопки: Да (Yes) и Нет (No).MB_YESNOCANCEL Окно сообщения содержит три командных кнопки: Да (Yes), Нет (No) и Отменить (Cancel).

Чтобы показать на экране значок в окне сообщения, установите одно из ниже перечисленных значений.


ЗначениеПредназначениеMB_ICONEXCLAMATION В окне сообщения появляется иконка знака восклицания.MB_ICONWARNING В окне сообщения появляется иконка знака восклицания.MB_ICONINFORMATION В окне сообщения появляется значок, состоящий из строчной буквы i в круге.MB_ICONASTERISK В окне сообщения появляется значок, состоящий из строчной буквы i в круге.MB_ICONQUESTION В окне сообщения появляется иконка знака вопроса.MB_ICONSTOP В окне сообщения появляется значок стоп-сигнала.MB_ICONERROR В окне сообщения появляется значок стоп-сигнала.MB_ICONHAND В окне сообщения появляется значок стоп-сигнала.

Чтобы указать основную кнопку (по умолчанию), установите одно из ниже перечисленных значений.


ЗначениеПредназначениеMB_DEFBUTTON1 Первая кнопка - основная (кнопка используемая по умолчанию). MB_DEFBUTTON1 - значение по умолчанию, если MB_DEFBUTTON2, MB_DEFBUTTON3, или MB_DEFBUTTON4 не определены.MB_DEFBUTTON2 Вторая кнопка - основная кнопка.MB_DEFBUTTON3 Третья кнопка - основная кнопка.MB_DEFBUTTON4 Четвертая кнопка - основная кнопка.

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


ЗначениеПредназначениеMB_APPLMODAL Пользователь должен ответить окну сообщения перед продолжением работы в окне, идентифицированном параметром hWnd. При этом, пользователь может перемещаться в окна других потоков и работать в этих окнах. В зависимости от иерархии окон в приложении, пользователь может быть в состоянии перемещаться в другие окна в пределах потока. Все дочерние окна родителя окна сообщения автоматически блокируются, однако всплывающие окна - не блокируются. MB_APPLMODAL является значением по умолчанию, если ни MB_SYSTEMMODAL, ни MB_TASKMODAL не определены.MB_SYSTEMMODAL То же самое, что и MB_APPLMODAL за исключением того, что окно сообщения имеет стиль WS_EX_TOPMOST. Используйте работающие в системном режиме (недоступном для пользователя) окна сообщения, чтобы уведомить пользователя о серьезных, потенциально разрушительных ошибках, которые требуют немедленного внимания (например, выход за пределы объема памяти). Этот флажок не имеет никакого влияния на способность пользователя взаимодействовать с другими окнами , а не только связанными с hWnd.MB_TASKMODAL То же самое, что и MB_APPLMODAL за исключением того, что все окна верхнего уровня, принадлежащие текущему потоку блокируются, если параметр hWnd равен ПУСТО (NULL). Используйте этот флажок тогда, когда вызывающая программа или библиотека не имеют доступного дескриптора окна, но тем не менее должны воспрепятствовать вводу данных в другие окна в вызывающем потоке, не приостанавливая работу других потоков.

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

Возвращаемое значение:

Если окно сообщения имеет кнопку Отменить (Cancel), то функция возвращает значение IDCANCEL, если или обрабатывается клавиша ESC, или выбрана кнопка Отменить (Cancel). Если окно сообщения не имеет кнопки Отменить (Cancel), нажатия ESC не имеет никакого действия.

Если функция завершается ошибкой, возвращаемое значение равняется нулю. Чтобы получить дополнительную информацию об ошибке, вызовите GetLastError <#"justify">ЗначениеПредназначениеIDABORTБыла выбрана кнопка Прекратить (Abort).IDCANCELБыла выбрана кнопка Отменить (Cancel).IDCONTINUEБыла выбрана кнопка Продолжить (Continue).IDIGNOREБыла выбрана кнопка Пропустить (Ignore).IDNOБыла выбрана кнопка Нет (No).IDOKБыла выбрана кнопка OK.IDRETRYБыла выбрана кнопка Поторить (Retry).IDTRYAGAINБыла выбрана кнопка Попытаться снова (Try Again).IDYESБыла выбрана кнопка Да (Yes).

Когда Вы используете работающее в системном (недоступном) режиме окно сообщения, которое обращает внимание на то, что в системе мало памяти, строки, на которые указывают параметры lpText и lpCaption не должны браться из файла ресурса, потому что попытка загрузить ресурс может завершиться ошибкой.

Если Вы создаете окно сообщения, в то время, когда диалоговое окно присутствует, используйте дескриптор блока диалога как параметр hWnd. Параметр hWnd не должен идентифицировать дочернее окно, такое как орган управления в блоке диалога.95/98/Me: Система может поддержать максимум 16 364 дескриптора окна.

Windows NT/2000/XP: Значение MB_SERVICE_NOTIFICATION изменялось, начиная с Windows NT 4.0. Windows NT 4.0 предусматривает совместимость вниз для существовавших до этого услуг, преобразуя старое значение в новое при исполнении функции MessageBox. Это преобразование делалось только для исполняемых программ, которые имеют номер версии меньше чем 4.0, как устанавливалось компоновщиком.

Чтобы построить сервисный модуль, который использует MB_SERVICE_NOTIFICATION и может выполниться и в Windows ® Microsoft NT 3.x и в Windows NT 4.0, Вы можете сделать одно из ниже перечисленного.

·Во время компоновки программы, установите номер версии меньше, чем 4.0

·Во время компоновки программы, установите версию 4.0. В период исполнения, используйте функцию GetVersionEx, чтобы проверить версию системы. Затем при запуске в Windows NT 3.x, используйте MB_SERVICE_NOTIFICATION_NT3X; а в Windows NT 4.0, используйте MB_SERVICE_NOTIFICATION.

Функция ExitProcess

Функция ExitProcess заканчивает работу процесса и всех его потоков.

Синтаксис:ExitProcess(uExitCode // код выхода для всех потоков

);

Параметры:

[in] Определяет код выхода для процесса, и для всех потоков, которые завершают работу в результате вызова этой функции. Используйте функцию GetExitCodeProcess <#"justify">·В ходе запуска процесса и процедуры инициализации DLL, новые потоки могут быть созданы, но они не начинают исполнение кода до тех пор, пока не будет сделана инициализация DLL для процесса.

·Одновременно только один поток в процессе может быть инициализирован или отключен процедурой в DLL.

·Функция ExitProcess не возвращает значения до тех пор, пока в потоках не отработают в их DLL процедуры инициализации или отключения.

Функция GetModuleHandle

Функция GetModuleHandle извлекает дескриптор указанного модуля, если файл был отображен в адресном пространстве вызывающего процесса.

Чтобы избежать состояний гонки, описанных в разделе Замечаний, используйте функцию GetModuleHandleEx <#"justify">HMODULE GetModuleHandle(

LPCTSTR lpModuleName);

Параметры:

lpModuleName

[in] Указатель на символьную строку с нулем в конце, которая содержит имя модули (или .dll или .exe файл). Если расширение имени файла опускается, в конец добавляется заданное по умолчанию библиотечное расширение .dll. Символьная строка имени файла может включать в себя конечный символ точки (.), который указывает, что имя модуля не имеет расширения. Строка не должна определять путь. Когда определяется путь, убедитесь, что используются обратные слэши (\), а не прямые слэши (/). Имя сравнивается (независимо от ситуации) с именами модулей в текущий момент отображаемыми в адресном пространстве вызывающего процесса.

Если этот параметр - NULL, GetModuleHandle возвращает дескриптор файла, используемый, чтобы создать вызывающий процесс (.exe файл).

Возвращаемые значения:

Если функция завершается успешно, возвращаемое значение - дескриптор указанного модули.

Если функция завершается ошибкой, возвращаемое значение - NULL. Чтобы получить дополнительную информацию об ошибке, вызовите GetLastError <#"justify">Функция DialogBoxParam

Функция DialogBoxParam создает модальное диалоговое окно из шаблона ресурса блока диалога. Перед показом диалогового окна на экране, функция передает в процедуру блока диалога определяемое программой значение, такое как параметр lParam сообщения WM_INITDIALOG <#"justify">INT_PTR DialogBoxParam(hInstance,lpTemplateName,hWndParent,lpDialogFunc,dwInitParam

);

Параметры:

[in] Дескриптор модуля, исполняемый файл которого содержит шаблон диалогового окна.

lpTemplateName

[in] Определяет шаблон диалогового окна. Этот параметр - или указатель на строку символов с нуль-терминатором в конце, которая определяет имя шаблона диалогового окна, или целочисленное значение, которое определяет идентификатор ресурса шаблона блока диалога. Если параметр определяет идентификатор ресурса, его старшее слово должно быть нуль, а младшее слово должно содержать этот идентификатор. Вы можете использовать макрокоманду MAKEINTRESOURCE, чтобы создать это значение.

[in] Дескриптор окна, которое владеет диалоговым окном.

[in] Указатель на процедуру диалогового окна. Дополнительную информацию о процедуре диалогового окна, см. в описании DialogProc <#"justify">Функция EndDialog

Функция EndDialog уничтожает модальное диалоговое окно, заставляя систему закончить любую обработку информации диалогового окна.

Синтаксис:

BOOL EndDialog(hDlg,_PTR nResult

);

Параметры:

[in] Дескриптор уничтожаемого диалогового окна.

nResult

[in] Устанавливает значение, возвращаемое прикладной программе из функции, которая создала диалоговое окно.

Возвращаемое значение:

Если функция завершается успешно, возвращаемое значение не нуль.

Если функция завершается ошибкой, возвращаемое значение равняется нулю. Чтобы получить дополнительную информацию об ошибке, вызовите GetLastError <#"justify">Функция SendMessage

Функция SendMessage отправляет заданное сообщение окну или окнам. Функция вызывает оконную процедуру для заданного окна и не возвращает значение до тех пор, пока оконная процедура не обработает сообщение.

Чтобы отправить сообщение и возвратить немедленно значение, используйте функцию SendMessageCallback <#"justify">LRESULT SendMessage(hWnd,Msg,wParam,lParam

);

Параметры:

[in] Дескриптор окна, оконная процедура которого примет сообщение. Если этот параметр - HWND_BROADCAST, сообщение отправляется всем окнам верхнего уровня в системе, включая заблокированные или невидимые, не имеющие владельца, перекрывающие и выскакивающие окна; но сообщение не отправляется дочерним окнам.

[in] Определяет сообщение, которое будет отправлено.

[in] Определяет дополнительную конкретизирующую сообщение информацию.

[in] Определяет дополнительную конкретизирующую сообщение информацию.

Возвращаемые значения:

Величина возвращаемого значения определяет результат обработки сообщения; он зависит от отправленного сообщения.

Замечания:

Прикладные программы, которые связываются, применяя флажок HWND_BROADCAST, должны использовать функцию RegisterWindowMessage <#"justify">Функция SetTimer

Функция SetTimer создает таймер с указанным значением времени простоя.

Синтаксис:

UINT_PTR SetTimer(hWnd,_PTR nIDEvent,uElapse,lpTimerFunc

);

Параметры:

hWnd

[in] Дескриптор окна, которое связано с таймером. Это окно должно быть собственностью вызывающего потока. Если этот параметр NULL, никакое окно не связано с таймером, а параметр nIDEIvent игнорируется.

[in] Указывает идентификатор таймера отличный от нуля. Если параметр hWnd - NULL, этот параметр игнорируется. Если параметр hWnd - не NULL, и у окна, указанного hWnd уже есть таймер со значением nIDEvent, то существующий таймер заменяется новым таймером. Когда SetTimer заменяет таймер, то таймер возвращается в исходное положение. Поэтому, сообщение должно отправляться после того, как текущее значение времени простоя истекает, а раньше установленное значение времени простоя игнорируется.

[in] Указывает значение времени простоя, в миллисекундах.NT/2000/XP: Если uElapse больше, чем USER_TIMER_MAXIMUM, блокировка по времени устанавливается в 1.2000/XP: Если uElapse меньше, чем USER_TIMER_MINIMUM, блокировка по времени устанавливается в USER_TIMER_MINIMUM.Server 2003: Если uElapse больше, чем USER_TIMER_MAXIMUM, блокировка по времени устанавливается в USER_TIMER_MAXIMUM.XP SP2/Windows Server 2003 SP1: Если uElapse меньше, чем USER_TIMER_MINIMUM, блокировка по времени устанавливается в USER_TIMER_MINIMUM. Если uElapse больше, чем USER_TIMER_MAXIMUM, блокировка по времени устанавливается в USER_TIMER_MAXIMUM.

[in] Указатель на функцию, которая уведомляет, когда значение времени простоя истекает. Для получения дополнительной информации о функции, см. описание TimerProc <#"justify">Возвращаемое значение

Если функция завершается успешно, а параметр hWnd - NULL, возвращаемое значение - целое число, идентифицирующее новый таймер. Приложение может передать это значение в функцию KillTimer <#"justify">Замечания:

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

Параметр wParam сообщения WM_TIMER содержит значение параметра nIDEvent.

Идентификатор таймера nIDEvent, указывается связанным окном. Другое окно может иметь свой собственный таймер, у которого есть тот же самый идентификатор что и таймер, собственность другого окна. Таймеры индивидуальны.может многократно использовать идентификаторы (ID) таймера в случае, где hWnd - NULL.


3 Текст программы


// файл timer.rc

// определение констант

#define WS_SYSMENU 0x00080000L

#define WS_MINIMIZEBOX 0x00020000L

#define WS_MAXIMIZEBOX 0x00010000L

// стиль - кнопка

#define BS_PUSHBUTTON 0x00000000L

// кнопка в окне должна быть видимой

#define WS_VISIBLE 0x10000000L

// центрировать текст на кнопке

#define BS_CENTER 0x00000300L

// стиль кнопки

#define WS_CHILD 0х40000000L

// возможность фокусировать элемент

// при помощи клавиши TAB

#define WS_TABSTOP 0x00010000L

#define DS_3DLOOK 0x0004L

//определение диалогового окнаDIALOG 0, 0, 240, 120

STYLE WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | DS_3DLOOK

CAPTION "Пример диалогового окна с таймером"8, "Arial"

{

// кнопка, идентификатор 5"Выход", 5, "button", BS_PUSHBUTTON

| BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP,

180, 76, 50, 14

}

; файл timer.inc

; константы

; сообщение приходит при закрытии окна

WM_CLOSE equ 10h_INITDIALOG equ 110h_COMMAND equ 111h_TIMER equ 113h

; прототипы внешних процедурMASMReleaseDC@8:NEAR

EXTERN GetDC@4:NEARTextOutA@20:NEARMessageBoxA@16:NEARExitProcess@4:NEARGetModuleHandleA@4:NEARDialogBoxParamA@20:NEAREndDialog@8:NEARSendMessageA@16:NEARSetTimer@16:NEARKillTimer@8:NEARReleaseDC:NEARGetDC:NEARTextOutA:NEARMessageBoxA:NEARExitProcess:NEARGetModuleHandleA:NEARDialogBoxParamA:NEAREndDialog:NEARSendMessageA:NEARSetTimer:NEARKillTimer:NEAR@8 = ReleaseDC@4 = GetDC@20 = TextOutA@16 = MessageBoxA@4 = ExitProcess@4 = GetModuleHandleA@20 = DialogBoxParamA@8 = EndDialog@16 = SendMessageA@16 = SetTimer@8 = KillTimer

; структуры

; структура сообщенияSTRUC

MSHWND DD ?DD ?DD ?DD ?DD ?DD ?ENDS

; файл timer.asm

.386P

; плоская модель

.MODEL FLAT, stdcalltimer.inc

; директивы компоновщику для подключения библиотекMASM

; для компоновщика LINK.EXEc:\masm32\lib\user32.libc:\masm32\lib\kernel32.libc:\masm32\lib\gdi32.lib

; для компоновщика TLINK32.EXEc:\tasm32\lib\import32.lib

;-------------------------------------------------

; сегмент данных

_DATA SEGMENT DWORD PUBLIC USE32 'DATA'MSGSTRUCT <?>DD 0 ; дескриптор приложенияDB "DIAL1",0DD 0

TEXT DB 0DB 'Сообщение',0DB 'Выход по таймеру',0

_DATA ENDS

; сегмент кода

_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'

START:

; получить дескриптор приложения0

CALL GetModuleHandleA@4[HINST], EAX

;----------------------------------------0OFFSET WNDPROC0OFFSET PA[HINST]DialogBoxParamA@20EAX,-1KOL

KOL:

;----------------------------------------0ExitProcess@4

;----------------------------------------

; процедура окна

; расположение параметров в стеке

; [EBP+014Н] ; LPARAM

; [EBP+10Н] ; WAPARAM

; [EBP+0CH] ; MES

; [EBP+8] ; HWNDPROCEBPEBP,ESPEBXESIEDI

;---------------DWORD PTR [EBP+0CH],WM_CLOSE

JNE L1

; здесь реакция на закрытие окна:

; удалить таймер1 ; идентификатор таймера

PUSH DWORD PTR [EBP+08H]

CALL KillTimer@8

; закрыть диалог0

PUSH DWORD PTR [EBP+08H]EndDialog@8FINISH:DWORD PTR [EBP+0CH], WM_INITDIALOG

JNE L5

; здесь начальная инициализация

; установить таймер0 ; параметр = NULL1000 ; интервал 1 с.1 ; идентификатор таймераDWORD PTR [EBP+08H]

CALL SetTimer@16FINISH:DWORD PTR [EBP+0CH], WM_COMMANDL2

; кнопка выхода?WORD PTR [EBP+10H],5FINISHL3:DWORD PTR [EBP+0CH],WM_TIMER

JNE FINISH

; не пора ли заканчивать ?COUNT,9

; выход без предупрежденияL3

; выход через сообщениеL4

; пришло сообщение таймера

; подготовить текст

MOV EAX, COUNT

ADD EAX,49

MOV TEXT, AL

; получить контекст

PUSH DWORD PTR [EBP+08H]GetDC@4

; запомнить контекстEAX

; вывести значение счетчика1OFFSET TEXT

PUSH 1010EAXTextOutA@20

; удалить контекстEAXEAX

PUSH DWORD PTR [EBP+08H]

CALL ReleaseDC@8

; увеличить счетчикCOUNTFINISH:COUNT

; сообщение о выходе по таймеру

PUSH 0OFFSET CAPOFFSET MESDWORD PTR [EBP+08H] ; дескриптор окнаMessageBoxA@16L3:EDIESIEBXEBPEAX,016ENDP

;-------------------------------------------------

_TEXT ENDSSTART


4 Результат выполнения программы




Выводы


В процессе выполнения курсовой работы были получены теоретические сведения о таймерах Windows, для реализации программы было изучено 32-битное программирование, освоены такие программы, как MASM32(основной компилятор), MASM Builder(графическая оболочка MASM32), ResEdit(редактор ресурсов), OllyDBG(отладчик от стороннего разработчика). На основе полученных знаний с целью их закрепления была написана программа.


Оглавление Введение Теоретические сведения о таймерах Windows Описание используемых WinAPI функций Текст программы Результат выполнения прогр

Больше работ по теме:

КОНТАКТНЫЙ EMAIL: [email protected]

Скачать реферат © 2017 | Пользовательское соглашение

Скачать      Реферат

ПРОФЕССИОНАЛЬНАЯ ПОМОЩЬ СТУДЕНТАМ