Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

Программирование для IBM OS/2

© Александр Фролов, Григорий Фролов
Том 25, М.: Диалог-МИФИ, 1993, 286 стр.

[Назад] [Содеожание] [Дальше]

7.3. Приложение BEEP

Для иллюстрации методов работы с таймером мы подготовили несложное приложение BEEP, исходный текст которого приведен в листинге 7.1.

Листинг 7.1. Файл beep\beep.c

// =================================================
// Определения
// =================================================

#define INCL_WIN
#define INCL_GPI
#define INCL_WINDIALOGS
#include <os2.h>
#include "beep.h"

// Прототип функции окна приложения
MRESULT EXPENTRY WndProc(HWND, ULONG, MPARAM, MPARAM);

// =================================================
// Глобальные переменные
// =================================================

HAB  hab;
HWND hWndFrame;
HWND hWndClient;

CHAR szAppTitle[] = "Timer Beep";

// =================================================
// Главная функция приложения main 
// =================================================

int main ()
{
  HMQ   hmq;
  QMSG   qmsg;
  BOOL  fRc;

  // Флаги для создания окна Frame Window 
  ULONG flFrameFlags =
    FCF_SYSMENU    | FCF_TITLEBAR       | FCF_MINMAX   |
    FCF_SIZEBORDER | FCF_SHELLPOSITION | FCF_TASKLIST |
    FCF_ICON;

  // Имя класса главного окна
  CHAR  szWndClass[] = "TIMERBEEP";

  hab = WinInitialize (0);
  if(hab == NULLHANDLE)
  {
    WinMessageBox (HWND_DESKTOP, HWND_DESKTOP,
      "Ошибка инициализации",
      "Ошибка", 0, MB_ICONHAND | MB_OK);
    return(-1);
  }

  // Создаем очередь сообщений
  hmq = WinCreateMsgQueue (hab, 0);
  if(hmq == NULLHANDLE)
  {
    WinMessageBox (HWND_DESKTOP, HWND_DESKTOP,
      "Ошибка при создании очереди сообщений",
      "Ошибка", 0, MB_ICONHAND | MB_OK);
    WinTerminate (hab);
    return(-1);
  }

  // Регистрация главного окна приложения
  fRc = WinRegisterClass (hab, szWndClass,
    (PFNWP)WndProc, 0, 0);
  if(fRc == FALSE)
  {
    WinMessageBox (HWND_DESKTOP, HWND_DESKTOP,
      "Ошибка при регистрации класса главного окна",
      "Ошибка", 0, MB_ICONHAND | MB_OK);
    WinDestroyMsgQueue (hmq);
    WinTerminate (hab);

    return(-1);
  }

  // Создаем главное окно приложения
  hWndFrame = WinCreateStdWindow  (HWND_DESKTOP,
    WS_VISIBLE ,
    &flFrameFlags, szWndClass, szAppTitle,
    0, 0, ID_APP_FRAMEWND, &hWndClient);
  if(hWndFrame == NULLHANDLE)
  {
    WinMessageBox (HWND_DESKTOP, HWND_DESKTOP,
      "Ошибка при создании главного окна",
      "Ошибка", 0, MB_ICONHAND | MB_OK);
    WinDestroyMsgQueue (hmq);
    WinTerminate (hab);

    return(-1);
  }

  // Запускаем цикл обработки сообщений
  while(WinGetMsg (hab, &qmsg, 0, 0, 0))
    WinDispatchMsg (hab, &qmsg);

  WinDestroyWindow(hWndFrame);
  WinDestroyMsgQueue (hmq);
  WinTerminate (hab);
  return(0);
}

// =================================================
// Функция главного окна приложения
// =================================================

