Работе с таймером в условиях WinAPI

  • Вид работы:
    Курсовая работа (т)
  • Предмет:
    Информационное обеспечение, программирование
  • Язык:
    Русский
    ,
    Формат файла:
    MS Word
    31,51 Кб
  • Опубликовано:
    2014-05-07
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

Работе с таймером в условиях WinAPI

Содержание

Введение

Цель работы

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

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

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

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

Выводы

Литература

Введение

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

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

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

Цель работы

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Любой, маломальски опытный 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. Отсюда следуют два важных вывода:

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

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 в течение этого времени.

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

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

·   SendDlgItemMessage

·   wsprintf

·   GetLocalTime

·   ExitProcess

·   GetModuleHandle

·   DialogBoxParam

·   EndDialog

·   SetTimer

·   KillTimer

·   LoadIcon

·   GetWindowLong

·   GetDlgItemInt

·   SendMessage

·   GetDlgItem

·   CreateProcess

·   GetSystemMenu

·   AppendMenu

·   MessageBox

Все функции, их назначение и передаваемые параметры сведены в Таблице 1.

Таблица 1 - Сводная таблица используемых функций WinAPI

Функция

Действие

Параметры

1

2

3

SendDlgItemMessage ( HWND hDlg,  int nIDDlgItem,  UINT Msg,  WPARAM wParam,  LPARAM lParam  );

Отправляет сообщение заданному элементу управления в диалоговом окне

wsprintf ( LPTSTR lpOut, LPTSTR lpFmt, … );

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

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

GetLocalTime ( LPSYSTEMTIME lpSystemTime  );

Извлекает текущую локальную дату и время.

 lpSystemTime  Указатель на структуру SYSTEMTIME, чтобы получить текущую локальную дату и время

ExitProcess ( UINT uExitCode );

Заканчивает работу процесса и всех его потоков.

uExitCode Определяет код выхода для процесса, и для всех потоков, которые завершают работу в результате вызова этой функции

GetModuleHandle ( LPCTSTR lpModuleName );

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

lpModuleName Указатель на символьную строку с нулем в конце, которая содержит имя модуля.Если параметр NULL, то возвращает дескриптор.exe

