		MFC Programming  
		from the 
		Ground Up 


					Herbert Shildt 


					Osborne McGraw-Hill 
Berkeley   New York  St. Louis  San Francisco  Auckland   Bogota   Hamburg   
London   Madrid   Mexico City Milan   Montreal   New Delhi   Panama City   
Paris   Sao Paulo   Singapore   Sydney  Tokyo  Toronto 


    Герберт Шилдт 

    ОСНОВЫ программирования 

    Перевод с английского и под редакцией В.Р. Гинзбурга 


    Дюссельдорф — Киев — Москва — Санкт-Петербург	Киев, BHV, 1997 


2


    УДК 681.3.06 
    Герберт Шилдт 
    MFC: основы программирования: Пер. с англ. 
    1997. - 560 с. 
    ISBN 5-7733-0021-4 
    — К.: Издательская группа BHV, 

    В книге рассматриваются все аспекты работы с MFC 4. Подробно описывается 
иерархия классов библиотеки и рассказывается о том, как создавать основные 
компоненты Windows-приложения, включая меню, диалоговые окна и различные 
элементы управления. Дается исчерпывающая информация об использовании новых 
элементов управления, таких как панели инструментов, окна просмотра деревьев и 
мастера. Детально объясняются механизмы реализации потоковой многозадачности, 
всплывающих меню и контекстной помощи. В книге содержится огромное число 
примеров, большая часть которых совместима с любой версией Windows, включая 
Windows 95 и Windows NT. 
    Книга предназначена для начинающих разработчиков Windows-приложений, но 
будет интересна и опытным программистам, желающим узнать об особенностях 
программирования в 32-разрядных системах. 
    ISBN 0-07-882222-Х ISBN 5-7733-0021-4 
    © McGraw-Hill, 1996 
    © Издательская группа BHV, 1997 Обложка АЛ.Стеценко 

3

    Предисловие 

    Библиотека MFC (Microsoft Foundation Classes) — это следующий этап в 
эволюции систем программирования под Windows. Как известно, написание программ 
для Windows — процесс достаточно трудоемкий, а результаты его далеко не всегда 
соответствуют затратам. Внушительный размер и сложность программной оболочки 
Windows делают создание даже маленькой утилиты для нее устрашающе трудным. 
Кроме того, в программах для Windows, написанных традиционным способом, с 
использованием API-функций, все детали должны быть реализованы явно. 
Библиотека MFC специально разрабатывалась для устранения большинства 
трудностей, связанных с программированием под Windows. И, как вы убедитесь, 
разработчикам это в значительной мере удалось. 
    Как и большинству программистов, вам предстоит освоить процесс написания 
совершенно новых программ: познакомиться с новыми методами; проблемами, 
которых следует избегать, и изменениями в структуре программ, с которыми 
придется считаться. Иногда необходимо будет вернуться немного назад и 
рассмотреть некоторые вещи с точки зрения перспективы. Хотя программисты 
трудятся непрерывно уже многие годы, подавляющее большинство приложений для 
Windows еще только предстоит написать! Поэтому значение библиотеки MFC трудно 
переоценить. Увеличение спроса на программы для Windows вызовет потребность в 
средствах, позволяющих писать такие программы с меньшими затратами и в более 
короткие сроки. MFC как раз и отвечает этой потребности. Проще говоря, Windows 
является наиболее значительной операционной системой, для которой пишутся 
программы, a MFC обеспечивает самый быстрый способ их написания. Будьте 
уверены: программисты, умеющие работать с MFC, вскоре начнут цениться очень и 
очень высоко. 
    Таким образом, читая книгу, вы сможете изучить основы программирования с 
использованием MFC. Кроме того, вы познакомитесь с различными методиками и 
трюками, которые позволят вам стать первоклассным программистом. 

    Предисловие     5 

    С какой версией Windows работать? 

    В настоящее время широко используются три версии Windows: Windows 3.1, 
