Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Паппас К., Мюррей У. - Visual C++ 6. Руководство разработчика - 2000

.pdf
Скачиваний:
289
Добавлен:
13.08.2013
Размер:
4.96 Mб
Скачать

cout .setf (ios:: fixed) ; //

фиксированный формат

(безэкспоненты)

i < 25;i++) {

 

for(int i << 0;

 

factorial *= number++;

cout << factorial << endl; } return(0);

}

Результаты работы программы будут такими:

1

2

6

24

120

720

5040

40320

362880

3628800

39916800

479001600

6227020800

87178291200

1307674368000

20922789888000

355687428096000

6402373705728000

121645100408832000

2432902008176640000

51090942171709440000

1124000727777607680000

25852016738884976640000

620448401733239439360000

15511210043330985984000000

Во втором примере на экран выводится таблица квадратов и квадратных корней целых чисел от 1 до 15.

//

//sqrt.cpp

//Эта программа на языке C++ строит таблицу квадратов и квадратных

//корней чисел от 1 до 15.

//

#include <iostream.h>

# include <math.h> main () {

double number =1.0,square, sqroot;

cout << "Число\tKвaдрат\t\tKвадратный корень\n";

cout << " ______________________________________ \n";

cout .setf (ios:: fixed) ; // фиксированный формат (без экспоненты) for(int i = 1; i < 16;i++) {

square = number * number; // вычисление квадрата числа

sqroot = sqrt(number);

//

нахождение корня

числа

cout.fill('0');

// заполнение недостающих

позиций нулями

cout.width(2);

// ширина

столбца — минимум 2 символа

cout.precision(0);

// 0 цифрпосле запятой

 

251

cout << number << "\t";

cout.fill(' '); //

использовать пробел в качестве заполнителя cout

<< square << "\t\t";

 

cout.precision(6); // 6 цифр после запятой cout<< sqroot<< endl;

number++; } return(0); }

Программа выведет следующую таблицу чисел:

число корень квадратный корень

01

1

1.000000

02

4

1.414214

03

9

1.732051

04

16

2.000000

05

25

2..236068

06

36

2.449490

07

49

2.645751

08

64

2.828427

09

81

3.000000

10

100

3.162278

11

121

3.316625

12

144

3.464102

13

169

3.605551

14

196

3.741657

15

225

3.872983

252

Глава 16. Концепции и средства программирования

вWindows

Основные понятия

o Среда Windows

o Преимущества Windows

oФормат исполняемых файлов

Базовые концепции программирования

oЧто представляет собой окно

o Компоненты окна

o Классы окон

o Графические объекты, используемые в окнах

o Принципы обработки сообщений

o Вызов системных функций

o Файл WINDOWS.H

oЭтапы создания приложения

Создание ресурсов приложений средствами Visual C++

oФайлы проектов

o Редакторы ресурсов

Языки С и C++ являются основными средствами программирования 32-разрядных приложений Windows. Раньше, когда решающим фактором была скорость выполнения программ, основным языком программирования считался ассемблер, но с появлением Windows ситуация коренным образом изменилась. В настоящей главе мы познакомимся с существующими подходами к созданию традиционных 32-разрядных приложений Windows.

Главу условно можно разбить на три части. В первой из них рассматриваются терминология и основные концепции программирования в Windows. Затем, во второй части, речь пойдет об окнах и графических компонентах приложений, таких как значки, шрифты и прочее. В третьейчасти мы поговорим о ресурсах Windows и редакторах ресурсов, предоставляемых компилятором Visual C++.

Примечание

Далее в книге под Windows подразумеваются Windows 95, Windows 98 и WindowsNT. Если описываемая возможность реализуется лишь одной из указанных версий, это оговаривается отдельно.

Основные понятия

Приложения Windows могут создаваться как традиционными методами процедурного программирования на языках С и C++, так и с помощью мощных средств объектноориентированного программирования, предоставляемых языком C++. В данном параграфе раскрываются основные концепции программирования в Windowsи объясняется используемая терминология.

Среда Windows

253

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

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

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

Преимущества Windows