DialogBoxParam ( HINSTANCE hInstance,  LPCTSTR lpTemplateName, HWND hWndParent,  // дескриптор окна владельца DLGPROC lpDialogFunc,  LPARAM dwInitParam  );

Создает модальный блок диалога из ресурса шаблона диалогового окна

hInstance Идентифицирует экземпляр модуля, исполняемый файл, которого содержит шаблон диалогового окна. lpTemplateName Идентифицирует шаблон диалогового окна. hWndParent Идентифицирует диалоговое окно, которое владеет блоком диалога. lpDialogFunc Указывает на процедуру диалогового окна dwInitParam Устанавливает значение, которое пересылает диалоговому окну сообщение WM_INITDIALOG в параметре lParam.

EndDialog ( HWND hDlg, int nResult );

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

hDlg Идентифицирует диалоговое окно, которое будет разрушено. nResult Устанавливает значение, которое будет возвращено прикладной программе от функции, которая создавала диалоговое окно.

SetTimer ( UINT nIDEvent, UINT nElapse,  void (CALLBACK EXPORT* lpfnTimer)(HWND, UINT, UINT, DWORD)  );

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

nDEvent  Определяет идентификатор таймера отличный от нуля. nElapse Определяет значение времени задержки в миллисекундах. lpfnTimer Определяет адрес обеспеченный прикладной программой для TimerProc функции повторного вызова, которая обрабатывает WM_TIMER сообщения. Если этот параметр NULL WM_TIMER сообщения помещены в очередь сообщений прикладной программы

KillTimer ( Wnd: HWnd, IDEvent:Integer );

Ликвидирует указанный таймер

Wnd Идентификатоp окна. IDEvent Идентификатоp события таймеpа.

LoadIcon ( HINSTANCE hInstance, LPCTSTR lpIconName  // идентификатор );

Загружает определяемый ресурс пиктограммы из исполняемого файла

hInstance Идентифицирует экземпляр модуля, исполняемый файл которого содержит пиктограмму, которая будет загружена. Этот параметр должен иметь значение ПУСТО (NULL), когда загружается стандартная пиктограмма. lpIconName идентификатор ресурса в младшем слове и нули в старшем слове

GetWindowLong ( HWND hWnd,  int nIndex   );

Извлекает информацию об определяемом окне

hWnd Определяет окно, о котором получается информация. nIndex Определяет смещение (начиная от нуля) получаемого значения. GWL_ID - получить идентификатор окна.

GetDlgItemInt ( HWND hDlg,   int nIDDlgItem,   BOOL *lpTranslated,    // индикатор успешного завершения/неудачи BOOL bSigned   );

Переводит текст заданного органа управления в блоке диалога в целочисленное значение.

hDlg Дескриптор диалогового окна nIDDlgItem Идентификатор элемента блока диалога, который определяет орган управления.



lpTranslated Этот параметр необязательный: он может быть значением ПУСТО (NULL). В этом случае, функция не возвращает информации об успехе или неудаче. bSigned Определяет, должна ли функция сначала проверять текст на знак "минус" и возвращать значение целого числа со знаком, если она находит его. Значение ИСТИНА (TRUE) устанавливает, что это должно быть сделано, ЛОЖЬ (FALSE), что этого делать не надо.

GetDlgItem ( HWND hDlg, int nIDDlgItem );

Извлекает дескриптор органа управления в заданном диалоговом окне.

hDlg Идентифицирует диалоговое окно, которое содержит орган управления. nIDDlgItem Определяет идентификатор элемента управления, который будет возвращен обратно.

BOOL CreateProcess ( LPCTSTR lpApplicationName,  LPTSTR lpCommandLine,  LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes,  BOOL bInheritHandles,  DWORD dwCreationFlags,  LPVOID lpEnvironment,  LPCTSTR lpCurrentDirectory,  LPSTARTUPINFO lpStartupInfo,  LPPROCESS_INFORMATION lpProcessInformation  );

Основная функция запуска процесса

lpApplicationName. - Имя выполняемого модуля lpCommandLine-Командная строка. lpProcessAttributes - Атрибуты защиты для нового приложения. lpThreadAttributes - Атрибуты защиты для первого потока.  bInheritHandles - Флаг наследования dwCreationFlags -Флаг способа создание процесса  lpEnvironment.-Указывает на блок среды.  lpCurrentDirectory - Указывает текущий диск и каталог.  lpStartupInfo - Используется для настройки свойств процесса,  lpProcessInformation Структура PROCESS_INFORMATION с информацией о процессе

GetSystemMenu ( Wnd: HWnd;  Revert: Bool ):

Считывает системное меню окна для копиpования и модификации.

hWnd Идентифицирует окно, которое будет владеть копией меню окна. bRevert Определяет действие, которое нужно предпринять. Если этот параметр - ЛОЖЬ (FALSE), GetSystemMenu возвращает дескриптор копии используемого в настоящее время меню окна. Если этот параметр - ИСТИНА (TRUE), GetSystemMenu возвращает меню окна обратно в состояние определяемое в Windows по умолчанию.

AppendMenu ( HMENU hMenu,  // дескриптор меню, который будет изменен UINT uFlags,  // флажки пункта меню UINT uIDNewItem, LPCTSTR lpNewItem  // пункт контекстного меню );

Добавляет в конец определяемой строки меню, "выскакивающего" меню, подменю или контекстного меню новый пункт

hMenu Идентифицирует строку меню, "выскакивающее" меню, подменю или контекстное меню, которое будет изменено. uFlags Определяет флажки, которые управляют внешним видом и характеристиками нового пункта меню. Этот параметр может быть комбинация значений, перечисленных в разделе Замечаний ниже. uIDNewItem Определяет или идентификатор нового пункта меню или, если параметр uFlags установлен в MF_POPUP, дескриптор "выскакивающего" меню или подменю. lpNewItem Определяет содержание нового пункта меню.

MessageBox ( HWND hWnd,  LPCTSTR lpText,  LPCTSTR lpCaption,  UINT uType  );

Создает, отображает на экране и оперирует окном сообщений

hWnd Идентифицирует окно владельца блока сообщений, которым оно было создано.  lpText Указывает на строку с символом нуля в конце, содержащую сообщение, которое должно быть отражено на экране. lpCaption Указывает на строку с символом нуля в конце, используемую для заголовка диалогового окна.  uType Определяет установку битов флажков, которые обуславливают содержание и поведение диалогового окна.


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

Файл timer2.rc

// файл timer2.rc

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

#define WS_SYSMENU 0x00080000L

// элементы на окне должны быть изначально видимы

#define WS_VISIBLE 0x10000000L

// бордюр вокруг элемента

#define WS_BORDER 0x00800000L

// при помощи TAB можно по очереди активизировать элементы

#define WS_TABSTOP 0x00010000L

// текст в окне редактирования прижат к левому краю

#define ES_LEFT 0x0000L

// стиль всех элементов на окне

#define WS_CHILD 0x40000000L

// запрещается ввод с клавиатуры

#define ES_READONLY 0x0800L

#define DS_3DLOOK 0x0004L

// определение диалогового окна

DIAL1 DIALOG 0, 0, 240, 100

STYLE WS_SYSMENU | DS_3DLOOK

FONT 8, "Arial"

{

CONTROL "", 1, "edit", ES_LEFT | WS_CHILD

| WS_VISIBLE | WS_BORDER

| WS_TABSTOP | ES_READONLY, 100, 5, 130, 12

}

Файл timer2.inc

; файл timer2.inc

; константы

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

WM_CLOSE equ 10h

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

WM_INITDIALOG equ 110h

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

WM_COMMAND equ 111h

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

WM_TIMER equ 113h

; сообщение посылки текста элементу

WM_SETTEXT equ 0Ch

; прототипы внешних процедур

IFDEF MASM

EXTERN SendDlgItemMessageA@20:NEAR

EXTERN wsprintfA:NEAR

EXTERN GetLocalTime@4:NEAR

EXTERN ExitProcess@4:NEAR

EXTERN GetModuleHandleA@4:NEAR

EXTERN DialogBoxParamA@20:NEAR

EXTERN EndDialog@8:NEAR

EXTERN SetTimer@16:NEAR

EXTERN KillTimer@8:NEAR

ELSE

EXTERN SendDlgItemMessageA:NEAR

EXTERN _wsprintfA:NEAR

EXTERN GetLocalTime:NEAR

EXTERN ExitProcess:NEAR

EXTERN GetModuleHandleA:NEAR

EXTERN DialogBoxParamA:NEAR

EXTERN EndDialog:NEAR

EXTERN SetTimer:NEAR

EXTERN KillTimer:NEAR

SendDlgItemMessageA@20 = SendDlgItemMessageA

wsprintfA = _wsprintfA

GetLocalTime@4 = GetLocalTime

ExitProcess@4 = ExitProcess

GetModuleHandleA@4 = GetModuleHandleA

DialogBoxParamA@20 = DialogBoxParamA

EndDialog@8 = EndDialog

SetTimer@16 = SetTimer

KillTimer@8 = KillTimer

ENDIF

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

MSGSTRUCT STRUC

MSHWND DD ?

MSMESSAGE DD ?

MSWPARAM DD ?

MSLPARAM DD ?

MSTIME DD ?

MSPT DD ?

MSGSTRUCT ENDS

; структура данных дата-время

DAT STRUC

year DW ?

month DW ?

dayweek DW ?

day DW ?

hour DW ?

min DW ?

sec DW ?

msec DW ?

DAT ENDS

.386P

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

.MODEL FLAT, stdcall

include timer2.inc

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

IFDEF MASM

; для компоновщика LINK.EXE

includelib d:\masm32\lib\user32.lib

includelib d:\masm32\lib\kernel32.lib

includelib d:\masm32\lib\gdi32.lib

ELSE

; для компоновщика TLINK32.EXE

includelib c:\tasm32\lib\import32.lib

ENDIF

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

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

_DATA SEGMENT DWORD PUBLIC USE32 'DATA'

MSG MSGSTRUCT <?>

HINST DD 0; дескриптор приложения

PA DB "DIAL1",0

TIM DB "Дата %u/%u/%u Время %u:%u:%u",0

STRCOPY DB 50 DUP (?)

DATA DAT <0>

_DATA ENDS

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

_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'

START:

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

PUSH 0

CALL GetModuleHandleA@4

MOV [HINST], EAX

; создать диалоговое окно

PUSH 0

PUSH OFFSET WNDPROC

PUSH 0

PUSH OFFSET PA

PUSH [HINST]

CALL DialogBoxParamA@20

CMP EAX,-1

JNE KOL

; сообщение об ошибке

KOL:

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

PUSH 0

CALL ExitProcess@4

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

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

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

; [EBP+014Н]; LPARAM

; [EBP+10Н]; WAPARAM

; [EBP+0CH]; MES

; [EBP+8]; HWND

WNDPROC PROC

PUSH EBP

MOV EBP,ESP

PUSH EBX

PUSH ESI

PUSH EDI

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

CMP DWORD PTR [EBP+0CH],WM_CLOSE

JNE L1

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

; удалить таймер 1

PUSH 1; идентификатор таймера

PUSH DWORD PTR [EBP+08H]

CALL KillTimer@8

; удалить таймер 2

PUSH 2; идентификатор таймера

PUSH DWORD PTR [EBP+08H]

CALL KillTimer@8

PUSH 0

PUSH DWORD PTR [EBP+08H]

CALL EndDialog@8

JMP FINISH

L1:

CMP DWORD PTR [EBP+0CH], WM_INITDIALOG

JNE L2

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

; установить таймер 1

PUSH 0; параметр = NULL

PUSH 1000; интервал 1 с.

PUSH 1; идентификатор таймера

PUSH DWORD PTR [EBP+08H]

CALL SetTimer@16

; установить таймер 2

PUSH OFFSET TIMPROC; параметр = NULL

PUSH 500; интервал 0.5 с.

PUSH 2; идентификатор таймера

PUSH DWORD PTR [EBP+08H]

CALL SetTimer@16

JMP FINISH

L2:

CMP DWORD PTR [EBP+0CH],WM_TIMER

JNE FINISH

; отправить строку в окно

PUSH OFFSET STRCOPY

PUSH 0

PUSH WM_SETTEXT

PUSH 1; идентификатор элемента

PUSH DWORD PTR [EBP+08H]

CALL SendDlgItemMessageA@20

FINISH:

POP EDI

POP ESI

POP EBX

POP EBP

MOV EAX,0

RET 16

WNDPROC ENDP

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

;процедура таймера

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

; [EBP+014Н]; LPARAM - промежуток запуска Windows

; [EBP+10Н]; WAPARAM - идентификатор таймера

; [EBP+0CH]; WM_TIMER

; [EBP+8]; HWND

TIMPROC PROC

PUSH EBP

MOV EBP,ESP

; получить локальное время

PUSH OFFSET DATA

CALL GetLocalTime@4

; получить строку для вывода даты и времени

MOVZX EAX,DATA.sec

PUSH EAX

MOVZX EAX,DATA.min

PUSH EAX

MOVZX EAX,DATA.hour

PUSH EAX

MOVZX EAX,DATA.year

PUSH EAX

MOVZX EAX,DATA.month

PUSH EAX

MOVZX EAX,DATA.day

PUSH EAX

PUSH OFFSET TIM

PUSH OFFSET STRCOPY

CALL wsprintfA

; восстановить стек

ADD ESP,32

RET 16

TIMPROC ENDP

_TEXT ENDS

END START

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

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

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

таймер windows winapi

Выводы

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

·   Выключение компьютера по нажатию на кнопку

·   Перезагрузка компьютера по нажатию на кнопку

·   Выключение компьютера по таймеру

·   Перезагрузка компьютера по таймеру

·   Вывод текущей даты и времени

·   Вывод оставшегося времени до перезагрузки/выключения

·   Отображение сведений о программе

Похожие работы на - Работе с таймером в условиях WinAPI

 

Не нашли материал для своей работы?
Поможем написать уникальную работу
Без плагиата!