Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Основы программирования для информатиков и инженеров. Часть 2 Прикладное программирование в Windows.docx
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
603.45 Кб
Скачать

Размеры системных метрик

 

Значение

Получаемый размер

1

SM_CXFULLSCREEN

Ширина рабочей области максимизированного окна

2

SM_CYFULLSCREEN

Высота рабочей области максимизированного окна

3

SM_CXICON

Ширина большой иконки

4

SM_CYICON

Высота большой иконки

5

SM_CXSMICON

Ширина малой иконки

6

SM_CYSMICON

Высота малой иконки

7

SM_CXSCREEN

Ширина экрана

8

SM_CYSCREEN

Высота экрана

Пример 8-1. Теперь, когда Вы кое-что узнали о функциях работы с текстом в Windows, полезно будет привести небольшой пример программы, демонстрирующий описан­ные возможности:

 

// Демонстрация вывода текста

#include <Windows.h>

#include <String.h>

#include <Stdio.h>

#include "Text.h"

 

LRESULT CALLBACK Window

Func(HWND,UINT,WPARAM,LPARAM);

char szWinName[] = "МоеОкно";  // Имя класса окна

char str[255];  // Буфер строки вывода

int X=0, Y=0;   // Текущие координаты строки

int maxX, maxY; // Размеры экрана

 

int WINAPI WinMain (HINSTANCE hThisInst,

                    HINSTANCE hPrevInst,

                    LPSTR lpszArgs,

                    int nWinMode)

   {

   HWND hwnd;

   MSG msg;

   WNDCLASS wcl;

   HACCEL hAccel;

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

   wcl.hInstance=hThisInst;   // Дескриптор приложения

   wcl.lpszClassName=szWinName;  // Имя класса окна

   wcl.lpfnWndProc=WindowFunc;   // Функция окна

   wcl.style=0;                  // Стиль по умолчанию

   wcl.hIcon=LoadIcon(NULL,IDI_APPLICATION); // Иконка 

   wcl.hCursor=LoadCursor(NULL,IDC_ARROW) ;  // Курсор

   wcl.lpszMenuName="MYMENU";                // Меню

   wcl.cbClsExtra=0;             // Без дополнительной

   wcl.cbWndExtra=0;             // информации

   // Определить заполнение окна белым цветом

   wcl.hbrBackground=

                  (HBRUSH)GetStockObject(WHITE_BRUSH);

   if(!RegisterClass(&wcl))   // Зарегистр. класс окна

      return 0;

   // Создать окно

   hwnd=CreateWindow(szWinName,          // Имя класса

                     "Работа с текстом",  // Заголовок 

                     WS_OVERLAPPEDWINDOW,// Стиль окна

                     CW_USEDEFAULT,    // Х-координата

                     CW_USEDEFAULT,    // Y-координата

                     CW_USEDEFAULT,     // Ширина окна

                     CW_USEDEFAULT,     // Высота окна

                     HWND_DESKTOP,  // Нет родит. окна 

                     NULL,                 // Нет меню

                     hThisInst, // Дескрип. приложения 

                     NULL); // Без дополит. аргументов

   // Загрузить акселераторы

   hAccel=LoadAccelerators(hThisInst,"MYMENU");

   ShowWindow(hwnd,nWinMode) ; // Показать окно и 

   UpdateWindow(hwnd);      // перерисовать содержимое

   // Запустить цикл обработки сообщений

   while(GetMessage (&msg,NULL,0,0))

      if(!TranslateAccelerator(hwnd,hAccel,&msg))

         {

         TranslateMessage(&msg); // Использ.Клавиатуры

         DispatchMessage (&msg); // Возврат к Windows

         }

   return msg. wParam;

   }

 

// Следующая функция вызывается операционной системой // Windows и получает в качестве параметров сообщения

// из очереди сообщений данного приложения

 