Windows 95 и Windows NT. Поскольку программный код, содержащийся в библиотеке 
MFC, в значительной степени независим от используемой платформы, большая часть 
информации и примеров, имеющихся в книге, применима ко всем трем системам. 
Однако будущее — за 32-разрядными системами. Как вы сами увидите, некоторые 
аспекты работы с MFC не подходят для старой, 16-разрядной среды Windows 3.1. 
Помните, что программные продукты следующего поколения будут написаны для 
32-разрядных версий Windows. 

    Для кого предназначена эта книга? 

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

    Какие программные средства необходимы? 

    Программы, тексты которых приведены в книге, были написаны, 
откомпилированы и протестированы в Visual C++ версии 4. Вам понадобится или 
этот, или любой другой компилятор с языка C++, позволяющий создавать 
Windows-совместимый объектный код. Кроме того, он должен поддерживать 
компиляцию программ, написанных с использованием MFC. 
    Все примеры, содержащиеся в книге, должны компилироваться как программы на 
C++. Это и неудивительно, ведь библиотека MFC содержит иерархию классов, 
написанных на C++. Это означает, что исходные файлы должны иметь расширение 
СРР. Необходимо также установить соответствующие опции компилятора, 
относящиеся к MFC. Например, при работе в Visual C++ нужно указать на 
использование статической библиотеки MFC или разделяемой DLL-библиотеки. 

    6	MFC: основы программирования 


    MFC и Windows 

    Изучив эту книгу, вы научитесь писать программы для Windows с 
использованием библиотеки классов Microsoft Foundation Classes (MFC). Книга 
представляет собой в основном практическое пособие, с помощью которого вы 
сможете освоить программирование под Windows в кратчайшие сроки. Таким 
образом, в ней не затрагиваются глубоко теоретические аспекты  Windows или 
MFC. Однако нужно хотя бы в общих чертах разобраться, что такое MFC и для чего 
эта библиотека была создана. Затем вам предстоит узнать, как работает Windows, 
каким образом она взаимодействует с программами, каковы основные элементы 
любого Windows-приложения и каких правил программирования следует 
придерживаться. С этой целью в данной главе содержится краткое объяснение 
концепции и принципов построения библиотеки MFC. В завершение рассматриваются 
некоторые аспекты Windows с точки зрения программиста. 

7

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

    Что такое MFC? 

    MFC — это базовый набор (библиотека) классов, написанных на языке C++ и 
предназначенных для упрощения и ускорения процесса программирования под 
Windows. Библиотека содержит многоуровневую иерархию классов, насчитывающую 
около 200 членов. Они дают возможность создавать Windows-приложения на базе 
объектно-ориентированного подхода. С точки зрения программиста, MFC 
представляет собой каркас, на основе которого можно писать программы для Windows. 
    Библиотека MFC разрабатывалась для упрощения задач, стоящих перед 
программистом. Как известно, традиционный метод программирования под Windows 
требует написания достаточно длинных и сложных программ, имеющих ряд 
специфических особенностей. В частности, для создания только каркаса программы 
таким методом понадобится около 75 строк кода. По мере  же увеличения сложности 
программы ее код может достигать поистине невероятных размеров. Однако та же 
самая программа, написанная с использованием MFC, будет примерно в три раза 
меньше, поскольку большинство частных деталей скрыто от программиста. 
    Одним из основных преимуществ работы с MFC является возможность 
многократного использования одного и того же кода. Так как библиотека содержит 
много элементов, общих для всех Windows-приложений, нет необходимости каждый 
раз писать их заново. Вместо этого их можно просто наследовать (говоря языком 
объектно-ориентированного программирования). Кроме того, интерфейс, 
обеспечиваемый библиотекой, практически независим от конкретных деталей, его 
реализующих. Поэтому программы, написанные на основе MFC, могут быть легко 
адаптированы к новым версиям Windows (в отличие от большинства программ, 
написанных обычными методами). 
    Еще одним существенным преимуществом MFC является упрощение взаимодействия 
с прикладным программным интерфейсом (API) Windows. Вы, вероятно, знаете, что 
любое приложение взаимодействует с Windows через API, который содержит 
несколько сот функций. Внушительный размер API затрудняет попытки понять и 
изучить его целиком. Зачастую даже сложно проследить, как отдельные части API 
связаны друг с другом! Но поскольку библиотека MFC объединяет (путем 
инкапсуляции) функции API в логически организованное множество классов, 
интерфейсом становится значительно легче управлять. (Позже мы еще вернемся к 
этой теме.) 
    И последнее. Небольшое число классов, определенных в библиотеке, не 