MRESULT EXPENTRY
WndProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
  switch (msg)
  {
    case WM_CREATE :
    {
      // Запускаем таймер с интервалом 1000 мс
      WinStartTimer (hab, hWnd, ID_APP_TIMER1, 1000);

      // Запускаем таймер с интервалом 3000 мс
      WinStartTimer (hab, hWnd, ID_APP_TIMER2, 3000);
      return FALSE;
    }

    case WM_DESTROY :
    {
      // Останавливаем таймеры
      WinStopTimer (hab, hWnd, ID_APP_TIMER1);
      WinStopTimer (hab, hWnd, ID_APP_TIMER2);
      return 0;
    }

    case WM_TIMER :
    {
      // Для каждого таймера выдаем звуковой
      // сигнал своей частоты и длительности
      switch(SHORT1FROMMP (mp1))
      {
        case ID_APP_TIMER1:
        {
          DosBeep(1000, 100);
          break;
        }

        case ID_APP_TIMER2:
        {
          DosBeep(400, 300);
          break;
        }

        default:
          return(WinDefWindowProc (hWnd, msg, 
            mp1, mp2));
      }
      return 0;
    }

    case WM_ERASEBACKGROUND :
      return(MRFROMLONG(1L));

    default:
      return(WinDefWindowProc (hWnd, msg, mp1, mp2));
  }
}

Функция WndProc

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

Сообщение WM_CREATE

Обработчик сообщения WM_CREATE запускает два таймера с идентификаторами, соответственно, ID_APP_TIMER1 и ID_APP_TIMER2:

WinStartTimer (hab, hWnd, ID_APP_TIMER1, 1000);
WinStartTimer (hab, hWnd, ID_APP_TIMER2, 3000);

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

Сообщение WM_DESTROY

Перед уничтожением окна обработчик сообщения WM_DESTROY останавливает оба таймера, запущенных ранее. Для этого используется функция WinStopTimer :

WinStopTimer (hab, hWnd, ID_APP_TIMER1);
WinStopTimer (hab, hWnd, ID_APP_TIMER2);

Сообщение WM_TIMER

Обработчик сообщения WM_TIMER проверяет идентификатор таймера.

Для первого таймера вызывается функция DosBeep, издающая звуковой сигнал с частотой 1000 Гц и продолжительностью 100 мс. Для второго таймера эта же функция издает звуковой сигнал с частотой 400 Гц и длительностью 300 мс. Так как первый таймер посылает сообщения в три раза чаще второго, на каждый сигнал низкого тона вы услышите три сигнала высокого тона.

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

Функция DosBeep входит в программный интерфейс ядра операционной системы IBM OS/2 и не имеет никакого отношения к операционной системе MS-DOS или IBM DOS. Префикс имени Dos говорит лишь о принадлжедности этой функции к указанному программному интерфейсу.

В системе Presentation Manager есть еще одна функция, которую можно использовать для выдачи звуковых сигналов. Это фукнция WinAlarm:

BOOL WinAlarm(
  HWND hwndDeskTop,// идентификатор окна Desktop Window 
  ULONG flStyle);  // вид звукового сигнала

Параметр flStyle определяет вид звукового сигнала. Для подачи предупреждающего звукового сигнала этот параметр должен иметь значение WA_WARNING , для сигнализации ошибки - WA_ERROR , а для сопровождения информационного сообщения - WA_NOTE .

Файл beep.h

Файл beep.h (листинг 7.2) содержит определения константы ID_APP_FRAMEWND, а также идентификаторов двух таймеров ID_APP_TIMER1 и ID_APP_TIMER2.

Листинг 7.2. Файл beep\beep.h

#define ID_APP_FRAMEWND 1
#define ID_APP_TIMER1   1
#define ID_APP_TIMER2   2

Файл beep.rc

Файл описания ресуросв приложения beep.rc приведен в листинге 7.3.

Листинг 7.3. Файл beep\beep.rc

#include <os2.h>
#include "beep.h"
ICON ID_APP_FRAMEWND BEEP.ICO

Файл beep.def

Файл определения модуля приложения beep.def представлен в листинге 7.4.

Листинг 7.4. Файл beep\beep.def

NAME        BEEP   WINDOWAPI
DESCRIPTION 'Beep Application (C) Frolov A., 1996'
HEAPSIZE    4096
STACKSIZE   32768
EXPORTS     WndProc
[Назад] [Содеожание] [Дальше]