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

Операционная система Microsoft Windows 3.1 для программиста

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

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

4.2. Приложение SMETRICS

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

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


Листинг 4.1. Файл smetrics\smetrics.cpp


// ----------------------------------------
// Определение системных метрик Windows
// ----------------------------------------

#define STRICT
#include <windows.h>
#include <stdio.h>

// Таблица символических констант для
// различных компонент Windows
static struct {
    int  Const;
    char String[40];
} SMTable[] = {

  { SM_CXBORDER,        "SM_CXBORDER"},
  { SM_CYBORDER,        "SM_CYBORDER"},
  { SM_CYCAPTION,       "SM_CYCAPTION"},
  { SM_CXCURSOR,        "SM_CXCURSOR"},
  { SM_CYCURSOR,        "SM_CYCURSOR"},
  { SM_CXDLGFRAME,      "SM_CXDLGFRAME"},
  { SM_CYDLGFRAME,      "SM_CYDLGFRAME"},
  { SM_CXDOUBLECLK,     "SM_CXDOUBLECLK"},      
  { SM_CYDOUBLECLK,     "SM_CYDOUBLECLK"},
  { SM_CXFRAME,         "SM_CXFRAME"},
  { SM_CYFRAME,         "SM_CYFRAME"},
  { SM_CXFULLSCREEN,    "SM_CXFULLSCREEN"},
  { SM_CYFULLSCREEN,    "SM_CYFULLSCREEN"},
  { SM_CXHSCROLL,       "SM_CXHSCROLL"},
  { SM_CYHSCROLL,       "SM_CYHSCROLL"},
  { SM_CXHTHUMB,        "SM_CXHTHUMB"},
  { SM_CXICON,          "SM_CXICON"},
  { SM_CYICON,          "SM_CYICON"},
  { SM_CXICONSPACING,   "SM_CXICONSPACING"},
  { SM_CYICONSPACING,   "SM_CYICONSPACING"}, 
  { SM_CYKANJIWINDOW,   "SM_CYKANJIWINDOW"},
  { SM_CYMENU,          "SM_CYMENU"},
  { SM_CXMIN,           "SM_CXMIN"},
  { SM_CYMIN,           "SM_CYMIN"},
  { SM_CXMINTRACK,      "SM_CXMINTRACK"},
  { SM_CYMINTRACK,      "SM_CYMINTRACK"},
  { SM_CXSCREEN,        "SM_CXSCREEN"},
  { SM_CYSCREEN,        "SM_CYSCREEN"},
  { SM_CXSIZE,          "SM_CXSIZE"},
  { SM_CYSIZE,          "SM_CYSIZE"},
  { SM_CXVSCROLL,       "SM_CXVSCROLL"},
  { SM_CYVSCROLL,       "SM_CYVSCROLL"},
  { SM_CYVTHUMB,        "SM_CYVTHUMB"},
  { SM_DBCSENABLED,     "SM_DBCSENABLED"},
  { SM_DEBUG,           "SM_DEBUG"},
  { SM_MENUDROPALIGNMENT, "SM_MENUDROPALIGNMENT"}, 
  { SM_MOUSEPRESENT,    "SM_MOUSEPRESENT"},
  { SM_PENWINDOWS,      "SM_PENWINDOWS"},       
  { SM_RESERVED1,       "SM_RESERVED1"},
  { SM_RESERVED2,       "SM_RESERVED2"},
  { SM_RESERVED3,       "SM_RESERVED3"},
  { SM_RESERVED4,       "SM_RESERVED4"},
  { SM_SWAPBUTTON,      "SM_SWAPBUTTON"}
};

// ===========================================
// Функция WinMain
// ===========================================

#pragma argsused
int PASCAL
WinMain(HINSTANCE hInstance,
                HINSTANCE hPrevInstance,
                LPSTR     lpszCmdLine,
                int       nCmdShow)
{
  FILE *out;     // файл для вывода
  int i;         // рабочий счетчик
  char buf[80];  // рабочий буфер

  // Открываем выходной файл для вывода
  // текста потоком
  // Если открыть файл не удалось, выводим
  // сообщение об ошибке
  if ((out = fopen("sysmet.txt", "wt")) == NULL)
  {
    MessageBox(NULL,
     "Не могу открыть файл sysmet.txt",
     "Ошибка", MB_OK | MB_ICONSTOP);
    return 1;
  }

  // Выводим заголовок файла
  fputs("* ================================= *\n", out);
  fputs("* SYSMETRICS, (C) Frolov A.V., 1994 *\n", out);
  fputs("* ================================= *\n\n", out);

  // Перебираем в цикле всю таблицу констант
  // Для каждой константы определяем соответствующую
  // метрику и формируем текстовую строку 
  for(i=0; i < sizeof(SMTable)/sizeof(SMTable[0]); i++)
  {
    sprintf(buf, "%s\t = %d\n",
      SMTable[i].String,
      GetSystemMetrics(SMTable[i].Const));

    // Выводим строку в файл
    fputs(buf, out);
  }

  // Закрываем файл
  fclose(out);

  MessageBox(NULL,
    "Системные метрики Windows записаны "
    "в файл sysmet.txt", "SYSMETRIC", MB_OK);

  return 0;
}