связано непосредственно с программированием под Windows. Это, в частности, 
классы, предназначенные для создания строк, управления файлами и обработки особых 

    10  MFC: основы программирования 

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

    Связь MFC и C++ 

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

    Примечание: Читателям, желающим пополнить свои знания о языке C++, автор 
может порекомендовать собственную книгу "C++: полный справочник, 2-е изд." — 
"C++: The Complete Reference, 2d ed." (Berkeley, CA: Osborne/McGraw-Hill, 
1995). Тем же, кто совсем не знает C++, автор советует прочесть книгу "C++ с 
самого начала" — "C++ from the Ground Up" (Berkeley, CA: Osborne/McGraw-Hill, 1994). 

    16-ти или 32-разрядные приложения? 

    Как известно, в настоящее время существуют три основные разновидности 
Windows: Windows 3.1, Windows 95 и Windows NT. Windows 3.1 — это 16-разрядная 
система, выполняющаяся поверх DOS. Хотя к моменту написания книги она все еще 
широко использовалась, дни ее уже сочтены. Тем не менее специально для нее 
пока еще создается небольшое число продуктов, поскольку 32-разрядные 
приложения не могут корректно выполняться в 16-разрядной среде (правда. 
Windows 3.1 поддерживает некоторое подмножество 32-разрядного кода). Windows 
95 и Windows NT являются уже полностью 32-разрядными операционными системами. 
    Обе  эти  системы   поддерживают весь  набор функций  Windows 3.1,  а 
также включают много новых важных возможностей. В частности, поддерживается 
32-разрядная линейная адресация, потоковая многозадачность и интерфейс 
управления консолью. Будучи 32-разрядными, Windows 95 и Windows NT лишены 
большинства недостатков и проблем, связанных со старой, 16-разрядной системой. 

    1. MFC и Windows	11 

    Аналогичный переход справедлив и для MFC. Начиная с версии 3.0, библиотека 
также стала 32-разрядной. Как будет показано ниже, существенные отличия 
вызваны здесь не столько тем, что новые версии MFC написаны специально для 
32-разрядных систем (хотя это действительно так), а в основном потому, что 
большинство новых возможностей Windows поддерживается только 32-разрядными 
оболочками. Поэтому многие из этих возможностей окажутся недоступными для 
приложений, написанных в 16-разрядном коде. 
    Поскольку подавляющее большинство новых программных продуктов выпускаются 
32-разрядными, то в данной книге будут рассмотрены вопросы программирования 
именно 32-разрядных приложений с использованием MFC. Тем не менее большая 
часть информации и примеров может быть использована применительно к Windows 
3.1. Поэтому, если вы все еще работаете в этой системе, вам не о чем 
беспокоиться. Прочитав книгу, вы научитесь программировать под Windows с 
использованием MFC. Однако не стоит забывать, что будущее все-таки за 
32-разрядными приложениями. 
    Именно им будет посвящена оставшаяся часть книги. В качестве операционной 
системы была выбрана Windows 95, потому что это наиболее популярная и 
законченная 32-разрядная Windows-платформа. Но вся информация в книге 
применима к любой полностью 32-разрядной системе. 

    Какую версию MFC выбрать? 

    С тех пор как в 1992 г. была представлена MFC 1.0, появилось несколько 
новых версий библиотеки. В данной книге описывается самая последняя из них, 
версия 4, поставляемая с Visual C++ 4. MFC 4 полностью поддерживает новую 
программную оболочку Windows 95 и элементы ее интерфейса. Правда, следует 
отметить, что большая часть информации в книге справедлива для всех версий 
MFC. Это и неудивительно, ведь MFC разрабатывалась с уметом совместимости 
различных версий. 

    Программная среда Windows 

    Если раньше вам не приходилось заниматься программированием под Windows, 