Можно долго перечислять все открывающиеся перед пользователями преимущества среды Windows по сравнению с устаревшей операционной системой MS-DOS. Среди наиболее важных следует указать стандартизированный графический интерфейс пользователя, многозадачность, совершенные средства управления памятью, аппаратную независимость и возможность широкого применения библиотек динамической компоновки (DLL).

Графический интерфейс пользователя

Первое, что бросается в глаза при знакомстве с приложениями Windows, — это стандартизированный графический интерфейс. Графические стандарты со времени появления Windows 95 не претерпели кардинальных изменений. Для представления дисков, файлов, папок и других системных объектов используются специальные растровые изображения, называемые значками. Окно типичного приложения Windows показано на рис. 16.1.

254

Рис.16.1. Окно типичного Windows-приложения

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

Как правило, программы имеют сходный внешний вид окон и похожие наборы команд меню. Пользователю достаточно на примере одного приложения изучить основные операции по открытию и манипулированию файлами и данными, чтобы чувствовать себя вполне уверенно с любым другим приложением Windows. В качестве примера к сказанному давайте сравним внешний вид окон MicrosoftExcel и MicrosoftWord, представленных соответственно на рис. 16.2

и рис. 16.3.

Нетрудно заметить, что окна построены по одному и тому же принципу и в строке меню присутствуют стандартные пункты — File, Edit и другие. Эти же пункты меню вы найдете в окне редактора Paint, показанном на рис. 16.1.

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

Рис. 16.2. Окно приложения Microsoft Excel

255

Рис. 16.3. Окно приложения Microsoft Word

Многозадачная среда

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

256

Рис. 16.4. Windows позволяет запускать несколько приложений одновременно

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

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

Ввод данных посредством очередей

Как вы уже знаете, в среде Windows память компьютера представляет собой совместно используемый ресурс. Таковыми являются и большинство устройств ввода, в частности клавиатура и мышь. Поэтому при разработке Windows-приложений становятся недоступными функции наподобие getchar()языка С, считывающие символы непосредственно с клавиатуры, равно как и потоки ввода/вывода языка C++. В среде Windows приложение не может обращаться напрямую к клавиатуре или мыши и получать данные непосредственно от них. Подобная задача выполняется самой Windows, которая заносит данные в системную очередь. Из очереди введенные данные распределяются между запущенными программами. Это осуществляется путем копирования сообщений из системной очереди в очереди соответствующих приложений. Затем, как только приложение оказывается готовым принять данные, оно считывает сообщения из своей очереди и распределяет их между открытыми окнами.

257

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

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

[NumLock], [Alt], [Shift] и [Ctrl].

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

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

Сообщения

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

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

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

Управление памятью

Одним из наиболее Важных ресурсов системы является память компьютера. Если в системе одновременно запущено несколько приложений, то они должны иметь возможность координировать свою работу таким образом, чтобы не вызывать конфликтов при распределении системных ресурсов. Так, в результате многократного открытия и закрытия программ память компьютера может оказаться фрагментированной. Windows обладает встроенной подсистемой дефрагментации памяти, организующей перемещение и объединение блоков памяти.

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

258

Приложения Windows могут совместно использовать функции, хранящиеся в отдельных исполняемых файлах общего доступа. Такие файлы называются библиотеками динамической компоновки (DLL — dynamic link libraries). Windows содержит встроенный механизм компоновки таких библиотек с программами на этапе выполнения. Для работы самой Windows необходим достаточно большой набор DLL-файлов. С целью упрощения работы с динамическими библиотеками в Windows применяется новый формат исполняемых файлов. Такие файлы содержат информацию, позволяющую системе управлять блоками кода и данных, а также выполнять динамическую компоновку.

Аппаратная независимость

Windows обеспечивает также независимость пользовательской среды от типа используемых аппаратных устройств. Благодаря этому программисты избавляются от необходимости наперед учитывать, какие именно монитор, принтер или устройство вода будут подключены к конкретному компьютеру. Ранее, при написании приложений для MS-DOS, необходимо было снабжать программы драйверами всех устройств, которые могут повстречаться программе на разных компьютерах. Например, дня того чтобы приложение MS-DOS могло выводить данные на принтеры любого типа, программист должен был позаботиться о том, чтобы программа содержала драйверы принтеров всех известных марок и типов. Поэтому при написании программы уйма времени уходила на переписывание практически одинаковых программ драйверов. Скажем, один вариант драйвера принтера LaserJet предназначался для приложения MicrosoftWord for DOS, другой вариант этого же драйвера — для MicrosoftWorks и т.д.

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

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

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