В приложении SMETRICS определен массив структур SMTable, в котором для каждой константы хранится ее символическое имя в виде текстовой строки.

Алгоритм работы понятен без дополнительных объяснений. Заметим только, что мы впервые в приложении Windows использовали функции для работы с файлами. Возможно, мы вас немного порадуем, сообщив, что для работы с файлами вы по- прежнему можете использовать хорошо знакомые вам из MS-DOS функции потокового ввода/вывода. Действительно, функции потокового ввода/вывода будут работать в приложениях Windows. Однако лучше использовать специальные функции файлового ввода/вывода, которые мы рассмотрим позже, в одном из следующих томов "Библиотеки системного программиста".

Вы также можете пользоваться известной вам функцией sprintf (но не printf!). Эту функцию мы использовали для формирования текстовой строки.

Исходный текст файла определения модуля представлен в листинге 4.2.


Листинг 4.2. Файл smetrics\smetrics.def


; =============================
; Файл определения модуля
; =============================
NAME        SMETRICS
DESCRIPTION 'Приложение SMETRICS, (C) 1994, Frolov A.V.'
EXETYPE     windows
STUB        'winstub.exe'
STACKSIZE   5120
HEAPSIZE    1024
CODE        preload moveable discardable
DATA        preload moveable multiple

В листинге 4.3 приведен образец выходного файла, полученного при работе приложения при разрешении 640 х 480 точек.


Листинг 4.3. Образец файла sysmet.txt


* ================================= *
* SYSMETRICS, (C) Frolov A.V., 1994 *
* ================================= *
SM_CXBORDER      = 1
SM_CYBORDER      = 1
SM_CYCAPTION     = 20
SM_CXCURSOR      = 32
SM_CYCURSOR      = 32
SM_CXDLGFRAME    = 4
SM_CYDLGFRAME    = 4
SM_CXDOUBLECLK   = 4
SM_CYDOUBLECLK   = 4
SM_CXFRAME               = 3
SM_CYFRAME               = 3
SM_CXFULLSCREEN  = 640
SM_CYFULLSCREEN  = 460
SM_CXHSCROLL     = 17
SM_CYHSCROLL     = 17
SM_CXHTHUMB      = 17
SM_CXICON                = 32
SM_CYICON                = 32
SM_CXICONSPACING         = 68
SM_CYICONSPACING         = 72
SM_CYKANJIWINDOW         = 0
SM_CYMENU                = 18
SM_CXMIN                 = 100
SM_CYMIN                 = 24
SM_CXMINTRACK    = 100
SM_CYMINTRACK    = 24
SM_CXSCREEN      = 640
SM_CYSCREEN      = 480
SM_CXSIZE                = 18
SM_CYSIZE                = 18
SM_CXVSCROLL     = 17
SM_CYVSCROLL     = 17
SM_CYVTHUMB      = 17
SM_DBCSENABLED   = 0
SM_DEBUG                 = 0
SM_MENUDROPALIGNMENT     = 0
SM_MOUSEPRESENT  = 1
SM_PENWINDOWS    = 0
SM_RESERVED1     = 0
SM_RESERVED2     = 0
SM_RESERVED3     = 0
SM_RESERVED4     = 0
SM_SWAPBUTTON    = 0

Общие размеры экрана определяются метриками SM_CXSCREEN и SM_CYSCREEN. В приведенном выше листинге эти значения соответствуют разрешению 640 х 480. Максимальный размер внутренней области окна можно определить из метрик SM_CXFULLSCREEN и SM_CYFULLSCREEN. В нашем случае максимальная ширина внутренней области окна равна максимальной ширине экрана (640), в то время как максимальная высота меньше на высоту заголовка окна. Высота заголовка определяется метрикой SM_CYCAPTION и в нашем случае равна 20.

При разрешении 1024 х 768 метрики SM_CXSCREEN, SM_CYSCREEN, SM_CXFULLSCREEN и SM_CYFULLSCREEN изменили свое значение:

SM_CXFULLSCREEN  = 1024
SM_CYFULLSCREEN  = 748
SM_CXSCREEN      = 1024
SM_CYSCREEN      = 768

Остальные метрики не изменились и соответствовали значениям для разрешения 640 х 480.

Для того чтобы сделать приложение нечувствительным к используемому разрешению, вы не должны предполагать, что экран видеомонитора имеет какие-либо конкретные размеры. Размеры экрана должны определяться динамически с использованием соответствующих метрик. В этом случае при изменении разрешения размеры всех элементов изображения, нарисованных в окне приложения (и размеры самого окна) будут пересчитаны заново.

Обратите внимание на метрики SM_CXICON и SM_CYICON, определяющие размеры пиктограммы. Эти размеры потребуются вам при необходимости нарисовать в окне пиктограмму. Программный интерфейс Windows имеет специальную функцию DrawIcon, позволяющую нарисовать в окне приложения пиктограмму.

Метрика SM_MOUSEPRESENT позволяет приложению определить, есть ли в составе оборудования компьютера мышь. К сожалению, в Windows не предусмотрено никакого средства для определения количества клавиш, имеющихся на корпусе мыши.

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