вы будете удивлены, потому что программы, написанные для этой операционной 
системы, не похожи на программы других типов. Хотя при использовании 
библиотеки MFC подобные различия не столь заметны, все же написание программ 
для Windows гораздо сложнее, чем для DOS или Unix. Поэтому, прежде чем начать 
изучать структуру типичной Windows-программы, необходимо разобраться, как 
работает сама Windows и каковы принципы взаимодействия программ с ней. Давайте 
начнем с наиболее важных моментов. 

    Интерфейс вызовов функций в Windows 

    Если вы изучали DOS, вам должно быть известно, что программы обращаются к 
этой операционной системе, используя различные программные прерывания, 
например int 21h. Будучи достаточно удобным (хотя и не позволяя в полной мере

    12  MFC: основы программирования 

использовать все возможности DOS), такой метод является совершенно 
неприемлемым с точки зрения взаимодействия с многофункциональной, 
многозадачной операционной системой, каковой является Windows. Вместо этого в 
Windows реализован интерфейс вызовов функций. 
    Благодаря данному интерфейсу доступ к системным ресурсам осуществляется 
через целый ряд системных функций. Как уже упоминалось ранее, совокупность 
таких функций называется прикладным программным интерфейсом, или API 
(Application Programming Interface). Для взаимодействия с Windows приложение 
запрашивает функции API, с помощью которых реализуются все необходимые 
системные действия, такие как выделение памяти, вывод на экран, создание окон 
и т.п. 
    Как уже было сказано, библиотека MFC инкапсулирует многие функции API. 
Хотя программам и разрешено обращаться к ним напрямую, все же чаше это будет 
выполняться через соответствующие функции-члены. Как,правило, функции-члены 
либо аналогичны функциям API, либо непосредственно обращаются к нужной части 
интерфейса. 

    Библиотеки динамической загрузки (DLL) 

    Поскольку API состоит из большого числа функций, может сложиться 
впечатление, что при компиляции каждой программы, написанной для Windows, к 
ней подключается код довольно значительного объема. В действительности это не 
так. Функции API содержатся в библиотеках динамической загрузки (Dynamic Link 
Libraries, или DLL), которые загружаются в память только в тот момент, когда к 
ним происходит обращение, т.е. при выполнении программы. Рассмотрим, как 
осуществляется механизм динамической загрузки. 
    Функции API хранятся в виде загружаемых модулей внутри DLL-библиотек. На 
этапе компиляции, когда компоновщик встречает вызов API-функции, он не 
помещает ее код в исполняемый файл. Вместо этого он помещает в него команды 
вызова данной функции, содержашие указатель на DLL-библиотеку, в которой 
хранится функция, и имя функции. На этапе выполнения программы соответствующая 
функция вызывается загрузчиком Windows. Таким образом приложения избавляются 
от необходимости содержать весь API-код. Функции API вызываются только тогда, 
когда приложение загружается в память для выполнения. 
    Динамическая загрузка обеспечивает ряд существенных преимуществ. 
Во-первых, поскольку практически все программы используют API-функции, то 
благодаря DLL-библиотекам существенно экономится дисковое пространство, 
которое в противном случае занималось бы большим количеством повторяющегося 
кода, содержащегося в каждом из исполняемых файлов. Во-вторых, изменения и 
улучшения в Windows-приложениях сводятся к обновлению только содержимого 
DLL-библиотек. Уже существующие тексты программ не требуют перекомпиляции. 

    Win 16 или Win32 

    В настоящее время широко распространены две версии API. Первая называется 
Win16 и представляет собой 16-разрядную версию, используемую в Windows 3.1. 
Вторая, 32-разрядная версия, называется Win32 и используется в Windows 95 и 
Windows NT. Win32 является надмножеством для Win16 (т.е. фактически включает в 

    7. MFC и Windows	13 

себя этот интерфейс), так как большинство функций имеет то же название и 
применяется аналогичным образом. Однако, будучи в принципе похожими, оба 
интерфейса все же отличаются друг от друга. Win32 поддерживает 32-разрядную 
линейную адресацию, тогда как Win 16 работает только с 16-разрядной 
сегментированной моделью памяти. Это привело к тому, что некоторые функции 
были модифицированы таким образом, чтобы принимать 32-разрядные аргументы и 
возвращать 32-разрядные значения. Часть из них пришлось изменить с учетом 
32-разрядной архитектуры. Была реализована поддержка потоковой 
многозадачности, новых элементов интерфейса и прочих нововведений Windows. 
Если прежде вам не приходилось программировать под Windows, подобные изменения 
не покажутся вам существенными, поскольку вы, очевидно, с самого начата будете 
писать 32-разрядные приложения. Если же необходимо переписать старый код для 
работы под Windows 95 или Windows NT, то изменения придется учитывать. 
    Как уже упоминалось, новые версии библиотеки MFC требуют наличия 