Чтобы избежать конфликтов при вводе данных, в Windows также определен минимальный набор кодов клавиш, которые должны распознаваться любым приложением. Стандартный набор кодов в целом соответствует раскладке ПК-совместимой клавиатуры. Если какая-нибудь фирма выпустит клавиатуру с дополнительными клавишами, не входящими в стандартный набор, то она должна позаботиться о специальном программном обеспечении, преобразующем коды этих клавиш в последовательности стандартных кодов, распознаваемых Windows. Минимальному набору кодов должны соответствовать команды, поступающие не только от клавиатуры, но и от всех других устройств ввода, в том числе от мыши. Таким образом, если какая-нибудь фирма выпустит четырехкнопочную мышь, то это не должно вас беспокоить, поскольку производитель сам позаботится о том, чтобы команды от дополнительных кнопок соответствовали стандартным кодам Windows.

Библиотеки динамической компоновки

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

259

интерфейс. DLL-файлы содержат функции, которые подключаются к программе во время ее выполнения (динамически), а не во время компиляции (статически).

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

Компоновщик автоматически копирует из библиотек и вставляет в исполняемый файл такие функции, как getchar () и printf (). Благодаря использованию подобного подхода программист избавляется от необходимости переписывать каждый раз базовые функции, чем достигается стандартность выполнения таких операций, как считывание символов, вводимых с клавиатуры,

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

ивыравнивания текста. Предоставление доступа к функциям и методам как к глобальным инструментам среды программирования обеспечивает возможность повторного использования кода — ключевая концепция объектно-ориентированного программирования.

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

— в ОЗУ хранится только одна копия библиотеки, используемая всеми приложениями.

Если в программе вызывается стандартная функция Windows, то компилятор должен сгенерировать по месту вызова машинный код, содержащий обращение по адресу, находящемуся в другом сегменте кода. Такое положение представляет собой определенную проблему, поскольку до тех пор, пока программа не будет запущена, невозможно угадать, каким будет адрес библиотечной функции. Решение этой проблемы в Windows называется отложенным связыванием, или динамической компоновкой. Начиная с Windows 3.0 и Microsoft С 6.0, компоновщик позволяет обращаться к функциям, адреса которых не известны в момент компоновки. Окончательная компоновка функции происходит лишь после того, как программа запускается и загружается в память.

В компиляторах C/C++ используются специальные импортируемые библиотеки, назначение которых состоит в подготовке приложений к динамической компоновке в среде Windows. Например, в библиотеке USER32.LIB перечислены все стандартные функции Windows, к которым можно обращаться в программах. В записях этой библиотеки определяются модули Windows, где хранятся соответствующие функции, а также, в большинстве случаев, порядковый номер функции в этом модуле.

Например, многие приложения Windows вызывают функцию PostMessage (). Во время компиляции программы компоновщик получает из файла USER32.LIB информацию о модуле и номере функции PostMessage() и встраивает эти данные в код программы. При запуске программы Windows считывает имеющуюся информацию и связывает программу с реальным кодом функции PostMessage ().

Формат исполняемых файлов

Для Windows был разработан новый формат исполняемых файлов. В частности, изменения коснулись заголовка файла, который теперь может содержать информацию об импортируемых функциях библиотек динамической компоновки. Чаще всего используются функции модулей KERNEL, USER и GDI, содержащих множество подпрограмм, связанных с различными рутинными операциями, в том числе с обработкой сообщений. Функции, хранящиеся в DLLмодулях, еще называют экспортируемыми. В соответствии с новым форматом исполняемых файлов, экспортируемые функции определяются по имени модуля и порядковому номеру функции в нем. Все DLL-файлы содержат таблицу точек входа, в которой перечислены адреса всех экспортируемых функций,

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

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

260

Соседние файлы в предмете Программирование на C++