LRESULT CALLBACK WindowFunc(HWND hwnd,

                            UINT message,

                            WPARAM wParam,

                            LPARAM lParam)

   {

   HDC hdc;

   TEXTMETRIC tm;

   SIZE size;

   switch(message)

      {

      case WM_CREATE:       // Получаем размеры экрана

         maxX=GetSystemMetrics(SM_CXSCREEN);

         maxY=GetSystemMetrics(SM_CYSCREEN);

         break;

      case WM_COMMAND:

         switch(LOWORD(wParam))

            {

            case ID_SHOW:

               hdc=GetDC(hwnd); // Контекст устройства

               // Установить черный цвет текста

               SetTextColor(hdc,RGB(0,0,0));

               // Установить ярко-голубой цвет фона

               SetBkColor(hdc,RGB(0,255,255));

               // Получить метрики текста

               GetTextMetrics(hdc,&tm);

               sprintf(str,

                       "Высота шрифта %ld пикселов",

                       tm.tmHeight);

               // Вывести строку

               TextOut(hdc,X,Y,str,strlen(str));

               Y=Y+tm.tmHeight            // Следующая

                  +tm.tmExternalLeading;  // строка

               strcpy(str,"Это следующая строка.");

               // Вывести строку

               TextOut(hdc,X,Y,str,strlen(str));

               // Определить длину строки

               GetTextExtentPoint32(hdc,str,

                                    strlen(str), 

                                    &size);

               sprintf(str,

                       "Длина предыдущей строки %ld", 

                       size.cx);

               X=size.cx; // В конец предыдущей строки

               TextOut(hdc,X,Y,str,strlen(str));

               Y=Y+tm.tmHeight            // Следующая

                  +tm.tmExternalLeading;  // строка

               X=0;                // X опять в начало

               sprintf(str,"Размеры экрана %d x %d",

                       maxX,maxY);

               TextOut(hdc,X,Y,str,strlen(str));

               Y=Y+tm.tmHeight            // Следующая

                  +tm.tmExternalLeading;  // строка

               ReleaseDC(hwnd,hdc);   // Освободить DC

               break;

            case ID_RESET:

               X=Y=0;

               break;

            case ID_HELP:

               MessageBox(hwnd,"F2: вывести текст,\n"

                               "F3: с начала экрана",

                               "Помощь",MB_OK);

               break;

            }

         break;

      case WM_DESTROY: // Завершение программы  

         PostQuitMessage(0);

         break;

      default:

         // Все сообщения, не обрабатываемые в данной

         // функции, направляются на обработку по 

         // умолчанию

         return DefWindowProc(hwnd,message,

                              wParam,lParam);

      }

   return 0;

   }

 

Вам также понадобится следующий файл ресурсов:

 

#include <Windows.h>

#include "Text.h"

 

MYMENU MENU

   {

   MENUITEM "&Текст",   ID_SHOW

   MENUITEM "&Сначала", ID_RESET

   MENUITEM "Помощь",   ID_HELP

   }

MYMENU ACCELERATORS

   {

   VK_F2, ID_SHOW,  VIRTKEY

   VK_F3, ID_RESET, VIRTKEY

   VK_F1, ID_HELP,  VIRTKEY

   }

    

Кроме того, потребуется файл определений Text.h:

#define ID_SHOW  100

#define ID_RESET 101

#define ID_HELP  102

 

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

 

Рис. 8.1. Окно программы работы с текстом

 

При создании окна его оконная функция получает сообщение WM_CREATE. При его обработке инициализируются внешние переменные mахХ и maxY. Они прини­мают значения размеров экрана при помощи функции GetSystemMetrics(). И хотя эти значения не используются в нашем примере, они понадобятся в последующих программах.

Заметьте, что в программе используются еще две внешние переменные X и Y, имеющие нулевые начальные значения. Эти переменные сохраняют текущие коор­динаты в окне, в которых будет отображаться следующая текстовая строка. Они постоянно обновляются при выводе текста.

Самая интересная часть программы содержится во фрагменте, обрабатывающем сообщение WM_COMMAND. Рассмотрим его более подробно, начиная с команды ID_SHOW. При получении этой команды программа сначала получает контекст устройства вывода. Затем устанавливает черный цвет для текста и ярко-голубой для фона. Поскольку контекст устройства запрашивается каждый раз при получении команды ID_SHOW, эти цвета устанавливаются многократно, то есть их нельзя установить только один раз (например, при старте программы).

После установки цветов программа получает метрики текущего шрифта. Далее выводится первая строка текста. Заметьте, что сначала она формируется функцией sprintf(), а затем следует собственно вывод строки при помощи функции TextOut(). Как известно из предыдущих глав, ни TextOut(), ни любая другая функция API не выполняет форматирование выводимого текста, так что задача формирования строк для вывода и размещения их на экране полностью возлагается на програм­миста. После того как строка выведена на экран, координата Y увеличивается согласно формуле, приведенной выше, с тем чтобы вывести следующую строку текста в новом месте.

После этого выводится строка: «Это следующая строка». Затем, прежде чем содержимое буфера вывода изменится в результате вызова sprintf(), с помощью функции GetTextExtentPoint32() вычисляется длина строки, хранящейся в буфере. Полученное при этом значение используется для увеличения координаты X, поэтому следующая строка выводится как продолжение предыдущей (заметьте, что координата Y не изменяется). После вывода следующей строки координата Y снова увеличивается, а X устанавливается в 0, так что последующий текст будет выводиться с новой строки.

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

По команде Сначала текст (после вызова команды Текст) будет выводиться с начала рабочей области окна, поскольку значения координат X и Y будут обнуляться. Однако рабочая область при этом не очищается.