интерфейса Win32 API. Но если немного ограничить возможности программ, то 
можно с помощью MFC создавать приложения и для Windows 3.1, потому что она 
содержит усеченный набор функций Win32, называемый Win32s. 
    Так как Win32 поддерживает полностью 32-разрядную адресацию, то логично, 
что целые типы данных (integers) также объявлены 32-разрядными. Это означает, 
что переменные типа int и unsigned будут иметь длину 32 бита, а не 16, как в 
Windows 3.1. Если же необходимо использовать переменную или константу длиной 
16 бит, они должны быть объявлены как short. (Дальше будет показано, что для 
этих типов определены независимые typedef-имена.) Следовательно, при переносе 
программного кода из 16-разрядной среды необходимо убедиться в правильности 
использования целочисленных элементов, которые автоматически будут расширены 
до 32 битов, что может привести к появлению побочных эффектов. 
    Другим следствием 32-разрядной адресации является то, что указатели больше 
не нужно объявлять как near или far. Любой указатель может получить доступ к 
любому участку памяти. В Windows 95 и Windows NT константы near и far 
объявлены (с помощью директивы #define) пустыми. 

    Интерфейс GDI 

    Одним из подмножеств API является GDI (Graphics Device Interface — 
интерфейс графического устройства). GDI — это та часть Windows, которая 
обеспечивает поддержку аппаратно-независимой графики. Благодаря функциям GDI 
Windows-приложение может выполняться на самых различных компьютерах. 

    Многозадачность в Windows 

    Как известно, все версии Windows поддерживают многозадачность. В Windows 
3.1 имеется только один тип многозадачности — основанный на процессах. В более 
передовых системах, таких как Windows 95 и Windows NT, поддерживается два типа 
многозадачности: основанный на процессах и основанный на потоках. Давайте 
рассмотрим их чуть подробнее. 
    Процесс — это программа, которая выполняется. При многозадачности такого 
типа две или более программы могут выполняться параллельно. Конечно, они по 
очереди используют ресурсы центрального процессора и, с технической точки зрения, 

    14 MFC: основы программирования 

выполняются неодновременно, но благодаря высокой скорости работы 
компьютера этого практически не заметно. 
    Поток — это отдельная часть исполняемого кода. Название произошло от 
понятия "направление протекания процесса". В многозадачности данного типа 
отдельные потоки внутри одного процесса также могут выполняться одновременно. 
Все процессы имеют по крайней мере один поток, но в Windows 95 и Windows NT их 
может быть несколько. 
    Отсюда можно сделать вывод, что в Windows 95 и Windows NT допускается 
существование процессов, две или более частей которых выполняются 
одновременно. Оказывается, такое предположение верно. Следовательно, при 
работе в этих операционных системах возможно параллельное выполнение как 
программ, так и отдельных частей самих программ. Как вы убедитесь, это 
позволяет писать очень эффективные программы.
    Есть и другое существенное различие между многозадачностями Windows 3.1 и 
Windows 95/NT. В Windows З.1 используется неприоритетная многозадачность. Это 
означает, что процесс, выполняющийся в данный момент, получает доступ к 
ресурсам центрального процессора и удерживает их в течение необходимого ему 
времени. Таким образом, неправильно выполняюшаяся программа может захватить 
все ресурсы процессора и не давать выполняться другим процессам. В отличие от 
этого в Windows 95 и Windows NT используется приоритетная многозадачность. В 
этом случае каждому активному потоку предоставляется определенный промежуток 
времени работы процессора. По истечении данного промежутка управление 
автоматически передается следующему потоку. Это не дает возможность программам 
полностью захватывать ресурсы процессора. Интуитивно должно быть понятно, что 
такой способ более предпочтителен. 

    Взаимодействие программ и Windows 

    Во многих операционных системах взаимодействие между системой и программой 
инициализирует программа. Например, в DOS программа запрашивает разрешение на 
ввод и вывод данных. Говоря другими словами, нe-Windows-программы сами 
вызывают операционную систему. Обратного процесса не происходит. В Windows все 
совершенно наоборот: именно система вызывает программу. Это осушествлястся 
следующим образом: программа ожидает получения сообщения от Wjndows. Когда 
это происходит, то выполняется некоторое действие. После его завершения 
программа ожидает следующего сообщения. 
    Windows может посылать программе сообщения множества различных типов. 
Например, каждый раз при щелчке мышью в окне активной программы посылается 
соответствующее сообщение. Другой тип сообщений посылается, когда необходимо 
обновить содержимое активного окна. Сообщения посылаются также при нажатии 
клавиши, если программа ожидает ввода с клавиатуры. Необходимо запомнить одно: 
по отношению к программе сообщения появляются случайным образом. Вот почему 
Windows-программы похожи на программы обработки прерываний: невозможно 
предсказать, какое сообщение появится в следующий момент. 

    1. MFC и Windows	15 


    Основы программирования под Windows 

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

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

    Функция WinMain()

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

    Функция окна 

    Все Windows-программы должны содержать специальную функцию, которая не 
используется в самой программе, но вызывается операционной системой. Эту 
функцию обычно называют функцией окна, или процедурой окна. Она вызывается 
Windows, когда системе необходимо передать сообщение в программу. Именно через 
нее осуществляется взаимодействие между программой и системой. Функция окна 
передает сообщение в своих аргументах. Согласно терминологии Windows, функции, 
вызываемые системой, называются функциями обратного вызова. Таким образом, 
функция окна является функцией обратного вызова. 
    Помимо принятия сообщения от Windows, функция окна должна вызывать 
выполнение действия, указанного в сообщении. Конечно, программа не обязана 
отвечать на все сообщения, посылаемые Windows. Поскольку их могут быть сотни, 
то большинство сообщений обычно обрабатывается самой системой, а программе 
достаточно поручить Windows выполнить действия, предусмотренные по умолчанию. 
    В большинстве Windows-программ задача создания функции окна лежит на 
программисте. При использовании библиотеки MFC такая функция создается 
автоматически. В этом заключается одно из преимуществ библиотеки. Но в любом 
случае, если сообщение получено, то программа должна выполнить некоторое 
действие. Хотя она может вызвать для этого одну или несколько API-функций, 
само действие было инициировано Windows. Поэтому именно способ взаимодействия 
с операционной системой через сообщения диктует общий принцип построения всех 
программ для Windows, написанных как с использованием MFC, так и без нее. 

    16 MFC: основы программирования 


    Цикл сообщений 

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

    Класс окна 

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

    Специфика программ для Windows 

    Как вы уже заметили, структура Windows-программ отличается от структуры 
программ других типов. Это вызвано двумя обстоятельствами: во-первых, способом 
взаимодействия между программой и Windows, описанным выше; во-вторых, 
правилами, которым следует подчиняться для создания стандартного интерфейса 
Windows-приложения (т.е. чтобы сделать программу "похожей" на Windows-приложение). 
    Цель Windows — дать человеку, который хотя бы немного знаком с системой, 
возможность сесть за компьютер и запустить любое приложение без 
предварительной подготовки. Для этого Windows предоставляет дружественный 
интерфейс пользователя. Теоретически, если вы сумели запустить одно 
Windows-приложение, то сумеете запустить и любое другое. Конечно, на практике 
придется немного потренироваться, чтобы научиться использовать большинство 
программ с максимальной эффективностью. Однако это связано исключительно с 
тем, что программа делает, а не с тем, как ею пользоваться. Ведь, фактически, 
значительная часть кода Windows-приложения предназначена именно для 
организации интерфейса с пользователем. 
    Хотя создание удобного интерфейса "под Windows" является основной задачей 
при написании любой Windows-программы, такой интерфейс не создается автоматически. 

    1. MFC и Windows	17 

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

    Типы данных в Windows 

    Как вы вскоре убедитесь, в Windows-программах вообще (и в использующих 
библиотеку MFC в частности) не слишком широко применяются стандартные типы 
данных из С или C++, такие как int или char*. Вместо них используются типы 
данных, определенные в различных библиотечных (header) файлах. Наиболее часто 
используемыми типами являются HANDLE, HWND, BYTE, WORD, DWORD, UINT, LONG, 
BOOL, LPSTR и LPCSTR. Тип HANDLE обозначает 32-разрядное целое, используемое в 
качестве дескриптора. Есть несколько похожих типов данных, но все они имеют ту 
же длину, что и HANDLE, и начинаются с литеры Н. Дескриптор — это просто 
число, определяющее некоторый ресурс. Например, тип HWND обозначает 
32-разрядное целое — дескриптор окна. В программах, использующих библиотеку 
MFC, дескрипторы применяются не столь широко, как это имеет место в 
традиционных программах. Тип BYTE обозначает 8-разрядное беззнаковое 
символьное значение, тип WORD — 16-разрядное беззнаковое короткое целое, тип 
DWORD — беззнаковое длинное целое, тип UINT — беззнаковое 32-разрядное целое. 
Тип LONG эквивалентен типу long. Тип BOOL обозначает целое и используется, 
когда значение может быть либо истинным, либо ложным. Тип LPSTR определяет 
указатель на строку, а LPCSTR — константный (const) указатель на строку. 

    Соглашение об использовании имен 

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

    18  MFC: основы программирования 

    Префиксы типов приведены в табл. 1.1. Откровенно говоря, использование 
этих префиксов считается спорным и не всегда соблюдается. Многие программисты 
придерживаются этого правила, а многие — нет. В примерах, приведенных в книге, 
префиксы используются только тогда, когда это кажется достаточно разумным. Вы 
же можете поступать так, как вам нравится. 

    Таблица 1.1. Символы префиксов типов переменных Префикс b 

    Тип данных 
    с	символ (один байт) 
    С	класс 
    dw	длинное беззнаковое целое 
    f	16-разрядное битовое поле (флаги) 
    fn	функция 
    h	дескриптор 
    l	длинное целое 
    lр	 длинный указатель 
    п	короткое целое 
    р	указатель 
    pt	длинное целое, хранящее экранные координаты 
    w	короткое беззнаковое целое 
    sz	указатель на строку, завершающуюся символом '\0' 
    Ipsz	длинный указатель на строку, завершающуюся символом '\0' 
    rgb	длинное целое, хранящее значение цвета в формате RGB 


    1. MFC и Windows 19 


    Элементы окна 
    Пиктограмма системного меню 
    Кнопка минимизации 
    Кнопка максимизации 
    Заголовок 
    Кнопка закрытия 
    Рамка 
    Вертикальная — полоса прокрутки 
    Горизонтальная  полоса прокрутки 
    Рабочая  область 

    Рис. 1.1. Элементы стандартного окна 

    Прежде чем продолжить, необходимо определиться с некоторыми важными 
терминами. На рис. 1.1 изображено стандартное окно и указаны его элементы. 
    Любое окно имеет рамку, которая задает границы окна и используется для 
масштабирования. В верхней части окна расположено несколько элементов. В 
верхнем левом углу находится пиктограмма системного меню (называемая также 
пиктограммой строки заголовка). По щелчку на ней раскрывается системное меню. 
Справа от этой пиктограммы находится заголовок окна. В правом верхнем углу 
помещаются кнопки минимизации, максимизации и закрытия. (В старых версиях 
Windows кнопки закрытия нет. Она появилась только в Windows 95.) Рабочая 
область — это часть окна, в которой происходит работа программы. Большинство 
окон также содержат горизонтальную и вертикальную полосы прокрутки, 
предназначенные для перемещения документа внутри окна. 

    20 MFC: основы программирования 
