|
|
| ::Главная ->Литература ->Руководство по программированию в Windows | |
|
Содержание
::Новости::F.A.Q. ::Форум ::Компоненты ::Исходники ::Литература ::Рассылка ::Ссылки
Клуб
::Клуб программистов::Члены клуба ::off-форум ::off-чат
Работа
::Есть программисты::Есть вакансии ::Программы на заказ ::Готовые программы
Другое
::О сайте::Голосование ::Модератору |
Оглавление
Windows 3.0/pg/2#3 = 1 =
Глава 8. Блоки управления.....................................6
8.1 Что такое блок управления?................................6
8.2 Создание блока управления.................................6
8.2.1 Определение класса блока управления.....................7
8.2.2 Выбор типа блока управления.............................8
8.2.3 Определение родительского окна..........................9
8.2.4 Выбор идентификатора блока управления..................10
8.3 Использование блоков управления..........................10
8.3.1 Получение ввода от пользователя........................10
8.3.2 Передача управляющих сообщений.........................11
8.3.3 Как сделать блок управления доступным или...............11
8.3.4 Перемещение и изменение размера блока управления.......12
8.3.5 Разрушение блока управления............................12
8.4 Создание и использование некоторых наиболее часто........12
8.4.1 Использование клавишных блоков управления..............13
8.4.2 Использование статических блоков управления............18
8.4.3 Использование панелей перечней.........................18
8.4.4 Комбинированные блоки управления.......................30
8.4.5 Редактируемые блоки....................................32
8.4.6 Строки прокрутки.......................................35
8.5 Пример прикладной программы EditCntl.....................38
8.5.1 Добавление константы во включаемый файл................39
8.5.2 Добавление новых переменных............................39
8.5.3 Добавление функции CreateWindow........................39
8.5.4 Модификация фрагмента WM_COMMAND.......................41
8.5.5 Добавление фрагмента WM_SETFOCUS.......................41
8.5.6 Добавление фрагмента WM_SIZE...........................41
8.5.7 Трансляция и компоновка................................42
8.6 Заключение...............................................42
Глава 9. Панель диалога.......................................44
9.1 Что такое панель диалога.................................44
9.1.1 Модальные панели диалога...............................45
9.1.2 Немодальные панели диалога.............................45
9.2 Использование панели диалога.............................46
9.2.1 Создание функции панели дилога.........................47
9.2.2 Использование блоков управления в панелях диалога......48
9.3 Пример прикладной программы FileOpen.....................48
9.3.1 Добавление константы во включаемый файл................50
9.3.2 Создание шаблона панели диалога Open...................50
9.3.3 Добавление новых переменных............................51
9.3.4 Добавление фрагмента IDM_OPEN..........................52
9.3.5 Создание функции OpenDlg...............................53
9.3.6 Добавление вспомогательных функций.....................56
9.3.7 Экспортирование функции диалога........................58
9.3.8 Трансляция и компоновка................................58
9.4 Заключение...............................................58
Глава 10. Ввод и вывод из файлов..............................60
10.1 Правила работы с файлами в среде Windows.................60
10.2 Создание файлов.........................................62
10.3 Открытие существующих файлов............................63
10.4 Чтение и запись файлов..................................64
10.5 Повторное открытие файлов...............................64
10.6 Запрос имени файла......................................65
.
Windows 3.0/pg/2#3 = 2 =
10.7 Проверка состояния файла................................65
10.8 Простой редактор файлов EditFile........................65
10.8.1 Добавление констант во включаемый файл................66
10.8.2 Добавление панели диалога SaveAs......................66
10.8.3 Добавление операторов include.........................67
10.8.4 Добавление новых переменных............................67
10.8.5 Замена фрагмента WM_COMMAND...........................68
10.8.6 Добавление фрагментов WM_QUERYENDSESSION и
WM_CLOSE.....................................................71
10.8.7 Модификация функции диалога OpenDlg...................71
10.8.8 Добавление функции диалога SaveAsDlg..................72
10.8.9 Добавление вспомогательных функций.....................74
10.8.10 Экспорт функции диалога SaveAsDlg....................77
10.8.11 Расширение динамической области памяти................77
10.8.12 Трансляция и компоновка..............................78
10.9 Заключение..............................................78
11.1 Что такое растровая карта...............................80
11.2 Создание растровых карт.................................80
11.2.1 Создание и загрузка файлов растровых карт.............80
11.2.2 Создание и заполнение пустых растровых карт...........82
11.2.3 Создание растровых карт с помощью фиксированных.......83
11.2.4 Рисование цветных растровых карт......................87
11.3 Отображение растровых карт на экране....................88
11.3.1. Индицирование растровой карты с помощью
функции......................................................89
11.3.2 Растяжение растровых карт.............................91
11.3.3 Использование растровых карт в кисти шаблона..........92
11.3.4 Индицирование аппаратно-независимых растровых
карт.........................................................94
11.3.5 Использование растровой карты в качестве элемента....95
11.4 Добавление цвета к монохромной растровой карте..........95
11.5 Удаление растровых карт.................................96
11.6 Пример прикладной программы Bitmap......................96
11.6.1 Модификация включаемого файла.........................98
11.6.2 Добавление ресурсов растровой карты...................98
11.6.3 Добавление меню Bitmap, Pattern и Mode................98
11.6.4 Добавление глобальных и локальных переменных..........99
11.6.5 Добавление фрагмента WM_CREATE.......................100
11.6.6 Модификация фрагмента WM_DESTROY.....................104
11.6.7 Добавление фрагментов WM_LBUTTONUP, WM_MOUSEMOVE.....104
11.6.8 Добавление фрагмента WM_RBUTTONUP....................105
11.6.9 Добавление фрагмента WM_ERASEBKGND...................105
11.6.10 Добавление фрагмента WM_COMMAND.....................106
11.6.11 Модификация make-файла..............................108
11.6.12 Трансляция и компоновка.............................108
11.7 Заключение.............................................108
Глава 12. Вывод на печать....................................110
12.1 Печать в среде Windows.................................110
12.1.1 Использование управляющих последовательностей........111
12.2 Получение информации о текущем принтере................111
12.3 Печать строки текста...................................113
12.4 Печать растровой карты.................................114
12.5 Обработка ошибок во время печати.......................116
.
Windows 3.0/pg/2#3 = 3 =
12.6 Отмена операции печати.................................118
12.6.1 Определение панели диалога...........................118
12.6.2 Определение функции панели диалога...................119
12.6.3 Функция прерывания печати............................119
12.6.4 Выполнение прерываемых операций печати...............121
12.6.5 Отмена операции печати с помощью ABORTDOC............122
12.7 Печать порциями........................................122
12.8 Пример прикладной программы PrntFile...................124
12.8.1 Добавление панели диалога AbortDlg..................124
12.8.2 Добавление переменных для печати.....................125
12.8.3 Добавление фрагмента IDM_PRINT.......................125
12.8.4 Создание функций AbortDlg и AbortProc................128
12.8.5 Добавление функции GetPrinterDC......................129
12.8.6 Экспортирование функции AbortDlg и AbortProc.........130
12.6.7 Компиляция и компоновка..............................130
12.9 Заключение.............................................130
Глава 13. Системный буфер....................................132
13.1 Использование системного буфера........................132
13.1.1 Копирование текста в системный буфер.................133
13.1.2 Вставка текста из системного буфера..................136
13.1.3 Вставка растровых карт из системного буфера..........138
13.1.4 Инструментальная программа Clipboard.................140
13.2 Использование специальных возможностей системного...141
13.2.1 Представление данных по запросу......................141
13.2.2 Представление форматов перед завершением работы......142
13.2.3 Регистрация собственных форматов.....................142
13.2.4 Управление отображением данных Clipboard...........142
13.3. Пример прикладной программы ClipText...................145
13.3.1 Добавление новых переменных..........................146
13.3.2 Модификация программы инициализации экземпляра.......146
13.3.3 Добавление фрагмента WM_INITMENU.....................147
13.3.4 Модификация фрагмента WM_COMMAND.....................147
13.3.5 Добавление фрагмента WM_PAINT........................150
13.3.6 Добавление функции OutOfMemory.......................150
13.3.7 Трансляция и компоновка..............................150
13.4 Заключение.............................................151
ЧАСТЬ 3. БОЛЕЕ СЛОЖНЫЕ РАЗДЕЛЫ...............................152
Глава 14. Язык С и язык Ассемблера...........................153
14.1 Выбор модели памяти....................................153
14.2 Использование NULL.....................................154
14.3 Использование аргументов командной строки и...155
14.4 Написание экспортируемых функций.......................156
14.4.1 Создание функции многократного вызова................156
14.4.2 Создание функции WinMain.............................157
14.5 Использование функций исполняющей системы С............158
14.5.1 Использование библиотек С............................158
14.5.2 Выделение памяти.....................................159
14.5.3 Работа со строками...................................159
14.5.4 Использование функций файлового ввода/вывода.........161
14.5.5 Использование функций ввода и вывода на консоль......162
14.5.6 Использование графических функций....................162
14.5.7 Использование вычислений с плавающей точкой..........162
14.5.8 Запуск других прикладных программ....................163
.
Windows 3.0/pg/2#3 = 4 =
14.5.9 Использование функций интерфейса с MS-DOS и BIOS.....163
14.5.10 Исключение стартового кода С........................164
14.6 Написание программ на языке ассемблера.................165
14.6.1 Изменение состояния флага прерывания.................167
14.6.2 Как на ассемблере написать экспортируемую функцию....168
14.6.3 Использование регистра ES............................169
14.7 Заключение.............................................170
Глава 15. Управление памятью................................172
15.1 Использование памяти...................................172
15.1.1 Использование глобальной динамической области
памяти......................................................173
15.1.2 Использование локальной динамической области
памяти......................................................174
15.1.3 Работа со сбрасываемой памятью.......................176
15.2 Использование сегментов................................178
15.2.1 Использование кодовых сегментов......................179
15.2.2 Сегменты данных......................................180
15.3 Пример прикладной программы Memory.....................180
15.3.1 Разделение исходного С-файла.........................181
15.3.2 Модификация включаемого файла........................182
15.3.3 Добавление новых определений сегментов...............182
15.3.4 Модификация файла make...............................183
15.3.5 Трансляция и компоновка..............................184
15.4 Заключение.............................................184
.
Windows 3.0/pg/2#3 = 5 =
----------------------------------------------------------------
ПРОГРАММА-СПРАВОЧНИК ПО
Microsoft Windows
Версия 3.0
Руководство по програмированию в среде Microsoft Windows
2#3
Москва 1991 г.
----------------------------------------------------------------
.
Windows 3.0/pg/2#3 = 6 =
Глава 8. Блоки управления.
----------------------------------------------------------------
Блоки управления - это специальные окна, позволяющие осу-
ществить простое взаимодействие с пользователем.
В данной главе описаны следующие разделы:
- Что такое блок управления.
- Создание блока управления.
- Использование блоков управления в прикладных программах.
В данной главе также описано создание прикладной программы
EditCntl, которая иллюстрирует использование блоков управления.
8.1 Что такое блок управления?
Блоки управления - это встроенные дочерние окна, через
которые осуществляется специальный вид ввода/вывода. Например,
если необходимо получить от пользователя имя файла, можно
создать и индицировать редактируемый блок управления для того,
чтобы дать возможность пользователю ввести имя. "Редактируемый
блок управления" - это предопределнное дочернее окно, которое
получает и отображает ввод с клавиатуры.
Блок управления подобно любому другому окну принадлежит
классу окна. Класс окна определяет атрибуты по умолчанию блока
управления и, что более важно, функцию окна блока управления.
Функция окна определяет, как блок управления будет выглядеть и
как он будет отвечать на действия пользователя. Функции окон
для блоков управления являются встроенными в Windows, так что
для их использования не требуется специального
программирования.
8.2 Создание блока управления.
Для создания блока управления можно использовать два
метода:
- Внутри панели диалога.
- Внутри области пользователя любого другого типа окон.
В данной главе обсуждается использование блоков управления
в стандартном окне. В главе 9, "Панели диалога", описано
создание блоков управления в панели диалога.
Можно создать блок управления, используя функцию
CreateWindow. В отличие от обычного применения этой функции для
создания окна программы необходимо указать:
- класс блока управления;
.
Windows 3.0/pg/2#3 = 7 =
- тип блока управления;
- родительское окно блока управления;
- идентификатор блока управления.
Функция CreateWindow возвращает дескриптор блока
управления, который может быть использован последующими
функциями для перемещения, рисования, указания размера или
разрушения окна, или для того, чтобы заставить окно выполнить
свои задачи.
В приведенном ниже примере показано, как создать блок
управления типа альтернативная клавиша:
hButtonWnd = CreateWindow(
"Button", /* класс клавиши */
"OK",
BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE,
20, /* координата по оси X */
40, /* координата по оси Y */
30, /* ширина в пикселях */
12, /* высота в пикселях */
hWnd, /* родительское окно */
IDOK, /* ID блока управления */
hInstance, /* дескриптор экземпляра */
NULL);
В данном примере создается блок управления типа
альтернативная клавиша, который принадлежит классу окна
"Button" и имеет тип BS_PUSHBUTTON. Блок управления является
дочерним окном и будет виден при первом создании. Необходимо
использовать тип WS_CHILD; однако, если для индикации блока
управления будет использоваться функция ShowWindow, то тип
WS_VISIBLE применять не нужно. Функция CreateWindow поместит
блок управления в точку с координатами (20, 40) в области
пользователя родительского окна. Его ширина и высота равны
соответственно 30 и 12 пикселей. Родительское окно
идентифицируется дескриптором hWnd. Константа IDOK - это
идентификатор блока управления.
Оставшаяся часть данного раздела посвящена обсуждению
того, как указать класс окна блока управления, его тип,
родительское окно и идентификатор.
8.2.1 Определение класса блока управления.
Класс окна блока управления, или класс блока управления
определяет функцию и атрибуты блока управления, используемые по
умолчанию. Вы указываете класс блока управления при его
создании. Для этого имя класса (например, BUTTON") включается в
качестве параметра lpClassName функции CreateWindow.
.
Windows 3.0/pg/2#3 = 8 =
Windows предоставляет следующие встроенные классы блоков
управления:
Класс Описание
---------------------------------------------------------------
BUTTON Небольшие помеченные окна, которые может выби-
рать пользователь, задавая возможные ответы
типа да/нет или вкл/выкл.
EDIT Окна, в которые пользователь может войти для
ввода и редактирования текста.
LISTBOX Окна, которые содержат перечни имен, из кото-
рых пользователь может выбрать нужные имена.
COMBOBOX Комбинированный блок управления, состоящий из
редактируемого или статического блока управле-
ния и подключенной к ним панели перечня. Поль-
зователь может выбирать элементы из панели пе-
речня и/или вводить в редактируемом блоке
управления.
SCROLLBAR Окна, которые выглядят и работают как строки
прокрутки.
STATIC Небольшие окна, содержащие текст или простое
изображение. Они часто используются для того,
чтобы пометить другие блоки управления или
отделить одну группу блоков управления от
другой.
---------------------------------------------------------------
8.2.2 Выбор типа блока управления.
Тип блока управления зависит от класса и определяет вид и
работу блока управления. Тип задается при создании блока
управления. Для этого он включается в параметре dwStyle
(например, BS_PUSHBUTTON) функции CreateWindow.
Windows содержит много предопределенных типов блоков
управления. Ниже приведены наиболее часто встречающиеся типы:
Тип Описание
---------------------------------------------------------------
BS_PUSHBUTTON Специфицирует блок управления типа
альтернативная клавиша, содержащий
метку, которую пользователь может
выбрать для уведомления родительского
окна.
BS_DEFPUSHBUTTON Специфицирует альтернативную клавишу по
умолчанию, которая идентична обычной
.
Windows 3.0/pg/2#3 = 9 =
альтернативной клавише, но имеет
специальную окантовку.
BS_CHECKBOX Специфицирует блок управления типа
панель контроля. Пользователь может
включать/выключать панель. Когда панель
контроля включена, то в ней появляется
знак "Х".
BS_RADIOBUTTON
Специфицирует блок управления типа
клавиша установки (небольшой кружок).
Пользователь может включать/выключать
данный блок управления. Когда клавиша
установки включена, кружок закрашен.
ES_LEFT Специфицирует однострочный выравненный
влево редактируемый блок управления.
ES_MULTILINE Специфицирует многострочный
редактируемый блок управления.
SS_LEFT Специфицирует выравненный влево
статический блок управления.
SS_RIGHT Специфицирует выравненный вправо
статический блок управления.
LBS_STANDARD Специфицирует стандартную панель
перечня. Стандартная панель перечня
включает строку прокрутки и уведомляет
ее родителькое окно, когда пользователь
делает выборку.
CBS_DROPDOWN Определяет комбинированный блок управ-
ления, содержащий редактируемый блок
управления и панель перечня, которая
отображается, когда пользователь
нажимает на блок, следующий за полем
выбора. Если выбирается элемент в панели
перечня, в редактируемом блоке
отображается выбранный элемент.
---------------------------------------------------------------
8.2.3 Определение родительского окна.
Поскольку каждый блок управления является дочерним окном,
необходимо родительское окно. Родительское окно указывается при
создании блока управления. Для этого включите дескриптор
родительского окна в качестве параметра hWndParent в вызов
функции CreateWindow.
Как любое дочернее окно блок управления подвергается
.
Windows 3.0/pg/2#3 = 10 =
изменеиям со стороны родительского окна. Например, если
родительское окно делается недоступным, блок управления также
будет недоступен. Если Windows рисует, перемещает или разрушает
родительское окно, он также рисует, перемещает или разрушает
блок управления.
Хотя блок управления может быть любого размера и
перемещаться в любое положение, он ограничен областью
пользователя родительского окна. Windows вырезает окно, если
оно перемещается за пределы области пользователя или становится
больше области пользователя.
8.2.4 Выбор идентификатора блока управления.
При создании блока управления он получает уникальный
идентификатор (или ID) блока управления. Идентификатор блока
управления при создании блока управления. Идентификатор
указывается в функции CreateWindow вместо дескриптора меню
(hMenu). Блок управления определяется этим идентификатором в
любом уведомляющем сообщении, которое он посылает функции
родительского окна. Идентификатор блока управления особенно
полезен, когда в окне имеются несколько блоков управления. Это
наиболее простой и быстрый способ отличить один блок управления
от другого.
8.3 Использование блоков управления.
После создания блока управления вы можете:
- Получить ввод от блока управления.
- Сообщить блоку управления, что необходимо выполнить
определенные задачи, например, вернуть строку текста.
- Сделать доступным или недоступным ввод в блок
управления.
- Переместить или изменить размер блока управления.
- Разрушить блок управления.
В данном разделе описано, как выполнить все эти задачи.
8.3.1 Получение ввода от пользователя.
При взаимодействии пользователя с блоком управления
последний посылает родительскому окну информацию об этом
взаимодействии в форме уведомляющих сообщений. Уведомляющее
сообщение - это сообщение WM_COMMAND, в котором:
- параметр wParam содержит идентификатор блока управления;
- параметр lParam содержит код уведомления и дескриптор
блока управления.
.
Windows 3.0/pg/2#3 = 11 =
Например, пользователь нажимает кнопку мыши, когда курсор
находится на блоке управления BUTTON, этот блок управления
посылает функции окна родителя сообщение WM_COMMAND. Сообщение
WM_COMMAND содержит в параметре lParam идентификатор блока
управления, а в старшем слове параметра lParam содержится код
уведомления BN_CLICKED, который указывает на то, что
пользователь нажал на данную мягкую клавишу.
Поскольку уведомляющее сообщение имеет ту же основную
форму, что и при вводе из меню, оно может обрабатываться во
многом аналогично. Если идентификаторы блоков управления были
выбраны так, что они не входят в конфликт с идентификаторами
элементов меню, можно обрабатывать уведомляющие сообщения в том
же операторе switch, который используется для обработки ввода
из меню.
8.3.2 Передача управляющих сообщений.
Большинство блоков управления принимают и обрабатывают ряд
сообщений. Это специальные сообщения, которые побуждают блок
управления выполнять некоторые уникальные для данного блока
управления задачи. Например, сообщение WM_GETTEXTLENGTH
предписывает редактируемому блоку управления возвратить длину
выбранной строки текста.
Сообщение блоку управления посылается функцией
SendMessage. Необходимо задать номер сообщения и значения
параметров wParam и lParam. Например, приведенный ниже оператор
посылает сообщение EM_GETTEXTLENGTH редактируемому блоку
управления, идентифицированному дескриптором hEditWnd, а затем
возвращает длину выбранной строки.
nLength=SendMessage(hEditWnd, WM_GETTEXTLENGTH, 0, 0L);
Многие блоки управления также обрабатывают стандартные
сообщения окон, такие как WM_HSCROLL и WM_VSCROLL. Можно
послать эти сообщения блокам управления тем же способом,
который использовался для посылки управляющих сообщений.
8.3.3 Как сделать блок управления доступным или
недоступным для ввода.
Можно сделать блок управления доступным или недоступным
для ввода, использовав функцию EnableWindow.
Когда вы делаете ввод в блок управления недоступным, этот
блок управления не реагирует на ввод от пользователя. Windows
делает данный блок "серым", чтобы указать пользователю, что
данный блок управления недоступен. В приведенном примере
показано, как сделать блок управления недоступным:
.
Windows 3.0/pg/2#3 = 12 =
EnableWindow(hButton, FALSE);
Можно возобновить ввод в блок управления, сделав его
доступным с помощью функции EnableWindow, указав параметр TRUE:
EnableWindow(hButton, TRUE);
8.3.4 Перемещение и изменение размера блока управления.
Можно перемещать или изменять размер блока управления,
используя функцию MoveWindow. Эта функция перемещает блок
управления в указанную точку области пользователя родительского
окна и устанавливает для блока управления заданную ширину и
высоту. Следующий пример демонстрирует, как переместить и
изменить размеры блока управления:
MoveWindow(hButtonWnd, 10, 10, 30, 12, TRUE);
В этом примере блок управления перемещается в точку (10,
10) в области пользователя; ширина и высота устанавливается
равной 30 и 12 пикселям соответственно. Значение TRUE говорит о
том, что после перемещения блок управления должен быть
перерисован.
Windows автоматически перемещает блок управления при
перемещении родительского окна. Положение блока управления
берется всегда относительно левого верхнего угла области
пользователя родительского окна, так что когда родительское
окно перемещается, блок управления остается фиксированным в
области пользователя, но перемещается относительно экрана.
Windows не изменяет размеры блока управления при изменении
родительского окна, но посылает сообщение WM_SIZE родительскому
окну для указания его нового размера. При желании можно
использовать это сообщение для того, чтобы дать блоку
управления новые размеры.
8.3.5 Разрушение блока управления.
Можно разрушить блок управления с помощью функции
DestroyWindow. Эта функция удаляет все внутренние записи и сам
блок управления из области пользователя родительского окна. В
приведенном примере показано, как разрушить блок управления:
DestroyWindow(hEditWnd);
Windows автоматически разрушает блок управления при
разрушении родительского окна. Вообще говоря, блок управления
необходимо разрушать только тогда, когда он в родительском окне
больше не нужен.
.
Windows 3.0/pg/2#3 = 13 =
8.4 Создание и использование некоторых наиболее часто
встречающихся блоков управления.
Далее в этой главе приведена более подробная информация об
использовании наиболее часто встречающихся блоков управления:
- Блок управления типа клавиша.
- Статический блок управления.
- Панель перечня.
- Комбинированный блок управления.
- Редактируемый блок управления.
- Строки прокрутки.
8.4.1 Использование клавишных блоков управления.
Клавишный блок управления - это небольшое окно,
используемое для простого ввода типа да/нет или вкл/выкл.
Существуют следующие наиболее часто используемые клавишные
блоки управления:
- Альтернативная клавиша.
- Альтернативная клавиша по умолчанию.
- Клавиша установки.
- Панель контроля.
- Клавиша, рисуемая владельцем.
- Групповая панель.
Альтернативные клавиши.
Клавишный блок управления - это клавиша, которая позволяет
пользователю выбрать определенное действие. Кдавиша содержит
текст, который определяет ее действие. Когда пользователь
"нажимает" ее, прикладная программа обычно выполняет связанные
с ней действия. Например, если пользователь в панели диалога
выбирает клавишу "Cancel", то прикладная программа немедленно
убирает панель диалога и отменяет все произведенные в панели
диалога установки (если они были произведены).
Можно создать клавишный блок управления, используя класс
"Button" и специфицируя тип клавиши. Например, приведенный ниже
вызов функции CreateWindow создает блок управления типа
альтернативная клавиша с меткой "Cancel":
.
Windows 3.0/pg/2#3 = 14 =
HWND hCancelButton;
.
.
.
hCancelButton=CreateWindow("Button", "Cancel",
BS_PUSHBUTTON ! WS_CHILD ! WS_VISIBLE,
20, 40, 30, 12, hWnd, ICANCEL, hInstance, NULL);
В данном примере специфицирован тип WS_VISIBLE, так что
при создании блока управления он индицируется. Идентификатор
блока управления равен ICANCEL. Эта константа определена в
файле windows.h и предназначена для использования с
альтернативными клавишами , такими как клавиша "Cancel".
Альтернативные клавиши по умолчанию.
Альтернативная клавиша по умолчанию обычно используется
для того, чтобы дать пользователю возможность сигнализировать
об окончании некоторой работы, например такой, как запись в
редактируемый блок управления имени файла. Блок управления типа
альтернативная клавиша по умолчанию (также как и другие типы
клавишных блоков управления) отвечают на ввод от "мыши" или
клавиатуры. Если пользователь перемещает курсор "мыши" в блок
управления и нажимает кнопку на ней, клавиша посылает
уведомляющее сообщение BN_CLICKED родительскому окну. Клавиша
не должна захватывать ввод для ответа на действия с "мышью", но
это необходимо делать в ответ на ввод с клавиатуры. Для того,
чтобы дать возможность пользователю использовать клавиатуру,
необходимо захватить ввод для клавиши с помощью функции
SetFocus. Пользователь может затем нажать клавишу пробела для
того, чтобы побудить клавишу послать уведомляющее сообщение
BN_CLICKED родительскому окну.
Создание альтернативной клавиши по умолчанию во многом
аналогично созданию обычной альтернативной клавиши. Укажите
класс блока управления "Button", а тип укажите в параметре
dwStyle функции CreateWindow. Например, приведенный ниже вызов
функции CreateWindow создает блок управления типа
альтернативная клавиша по умолчанию с меткой "OК":
HWND hDefButton;
. . .
hDefButton=CreateWindow("Button", "OК",
BS_DEFPUSHBUTTON ! WS_CHILD ! WS_VISIBLE,
20, 40, 30, 12, hWnd, IDOK, hInstance, NULL);
В данном примере специфицирован тип WS_VISIBLE, так что
при создании блока управления он индицируется. ID блока уп-
равления равен IDOK. Эта константа определена в файле
windows.h и предназначена для использования с альтернативны-
ми клавишами по умолчанию, такими как клавиша "OК".
Панель контроля.
Панель контроля обычно используется для выбора некоторого
.
Windows 3.0/pg/2#3 = 15 =
параметра, применяемого в данной задаче. По соглашению внутри
группы панелей контроля можно выбрать более одного параметра.
(Для представления параметров, в которых можно выбрать только
один, используйте блоки управления типа клавиши установки.)
Например, можно использовать группу панелей контроля для
того, чтобы дать возможность пользователю выбрать параметры
шрифта для операции вывода. Пользователь может выбрать как
Жирный шрифт, так и Курсив, указав "Bold" и "Italic".
Можно создать блок управления типа панель контроля,
используя тип BS_CHECKBOX, как в приведенном примере:
#define ID_ITALIC 201
HWND hCheckBox;
.
.
.
hCheckBox=CreateWindow("Button", "Курсив",
BS_CHECKBOX ! WS_CHILD ! WS_VISIBLE,
20, 40, 80, 20, hWnd, ID_ITALIC, hInstance,
NULL);
В этом примере метка панели контроля - "Курсив", а
идентификатор блока управления - ID_ITALIC.
Панель контроля отвечает на ввод от "мыши" или клавиатуры
во многом также, как и блок управления типа альтернативная
клавиша. Другими словами, она посылает уведомляющее сообщение
родительскому окну, когда пользователь нажимает клавишный блок
управления или клавишу пробела. Однако панель контроля может
индицировать метку "Х" для того, чтобы показать, что она в
данный момент включена (выбрана).
Можно побудить блок управления показать отметку,
используя сообщение BM_SETCHECK. Можно также проверить, имеет
ли панель контроля отметку, используя сообщение BM_GETCHECK.
Например, для помещения отметки в панель контроля используйте
следующую функцию:
SendMessage(hCheckBox, BM_SETCHECK, 1, 0L);
Это означает, что можно поместить или удалить отметку из
панели контроля в любой момент (например, когда функция
родительского окна получает уведомляющее сообщение BN_CLICKED).
Windows также обеспечивает режим BS_AUTOCHECKBOX, который
служит для автоматического размещения или удаления контрольной
отметки.
Клавиши установки.
Блоки управления типа клавиша установки работают во многом
также, как и панели контроля. Однако, клавиши установки обычно
.
Windows 3.0/pg/2#3 = 16 =
используются группами, которые представляют взаимно исключающие
возможности. Например, вы можете использовать группу клавиш
установки для того, чтобы дать пользователю возможность указать
выравнивание текста (влево, вправо или по центру). Клавиши
установки позволяют пользователю выбрать только один тип
выравнивания.
Клавиша установки создается аналогично другим блокам
управления. Укажите класс "Button" в качестве класса окна и
укажите тип посредством параметра dwStyle. Например, ниже
приведены операторы, создающие клавишу установки с текстом
"Right":
HWND hRightJustifyButton;
#define IDC_RIGHTJUST
.
.
.
hRightJustifyButton = CreateWindow("Button", "Right",
BS_RADIOBATTON | WS_CHILD | WS_VISIBLE,
20, 40, 80, 20, IDC_RIGHTJUST, hInstance, NULL);
Как и в случае с панелью контроля вы можете послать
клавише установки сообщение BM_SETCHECK, чтобы клавиша
установки отобразила пометку (обычно закрашенный кружок).
Также, поскольку клавиша установки предоставляет возможность
выбора из взаимно исключающих возможностей, то необходимо
послать сообщение BM_SETCHECK клавише, которая была выбрана до
этого (если такая была), чтобы сбросить отметку. Вы можете
определить, какая из клавиш установки была выбрана, посылая
каждой клавише в группе сообщение BM_GETCHECK.
В панели диалога вы можете создать клавишу установки с
типом BS_AUTORADIOBUTTON. Если все клавиши установки в группе
имеют этот тип, Windows автоматически удалит старую отметку при
выборе нового элемента.
Для проверки и удаления отметок с клавиш установки в
панели диалога вы можете использовать функцию CheckRadioButton.
При вызове функции CheckRadioButton вы передаете ей
идентификаторы первой и последней клавиши установки в группе, а
также идентификатор клавиши в этом диапазоне, которая должна
быть помечена. Windows удаляет отметки со всех клавиш в
указанном диапазоне и помечает данную клавишу. Например, в
группе клавиш установки, представляющих выравнивание текста, вы
можете вызвать функцию CheckRadioButton для отметки клавиши
"Right". Это делается следующим образом:
CheckRadioButton(hDlg, ID_RIGHTLEFTJUST, ID_LEFTJUST,
ID_RIGHTJUST);
В этом примере CheckRadioButton отмечает клавишу установки
с идентификатором ID_RIGHTJUST и удаляет все отметки с клавиш в
.
Windows 3.0/pg/2#3 = 17 =
диапазоне от ID_RIGHTLEFTJUST до ID_LEFTJUST.
Клавиши, рисуемые владельцем.
Рисуемые владельцем клавиши аналогичны остальным типам
клавишных блоков управления, за исключением того, что
прикладная программа отвечает за поддержку вида клавиши,
включая те моменты, когда клавиша захватывает ввод, делается
недоступной или когда ее выбирают. Windows просто сообщает
прикладной программе, когда пользователь нажимает кнопку мыши,
когда ее курсор находится на этой клавише.
Для создания клавиши, рисуемой владельцем, используется
тип BS_OWNERDRAW, как показано в следующем примере:
hMyOwnButton = CreateWindow("Button", NULL,
BS_OWNERDRAW | WS_CHILD | WS_VISIBLE,
20, 40, 30, 12, hWnd, ID_MYBUTTON,
hInstance, NULL);
Когда возникает необходимость нарисовать клавишу, Windows
посылает сообщение WM_DRAWITEM окну, которому принадлежит
данный блок управления. Параметр lParam сообщения WM_DRAWITEM
содержит указатель на структуру данных типа DRAWITEMSTRUCT. Эта
структура кроме всего прочего содержит идентификатор блока
управления, значение, определяющее тип требуемой операции
рисования, значение, определяющее состояние клавиши,
прямоугольник, являющийся границей клавиши, и дескриптор
контекста устройства для данной клавиши.
В ответ на получение сообщения WM_DRAWITEM ваша программа
должна выполнить следующие действия:
1. Определить тип требуемой операции рисования. Для этого
проверьте содержимое поля itemAction структуры данных
DRAWITEMSTRUCT.
2. Нарисуйте клавишу соответствующим образом, используя
прямоугольник, ограничивающий клавишу и контекст
устройства, полученные из структуры DRAWITEMSTRUCT.
3. Восстановите объекты GDI, выбранные в контексте
устройства.
Например, когда клавиша теряет захват ввода, Windows
посылает в поле itemAction структуры данных DRAWITEMSTRUCT
значение ODA_FOCUS, но не устанавливает бит ODS_FOCUS в поле
itemState. Затем ваша программа должна нарисовать клавишу таким
образом, чтобы показать, что она потеряла захват ввода.
Групповые блоки.
Групповой блок - это прямоугольник, заключающий две или
.
Windows 3.0/pg/2#3 = 18 =
более зависимых клавиш или других блоков управления. Вы можете
послать групповому блоку сообщение WM_SETTEXT, чтобы поместить
в правый верхний угол заголовок. Групповые блоки не отвечают на
ввод от пользователя, т.е. они не посылают уведомляющих
сообщений.
8.4.2 Использование статических блоков управления.
Статический блок управления - это небольшое окно,
содержащее текст или изображение. Статический блок управления
обычно используется для пометки некоторого другого блока
управления или для создания панелей и линий, которые отделяют
одну группу блоков управления от другой.
Наиболее часто используемый статический блок управления -
SS_LEFT. Это выравненная влево строка текста. Текст
записывается, начиная с левого конца блока управления,
индицируя столько символов, сколько входит в блок управления и
обрезая остальное. Для текста блок управления использует
системные шрифты так, что можно вычислить размеры блока
управления, получив характеристики этого шрифта (более подробно
см. главу 18 "Шрифты").
Подобно групповым панелям статические блоки управления не
отвечают на ввод от пользователя; т.е. при выборке они не
генерируют уведомляющих сообщений. Однако имеется возможность в
любой момент времени изменить внешний вид и расположение
статических блоков управления. Например, можно изменить текст,
связанный со статическим блоком управления, используя функцию
SetWindowText или сообщение WM_SETTEXT.
8.4.3 Использование панелей перечней.
Панель перечня - это блок управления для перечня
символьных строк, таких как имена файлов. Обычно панель перечня
используется для индицирования перечня элементов, из которых
пользователь может выбрать одно или несколько. Имеется
несколько типов пенелей перечня. Наиболее употребительными
типами являются:
Тип Описание
---------------------------------------------------------------
LBS_BORDER Панель перечня с окантовкой вокруг нее.
LBS_NOTIFY Панель перечня посылает уведомляющие сообщения
родительскому окну при выборе элемента
пользователем.
LBS_SORT Панель перечня с отсортированными в алфавитном
порядке элементами.
WS_SCROLL Панель перечня имеет вертикальную строку про-
крутки.
---------------------------------------------------------------
.
Windows 3.0/pg/2#3 = 19 =
Эти типы включены в панель перечня типа LBS_STANDART. В
следующем примере создается стандартная панель перечня:
HWND hListBox;
#define IDC_LISTBOX 203
.
.
.
hListBox = CreateWindow("Listbox", NULL,
LBS_STANDART | WS_CHILD | WS_VISIBLE,
20, 40, 120, 56, hWnd, IDC_LISTBOX,
hInstance, NULL);
Добавление строки к панели перечня.
Можно добавить строку к панели перечня, используя
сообщение LB_ADDSTRING. Это сообщение копирует данную строку в
панель перечня, которая индицирует ее в составе перечня. Если
панель перечня имеет тип LBS_SORT, строка сортируется в
алфавитном порядке, иначе она просто добавляется в конец
списка. В приведенном ниже примере показано, как добавить
строку:
int nIndex;
.
.
.
nIndex=SendMessage(hListBox,
LB_ADDSTRING, NULL,
(LONG)(LPSTR) "Horseradish");
Это сообщение возвращает целое, представляющее индекс
строки в перечне. Можно использовать этот индекс в последующих
сообщениях панелей перечня для идентификации строки, но только
до тех пор, пока пользователь не добавит, удалит или вставит
другую строку, так как эти действия могут изменить индекс
строки.
Удаление строки из панели перечня.
Можно удалить строку из панели перечня, задав индекс с
сообщением LB_DELETESTRING, как это сделано в следующем
примере:
SendMessage(hListBox, LB_DELETESTRING, nIndex,
(LPSTR)NULL);
Вы можете добавить строку в панель перечня, послав
сообщение LB_INSERTSTRING. В отличие от сообщения LP_ADDSTRING,
LB_INSERTSTRING позволяет вам определить, куда необходимо
вставить строку в панели перечня. При получении сообщения
.
Windows 3.0/pg/2#3 = 20 =
сообщение LB_INSERTSTRING панель перечня не производит
сортировки элементов, даже если она имеет тип LBS_SORT.
Добавление к панели перечня имен файлов.
Как уже было сказано раньше, чаще всего панели перечня
используются для вывода списка имен файлов, директорий и/или
идентификаторов дисководов. Сообщение LB_DIR сообщает панели
перечня, что она должна заполнить себя такой информацией.
Параметр wParam этого сообщения содержит атрибуты файлов DOS, а
lParam содержит указатель на строку, содержащую спецификацию
файла.
Например, чтобы заполнить панель перечня именами всех
файлов текущей директории, имеющих расширение .TXT, и плюс
списком директорий и дисководов, вы должны послать сообщение
LB_DIR, как показано в следующем примере:
#define FILE_LIST 4010;
.
.
.
int nFiles;
.
.
.
nFiles = SendMessage(hListBox, LB_DIR, FILE_LIST,
(LPSTR)"*.TXT");
Возвращаемое значение после посылки сообщения LB_DIR
определяет число элементов, которые содержатся в панели
перечня.
Примечание: Если панель перечня принадлежит панели
диалога, то для выполнения той же задачи вы можете вызвать
функцию DlgDirList.
.
Windows 3.0/pg/2#3 = 21 =
Панель перечня отвечает на ввод от мыши и клавиатуры. Если
пользователь нажимает на кнопку мыши или нажимает клавишу
пробела, находясь на строке, происходит выборка строки из
панели перечня, на что указывает инверсия текста строки и
удаление выборки с предыдущего выбранного элемента.
Пользователь может также нажать символьную клавишу, и будет
выбран следующий элемент, который начинается с данного символа.
Если панель перечня имеет тип LBS_NOTIFY, она еще посылает
родительскому окну уведомляющее сообщение LBN_SELCHANGE. Если
пользователь дважды нажмет на кнопку мыши, находясь на строке,
и определен тип LBS_NOTIFY, панель перечня посылает
родительскому окну сообщения LBN_SELCHANGE и LBN_DBLCLK.
В любой момент можно определить индекс выбираемой строки,
используя сообщения LB_GETCURSEL и LB_GETTEXT. Сообщение
LB_GETCURSEL возвращает индекс выборки в панели перечня, а
сообщение LB_GETTEXT делает выборку из панели перечня, копируя
ее в заданный буфер.
.
Windows 3.0/pg/2#3 = 22 =
В таблице 8.1 приводится интерфейс клавиатуры и мыши для
стандартной панели перечня.
Таблица 8. Интерфейс пользователя со стандартной панелью
перечня.
---------------------------------------------------------------
Действие Результат
---------------------------------------------------------------
Интерфейс при использовании мыши
---------------------------------------------------------------
Единичное нажатие Выбирает элемент, и удаляет выборку с пре-
кнопки мыши дыдущего выбранного элемента (если такой
есть).
Двойное нажатие Аналогично единичному нажатию.
кнопки мыши
---------------------------------------------------------------
Интерфейс при использовании клавиатуры
---------------------------------------------------------------
Пробел Выбирает элемент.
Клавиша стрелка Выбирает следующий элемент в списке и
вправо или вниз удаляет выборку с предыдущего выбранного
элемента (если такой есть).
Клавиша стрелка Выбирает предшествующий элемент в списке
вверх или влево и удаляет выборку с предыдущего выбранного
элемента (если такой есть).
Клавиша PgUp Прокручивает текущий выбранный элемент
вниз панели перечня, выбирает первый
видимый элемент в панели перечня и снимает
выборку с предыдущего выбранного элемента
(если такой есть).
Клавиша PgDn Прокручивает текущий выбранный элемент
вверх панели перечня, выбирает последний
видимый элемент в панели перечня и снимает
выборку с предыдущего выбранного элемента
(если такой есть).
Клавиша HOME Прокручивает первый элемент панели перечня
вверх панели, выбирает первый видимый
элемент в панели перечня и снимает выборку
с предыдущего выбранного элемента (если
такой есть).
Клавиша END Прокручивает последний элемент панели пе-
речня вниз панели, выбирает последний
видимый элемент в панели перечня и снимает
выборку с предыдущего выбранного элемента
(если такой есть).
---------------------------------------------------------------
.
Windows 3.0/pg/2#3 = 23 =
Использование панелей перечня с множественной выборкой.
По умолчанию, панель перечня позволяет пользователю
выбирать одновременно только один элемент. Чтобы пользователь
мог выбрать одновременно несколько элементов, создайте панель
перечня с одним из следующих типов:
Тип Описание
---------------------------------------------------------------
LBS_MULTIPLESEL Панель перечня с типом LBS_MULTIPLESET
полностью аналогична стандартной панели
перечня, за исключением того, что
пользователь может выбирать больше, чем
один элемент.
LBS_EXTENDEDSEL Панель перечня с типом LBS_EXTENDEDSEL
предоставляет удобные средства для выбора
нескольких последовательных элементов, а
также для выбора отдельных элементов.
---------------------------------------------------------------
В оставшейся части данного раздела эти типы панелей с
множественной выборкой описаны более подробно.
Панели перечня с типом LBS_MULTIPLESEL.
Панель перечня, созданная с типом LBS_MULTIPLESEL,
полностью аналогична стандартной панели перечня, за исключением
того, что пользователь может выбирать в панели перечня больше,
чем один элемент. Нажатие мышкой или клавишей пробела в панели
перечня переключает состояние выборки элемента. Если
пользователь нажимает символьную клавишу, когда панель перечня
захватила ввод, то курсор панели перечня перемещается на
следующий элемент, который начинается с этого символа. Этот
элемент не будет выбран до тех пор, пока пользователь не нажмет
клавишу пробел.
.
Windows 3.0/pg/2#3 = 24 =
Таблица 8.2 Интерфейс пользователя с панелью перечня, имеющей
тип LBS_MULTIPLESEL.
---------------------------------------------------------------
Действие Результат
---------------------------------------------------------------
Интерфейс при использовании мыши
---------------------------------------------------------------
Единичное нажатие Переключает состояние выборки, но не
сникнопки мыши мает состояние выборки с предыдущего
выбранного элемента (если такой есть).
Двойное нажатие Аналогично единичному нажатию.
кнопки мыши
---------------------------------------------------------------
Интерфейс при использовании клавиатуры
---------------------------------------------------------------
Пробел Переключает состояние выборки, но не сни-
мает состояние выборки с предыдущего
выбранного элемента (если такой есть).
Клавиша стрелка Перемещает курсор панели перечня на
вправо или вниз следующий элемент.
Клавиша стрелка Перемещает курсор панели перечня на
вверх или влево предшествующий элемент.
Клавиша PgUp Прокручивает текущий выбранный элемент
вниз панели перечня и перемещает курсор на
первый видимый элемент в панели перечня.
Клавиша PgDn Прокручивает текущий выбранный элемент
вверх панели перечня и перемещает курсор
на последний видимый элемент в панели
перечня.
Клавиша HOME Прокручивает первый элемент панели перечня
вверх панели и перемещает курсор на первый
видимый элемент в панели перечня.
Клавиша END Прокручивает последний элемент панели пе-
речня вниз панели и перемещает курсор на
последний видимый элемент в панели
перечня.
---------------------------------------------------------------
Панели перечня с типом LBS_EXTENDEDSEL.
Панели перечня, созданные с типом LBS_EXTENDEDSEL,
предоставляют удобные средства для выбора нескольких
последовательных элементов в панели перечня, а также для выбора
отдельных элементов. В таблице 8.3 приведен интерфейс при
использовании мыши и клавиатуры для панелей перечня с типом
LBS_EXTENDEDSEL.
.
Windows 3.0/pg/2#3 = 25 =
Таблица 8.3 Интерфейс пользователя с панелью перечня, имеющей
тип LBS_EXTENDEDSEL.
---------------------------------------------------------------
Действие Результат Результат
(выкл. режим добавления) (вкл. режим добавления)
---------------------------------------------------------------
Интерфейс при использовании мыши
---------------------------------------------------------------
Единичное Выбирает элемент, уда- Как и при выключенном
нажатие ляет выборку с других режиме добавления, плюс
клавиши мышы элементов и устанав- выключает режим добавл-
ливает на него "якорь" ления.
выборки.
SHIFT + Выбирает элементы, на- Как и при выключенном
единичное ходящиеся между якорем режиме добавления, плюс
нажатие выборки и текущим эле- выключает режим добавл-
клавиши мышы ментом, и удаляет вы- ления.
борку с элементов, ко-
торые не попадают в
этот диапазон.
Двойное Аналогично единичному Как и при выключенном
нажатие нажатию. режиме добавления, плюс
SHIFT + Аналогично единичному выключает режим добавл-
Двойное нажатию + SHIFT. ления.
нажатие
CONTROL + Перемещает курсор вы- Как и при выключенном
единичное борки и переключает режиме добавления, плюс
нажатие состояние выборки для выключает режим добавл-
клавиши мышы выбираемых элементов, ления.
но не удаляет выборку
остальных элементов.
CONTROL + Не удаляет выборку с Как и при выключенном
SHIFT + других элементов (за режиме добавления, плюс
единичное исключением тех, кото- выключает режим добавл-
нажатие рые попадают в диапа- ления.
клавиши мышы зон между текущей и
последней установкой
якоря) и переключает
состояние всех элемен-
тов (в тоже состояние,
что и элемент, на кото-
ром установлен якорь)
от якоря до текущего
элемента. Не перемещаеь
якорь.
Тащить Помещает якорь выборки Как и при выключенном
.
Windows 3.0/pg/2#3 = 26 =
в точку, где пользова- режиме добавления, плюс
тель нажал на кнопку выключает режим добавл-
мыши, выбирает элементы ления.
от якоря до точки, в
которой пользователь
отпустил кнопку, и уда-
ляет выборку со всех
остальных элементов.
SHIFT + Выбирает элементы от Как и при выключенном
тащить якоря выборки до эле- режиме добавления, плюс
мента, на котором поль- выключает режим добавл-
зователь отпустил кноп- ления.
ку, и удаляет выборку
со всех остальных
элементов. Не переме-
щает якорь выборки.
CONTROL + Помещает якорь выборки Как и при выключенном
тащить в точку, где пользова- режиме добавления, плюс
тель нажал кнопку мыши. выключает режим добавл-
Не удаляет выборку с ления.
остальных элементов, но
переключает состояние
всех элементов в состо-
яние, соответствующее
элементу, на котором
находится якорь, от
якоря, до точки где
пользователь отпустил
кнопку мыши.
CONTROL + Не удаляет выборку с Как и при выключенном
SHIFT + остальных элементов режиме добавления, плюс
тащить (за исключением тех, выключает режим добавл-
которые входят в диапа- ления.
зон выборки, определяе-
мый последним положе-
нием якоря), но пере-
ключает состояние всех
элементов (в состояние,
соответсвующее элементу
на котором установлен
якорь) от якоря до
элемента, на котором
пользователь отпустил
кнопку мыши. Не пере-
мещает якорь.
---------------------------------------------------------------
Интерфейс при использовании клавиатуры (а)
---------------------------------------------------------------
SHIFT + F8 Включает режим добав- Выключает режим добав-
ления. В этом режиме ления.
курсор панели перечня
мигает.
.
Windows 3.0/pg/2#3 = 27 =
Пробел Выбирает элемент, уда- Переключает состояние
ляет выборку с других элемента и устанавли-
элементов и устанав- вает якорь, но не уда-
ливает на него "якорь" ляет выборку с других
выборки. элементов.
SHIFT + Удаляет выборку с пре- Не удаляет выборку с
Пробел дыдущих выбранных эле- остальных элементов
ментов и переключает (за исключением тех,
состояние элементов (в которые входят в диапа-
соответствии с сосоя- зон выборки, определяе-
нием элемента, на кото- мый последним положе-
ром установлен якорь) нием якоря), но пере-
от якоря до текущей по- ключает состояние всех
зиции. элементов (в состояние,
соответсвующее элементу
на котором установлен
якорь) от якоря до
текущего элемента. Не
перемещает якорь.
Клавиши нап- Перемещают курсор па- Перемещают курсор па-
равления (б) нели перечня в соот- нели перечня в соот-
ветствии с клавишей, ветствии с клавишей, но
выбирают элемент под не выбирают элемент
курсором, перемещают удаляют выборку со всех
на него якорь и уда- остальных элементов
ляют выборку со всех или перемещают на него
остальных элементов. якорь
SHIFT + Удаляет выборку со всех Не удаляет выборку с
Клавиши нап- остальных элементов, остальных элементов
равления перемешает курсор в (за исключением тех,
соответсвии с клавишей которые входят в диапа-
и переключает зон выборки, определяе-
состояние элементов (в мый последним положе-
соответствии с сосоя- нием якоря), перемещает
нием элемента, на кото- курсор в соответствии
ром установлен якорь) с клавишей и пере-
от якоря до текущей по- ключает состояние всех
зиции. Не перемещает элементов (в состояние,
якорь. соответсвующее элементу,
на котором установлен
якорь) от якоря до
текущего элемента. Не
перемещает якорь.
---------------------------------------------------------------
а) За исключением SHIFT + F8 все клавиши и комбинации клавиш
могут использоваться в комбинации с CONTROL. Например, CONTROL
.
Windows 3.0/pg/2#3 = 28 =
+ SHIFT + SPACEBAR имеет то же значение, что и SHIFT +
SPACEBAR.
б) Клавиши направления включают клавиши со стрелками и клавиши
HOME, END, PAGE UP и PAGE DOWN. Описание того, как каждая
клавиша управляет перемещением курсора, вы найдете в таблице
8.2 "Интерфейс пользователя для панелей перечня, имеющих тип
LBS_MULTIPLESEL".
Использование панелей перечня, состоящих из нескольких
столбцов.
Обычно панели перечня выводят элементы в один столбец.
Если вы знаете, что панель перечня будет содержать много
элементов, то вы можете создать панель перечня с типом
LBS_MULTICOLOMN. Этот тип определяет панель перечня, в которой
элементы отображаются в несколько столбцов. Элементы такой
панели перечня "змеятся" с нижней части одной колонки в другую.
По этой причине для таких панелей перечня не предусмотрена
вертикальная прокрутка. Однако, если панель перечня может
содержать больше элементов, чем могут быть отображены
одновременно, вы можете задать тип WM_HSCROLL для того, чтобы
пользователь мог выполнять горизонтальную прокрутку. Ниже
приведен пример создания панели перечня, которая содержит
несколько столбцов и занимает всю область пользователя
родительского окна:
#define IDC_MULTILISTBOX
RECT Rect;
HWND hMultiListBox;
.
.
.
GetClientRect(hWnd, (LPRECT) &Rect);
hMultiListBox = CreateWindow("Listbox",
NULL,
WS_CHILD | WS_VISIBLE | LBS_SORT |
LBS_MULTICOLOMN | WS_HSCROLL | LBS_NOTIFY,
Rect.left,
Rect.top,
Rect.right,
Rect.botton,
hWnd,
IDC_MULTILISTBOX,
hInst,
NULL);
В этом примере функция GetClientRect используется для
получения координат области пользователя родительского окна,
которые затем передаются функции CreateWindow для установки
местоположения и размеров панели перечня.
.
Windows 3.0/pg/2#3 = 29 =
Примером панели перечня, содержащей несколько столбцов,
может служить окно директории, которое отображает File Manager.
Чтобы установить ширину колонки панели перечня, которая
содержит несколько колонок, можно послать ей сообщение
LB_SETCOLOMNWIGTH.
Использование рисуемых панелей перечня.
Как и клавиши, панели перечня можно также создать как
рисуемый блок управления. Однако в случае панелей перечня ваша
программа отвечает только за рисование элементов панелей
перечня.
Для создания рисуемых панелей перечня можно использовать
один из следующих типов: LBS_OWNERDRAWFIXED или
LBS_OWNERDRAWVARIABLE. Тип LBS_OWNERDRAWFIXED определяет панель
перечня, в которой все рисуемые элементы имеют одинаковую
высоту.
Для добавления элемента к панели перечня пошлите сообщение
LB_ADDSTRING или LB_INSERTSTRING. Параметр lParam может
содержать любое 32-битовое значение, которое вы хотите связать
с элементом. Если lParam содержит указатель на строку, то тип
панели перечня LBS_HASSSTRING позволяет обрабатывать память и
указатели на строки. Это позволяет прикладной программе
использовать сообщение LB_GETTEXT для получения текста
определенного элемента. Аналогично, если вы создаете панель
перечня с типами LBS_SORT или LBS_HASSTRING, то Windows
автоматически сортирует элементы панели перечня.
Если вы создаете панель перечня с типом LBS_SORT, но без
LBS_HASSTRING, Windows не может определить порядок элементов
внутри панели перечня. В этом случае при добавлении элемента в
панель перечня (с помощью сообщения LB_ADDSTRING) Windows
посылает одно или несколько сообщений WM_COMPAREITEM владельцу
панели перечня. В этих сообщениях параметр lParam указывает на
структуру данных COMPAREITEMSTRUCT, которая содержит
информацию, идентифицирующую два элемента панели перечня. При
возврате управления после обработки этого сообщения прикладная
программа возвращает значение, определяющее какой (если такой
есть) элемент должен находиться выше другого. Windows посылает
эти сообщения до тех пор, пока не отсортирует все элементы
панели перечня.
При добавлении или вставке элемента в панель перечня
Windows определяет размер элемента, посылая сообщение
WM_MEASHUREITEM владельцу панели перечня. Windows требуется
информация, которая позволила бы осуществить взаимодействие с
пользователем. Если вы создали панель перечня с типом
LBS_OWNERDRAWFIXED, то Windows посылает это сообщение только
один раз, поскольку все элементы в панели перечня будут иметь
одинаковую высоту. Для панели перечня с типом
.
Windows 3.0/pg/2#3 = 30 =
LBS_OWNERDRAWVARIABLE Windows посылает сообщение
WM_MEASHUREITEM для каждого добавляемого элемента.
Параметр lParam сообщения WM_MEASHUREITEM содержит
указатель на структуру MEASHUREITEMSTRUCT. Кроме идентификатора
и типа блока управления эта структура содержит номер элемента
панели перечня, инофрмация о котором необходима (для панелей
перечня, имеющих тип LBS_OWNERDRAWVARIABLE), и необязательное
32-битовое значение, связанное с данным элементом. При
получении сообщения WM_MEASHUREITEM программа должна занести в
поле itemHeight структуры MEASHUREITEMSTRUCT высоту элемента.
Высота вычисляется в вертикальных единицах панели диалога.
Вертикальная единица панели диалога равна 1/8 базовой единицы
панели диалога, которая вычисляется из высоты системного
шрифта. Для определения высоты базовой единицы панели диалога в
пикселях можно воспользоваться функцией GetDialogBaseUnit.
Когда Windows выводит панель перечня, или когда необходимо
изменить вид элемента в панели перечня, Windows посылает окну
сообщение WM_DRAWITEM. Параметр lParam сообщения WM_DRAWITEM
содержит указатель на структуру данных DRAWITEMSTRUCT. Эта
структура содержит информацию, идентифицирующую элемент панели
перечня и тип требуемой операции. Как и в случае с рисуемой
клавишей, ваша программа использует эту инофрмацию для
рисования элемента.
Для удаления элемента из рисуемой панели перечня пошлите
панели перечня сообщение LB_DELETESTRING. Windows в свою
очередь пошлет сообщение WM_DELETEITEM владельцу панели
перечня. (Windows также посылает это сообщение при разрушении
панели перечня.) Параметр lParam этого сообщения содержит
указатель на структуру данных DELETEITEMSTRUCT. Эта структура
определяет панель перечня и элемент, который должен быть
удален, а также 32-битовое число, связанное с этим элементом.
Ваша прикладная программа может использовать эту инофрмацию для
освобождения памяти, занятой инофрмацией об этом элементе.
8.4.4 Комбинированные блоки управления.
Комбинированный блок управления состоит из панели перечня
и статического или редактируемого блока. В зависимости от типа
панели перечня, она может отображаться все время или быть
скрытой до тех пор, пока пользователь ее не отобразит.
Интерфейс с панелью перечня и редактируемым блоком управления
аналогичны стандартным, за исключением случаев, которые
описаны.
Тип CBS_SIMPLE создает комбинированный блок с
редактируемым блоком и панелью перечня, которая отображается
под редактируемым блоком. Когда комбинированный блок захватил
ввод, пользователь может набирать в редактируемом блоке
управления текст. Если элемент в панели перечня совпадает с
тем, который пользователь набрал, то соответствующий элемент
.
Windows 3.0/pg/2#3 = 31 =
прокручивается в начало панели перечня. Пользователь может
затем выбрать элементы из панели перечня, используя мышь или
клавиатуру (клавиши стрелка вверх и стрелка вниз).
Тип CBS_DROPDOWN аналогичен типу CBS_SIMPLE, за
исключением того, что панель перечня отображается только в том
случае, если пользователь выбирает элемент, следующий за
редактируемым блоком управления, или если пользователь нажимает
клавиши ALT + DOWN ARROW или ALT + UP ARROW. Даже если панель
перечня скрыта, пользователь может выбирать элементы в панели
перечня с помощью клавиш стрелка вверх и стрелка вниз.
Комбинированный блок управления с типом CBS_DROPDOWNLIST
выглядит аналогично блоку с типом CBS_DROPDOWN, за исключением
того, что в нем редактируемый блок управления заменен на
статический. Вместо того, чтобы набирать элемент в
редактируемом блоке, пользователь может выбирать элементы в
панели перечня, вводя только его первый символ. Конечно
пользователь может кроме этого использовать для выбора
элементов мышь и клавиши стрелка вверх и стрелка вниз.
Вы можете добавлять и удалять элементы в панели перечня
комбинированного блока тем же путем, как и из обычной панели
перечня, однако вы должны использовать сообщения CB_ADDSTRING,
CB_INSERTSTRING, CB_DIR и CB_DELETESTRING. Windows
предоставляет кроме этого дополнительные сообщения для
получения содержимого редактируемого блока, сравнения с
элементами панели перечня и для работы с содержимым
редактируемого блока управления.
Со многих точек зрения комбинированный блок аналогичен
панели перечня в том, как пользователь с ним взаимодействует.
Все уведомляющие коды панели перечня используются для
комбинированного блока. Кроме них Windows посылает уведомляющие
сообщения для указания следующих событий:
- Выпадает панель перечня из комбинированного блока
(CBN_DROPDOWN).
- Пользователь изменил текст в редактируемом блоке, и
Windows модифицирует изображение (CBN_EDITCHANGE).
- Пользователь изменил текст в редактируемом блоке, но
Windows не модифицировала изображение (CBN_EDITUPDATE).
- Комбинированный блок потерял захват ввода
(CBN_KILLFOCUS). В случае, если комбинированный блок
управоения имеет тип CBS_DROPDOWN или CBS_DROPDOWNLIST,
это приводит к тому, что Windows удаляет с экрана панель
перечня.
- Комбинированный блок осуществляет захват ввода
(CBN_SETFOCUS).
.
Windows 3.0/pg/2#3 = 32 =
Как и панель перечня, комбинированный блок может
создаваться с типом, определяющим переменную или фиксированную
высоту рисуемых элементов. Однако в случае комбинированных
блоков управления программа отвечает за вывод элементов в
панели перечня и в редактируемом или статическом блоке.
Например, если пользователь выбирает элемент в панели перечня,
программа для панели перечня получает сообщение WM_DRAWITEM,
определяющее, что элемент должен быть выведен как выбранный, и
другое сообщение (WM_DRAWITEM) для редактируемого блока.
Вы можете также указать для комбинированного блока тип
CBS_SORT. Windows сортирует элементы комбинированного блока тем
же путем, что и рисуемые панели перечня.
Для комбинированных блоков не существует типов,
предусматривающих несколько столбцов для панели перечня.
8.4.5 Редактируемые блоки.
Редактируемый блок управления - это прямоугольное дочернее
окно, в котором пользователь может вводить и редактировать
текст. Редактируемые блоки имеют широкие возможности, такие как
редактирование нескольких строк и прокрутка. Вы указываете
необходимые вам функции в типе блока управления.
Тип редактируемого блока управления определяет, как он
будет отображаться и функционировать. Например, тип
ES_MULTILINE определяет редактируемый блок, в который можно
вводить больше одной строки текста. Типы ES_AUTOHSCROLL и
ES_AUTOVSCROLL определяют, что блок управления будет
производить прокрутку, если пользователь введет текст, который
не будет помещаться в области пользователя редактируемого блока
управления. Если эти типы не указаны и пользователь вводит
больше, чем может поместиться в одной строке, то ввод будет
продолжен на следующей строке, если блок управления содержит
несколько строк. Вы можете кроме этого использовать типы
WS_HSCROLL и (в случае многострочного блока управления)
WS_VSCROLL, которые также позволяют пользователю прокручивать
текст в блоке управления.
Ваша прикладная программа может использовать редактируемый
блок управления для ввода паролей или другого секретного текста
таким образом, что он не будет отображаться на экране. Тип
ES_PASSWORD определяет редактируемый блок управления, который
не отображает текст при вводе его пользователем. Вместо этого в
блоке управления отображается для каждого набранного символа
необязательный символ (по умолчанию звездочка "*"). Вы можете
изменить этот символ с помощью сообщения EM_SETPASSWORDCHAR.
С помощью сообщения EM_SETTABSTOPS вы можете установить
позиции табуляции в многострочном редактируемом блоке
управлления. Это сообщение определяет число пробелов между
.
Windows 3.0/pg/2#3 = 33 =
следующими позициями табуляции.
Редактируемый блок управления посылает уведомляющее
сообщение своему родительскому окну. Например, редактируемый
блок управления посылает сообщение EN_CHANGE, когда
пользователь изменяет текст. Редактируемый блок управления
может также получать сообщения, такие как EM_GETLINE и
EM_LINELENGTH. В этом случае он выполняет указанные действия.
Очень удобная функция редактируемого блока управления -
это функция отмена изменений, произведенных в блоке
управлления. Для определения того, может ли блок управления
выполнить эту функцию, вы можете послать сообщение EM_CANUNDO.
Если Windows вернет ненулевое значение, то значит можно
отменить последнее изменение. В этом случае для выполнения этой
функции вы можете послать сообщение EM_UNDO редактируемому
блоку управления.
В таблице 8.4 описан пользовательский интерфейс с
редактируемым блоком управления.
Таблица 8.4 Интерфейс пользователя с редактируемым блоком
управления.
---------------------------------------------------------------
Действие Результат
---------------------------------------------------------------
Интерфейс при использовании мыши
---------------------------------------------------------------
Единичное нажатие Позиционирует точку ввода и помещает якорь
кнопки мышы выборки.
Двойное нажатие Выбирает слово.
кнопки мышы
SHIFT + Позиционирует точку ввода и расширяет вы-
единичное нажатие борку от "якоря" выборки до точки ввода.
кнопки мышы
Тащить Помещает "якорь" выборки, перемещает точку
ввода и расширяет выборку от "якоря" до
точки ввода.
---------------------------------------------------------------
Интерфейс при использовании клавиатуры
---------------------------------------------------------------
Клавиши направления Убирают выборку с любого текста и переме-
щают точку ввода в соответствующем направ-
лении.
SHIFT + Перемещает "якорь" выборки (если он еще не
клавиши направления установлен), перемещает точку ввода и вы-
бирает текст между точкой ввода и "якорем"
выборки.
.
Windows 3.0/pg/2#3 = 34 =
CONTROL + стрелка Перемещает точку ввода на начало слова в
влево, CONTROL + указанном направлении.
стрелка вправо
SHIFT + CONTROL + Устанавливает "якорь" выборки (если он еще
стрелка влево, не установлен), перемещает точку ввода на
SHIFT + CONTROL + начало слова в указанном направлении и
стрелка вправо выбирает текст между "якорем" и точкой
ввода.
HOME Удаляет выборку и перемещает точку ввода
в начало строки.
SHIFT + HOME Устанавливает "якорь" выборки (если он еще
не установлен), перемещает точку ввода в
начало строки и выбирает текст между
"якорем" и точкой ввода.
CONTROL + HOME Помещает точку ввода перед первым симво-
лом в редактируемом блоке управления.
SHIFT + CONTROL + Помещает "якорь" выборки (если он еще не
HOME установлен), помещает точку ввода перед
первым символом в редактируемом блоке
управления и выбирает текст между "яко-
рем" и точкой ввода.
END Удаляет выборку и перемещает точку ввода
в конец строки.
SHIFT + END Устанавливает "якорь" выборки (если он еще
не установлен), перемещает точку ввода в
конец строки и выбирает текст между
"якорем" и точкой ввода.
CONTROL + END Помещает точку ввода после последнего
символа в редактируемом блоке управления.
SHIFT + CONTROL + Устанавливает "якорь" выборки (если он еще
END не установлен), помещает точку ввода после
последнего символа в редактируемом блоке
управления, и выбирает текст между "якорем"
и точкой ввода.
DELETE Если текст выбран, то удаляет этот текст.
Если нет, то удаляет символ, справа от
точки ввода.
SHIFT + DELETE Если текст выбран, вырезает его и помещает
в системный буфер. Иначе удаляет символ пе-
ред точкой ввода.
.
Windows 3.0/pg/2#3 = 35 =
SHIFT + INSERT Вставляет текст из системного буфера, на-
чиная с точки ввода.
CONTROL + INSERT Копирует, но не удаляет, выбранный текст
в системный буфер.
PAGE UP В многострочном редактируемом блоке
управления прокручивает текст вверх на
строку меньше, чем высота блока управле-
ния.
CONTROL + PAGE UP В многострочном редактируемом блоке
управления прокручивает текст влево на
ширину блока управления минус один
символ.
PAGE DOWN В многострочном редактируемом блоке
управления прокручивает текст вниз на
строку меньше, чем высота блока управле-
ния.
CONTROL + PAGE DOWN В многострочном редактируемом блоке
управления прокручивает текст вправо на
ширину блока управления минус один
символ.
CONTROL + ENTER В многострочном редактируемом блоке
управления в панели диалога завершает
строку и перемещает курсор в начало сле-
дующей строки.
CONTROL + TAB В многострочном редактируемом блоке
управления в панели диалога вставляет
символ табуляции.
---------------------------------------------------------------
В конце данной главы описан пример EditCntl, который
использует многострочный редактируемый блок управления для
выполнения базовых функций по вводу и редактированию текста.
8.4.6 Строки прокрутки.
Строки прокрутки - это предопределенные блоки управления,
которые могут располагаться в любом месте окна. Они позволяют
пользователю выбирать значение в непрерывном диапазоне. Строки
прокрутки посылают уведомляющие сообщения родительскому окну в
тех случаях, когда пользователь нажимает кнопку мыши, когда
курсор находится на блоке управления или перемещает бегунок с
помощью клавиатуры. Это позволяет прикладной программе
обрабатывать сообщения для того, чтобы определить выбранное
пользователем значение и чтобы в соответствии с ним переместить
бегунок.
.
Windows 3.0/pg/2#3 = 36 =
Для создания дочернего окна строки прогрутки вы можете
использовать типы SBS_HORZ или SBS_VERT. Строка прокрутки может
иметь любой необходимый размер. Если вы хотите, чтобы ширина
(для вертикальной строки прокрутки) или высота (для
горизонтальной строки прокрутки) соответствовала размерам окна,
вы можете использовать соответствующие размерности окна, как
показано в следующем примере:
hScrollBar = CreateWindow("Scrollbar", NULL
WS_CHILD | WS_VISIBLE | SBS_VERT,
20,20,
GetSystemMetrics(SM_CXVSCROLL),50,
hWnd, IDSCROLLBAR, hInst, NULL);
Функция GetSystemMetrics возвращает значение SM_CXVSCROLL,
которое представляет собой ширину стандартной строки прокрутки
окна.
Строка прокрутки не имеет специальных уведомляющих
сообщений. Вместо этого они посылают сообщения WM_HSCROLL и
WM_VSCROLL как строки поркрутки окна. Параметр wParam этих
сообщений содержит значение, определяющее тип выполняемой
прокрутки. Прикладная программа использует эту инофрмацию для
определения местоположения бегунка и в своих внутренних целях.
Таблица 8.5 содержит список возможных значений параметра wParam
и действия пользователя, которые приводят к их генерации.
.
Windows 3.0/pg/2#3 = 37 =
Таблица 8.5 Пользовательский интерфейс со строкой прокрутки.
---------------------------------------------------------------
Значение пара- Мышь Клавиатура
метра wParam
---------------------------------------------------------------
SB_LINEUP Пользователь нажима- Пользователь нажал на
ет мышкой на стрелку клавишу стрелка влево
вверх или стрелку или стрелка вверх.
влево в строке прок-
рутки.
SB_LINEDOWN Пользователь нажима- Пользователь нажал на
ет мышкой на стрелку клавишу стрелка вправо
вниз или стрелку или стрелка вниз.
вправо в строке прок-
рутки.
SB_PAGEUP Пользователь нажал Пользователь нажал
мышкой выше или левее PAGE UP.
бегунка строки прок-
рутки.
SB_PAGEDOWN Пользователь нажал Пользователь нажал
мышкой ниже или PAGE DOWN.
правее бегунка строки
прокрутки.
SB_ENDSCROLL Пользователь нажал Нет.
мышкой в любом месте
строки прокрутки, за
исключением бегунка.
SB_THUMBTRACK Пользователь "тащит" Нет.
бегунок.
SB_THUMBPOSITION Пользователь отпус- Нет.
кает бегунок.
SB_TOP Нет. Пользователь нажимает
HOME.
SB_BOTTOM Нет. Пользователь нажимает
END.
---------------------------------------------------------------
Windows может позиционировать бегунок строки прокрутки,
связанной с панелью перечня или редактируемым блоком
управления, в соответствии с его содержимым. Однако, строка
прокрутки, являющаяся дочерним окном, представляет диапазон
значений, которые имеют смысл только для вашей программы.
Следовательно она отвечает за установку диапазона строки
прокрутки и за позиционирование бегунка после каждого
.
Windows 3.0/pg/2#3 = 38 =
перемещения его пользователем.
Функция SetScrollRange устанавливает диапазон значений,
представляемых строкой прокрутки. Например, в вашей программе
есть строка прокрутки, с помощью которой пользователь может
выбрать день месяца. В этом случае диапазон строки прокрутки
для Января может быть установлен следующим образом:
SetScrollRange(hScrollBar, SB_CTL, 1, 31, 1);
В данном примере константа SB_CTL сообщает Windows, что
строка прокрутки является отдельным блоком управления, не
связанным с окном. Третий и четвертый параметры определяют
диапазон, а пятый параметр (равный 1) заставляет Windows
перерисовать строку прокрутки для отображения нового диапазона.
Даже после того, как вы определили диапазон строки
прокрутки, Windows не может устанавливать бегунок в
соответствии с действиями пользователя, это остается на вашей
программе. Когда ваша программа получает от строки прокрутки
сообщения WM_HSCROLL или WM_VSCROLL, вы должны проверить
параметр wParam для определения того, насколько далеко
пользователь переместил бегунок. После этого вы вызываете
функцию SetScrollPos для позиционирования бегунка. Так же, если
пользователь может изменить положение бегунка, не используя
строку прокрутки (например, набирая текст в редактируемом блоке
управления), ваша программа должна переустановить позицию
бегунка в соответствии с новым значением.
8.5 Пример прикладной программы EditCntl
Эта прикладная программа иллюстрирует, как можно
использовать редактируемый блок управления в основном окне
прикладной программы для того, чтобы обеспечить ввод
многострочного текста и его редактирование. Прикладная
программа EditCntl заполняет область пользователя основного
окна многострочным редактируемым блоком управления и управляет
размерами области пользователя для уверенности в правильном ее
заполнении. Основное окно программы EditCntl приведено на
рисунке 8.1.
Рисунок 8.1 Окно прикладной программы EditCntl.
1. Вся область пользователя окна представляет собой один
блок управления.
Для создания прикладной программы скопируйте и
переименуйте исходные файлы ПП EditMenu, а затем выполните
следующие изменения:
1. Добавьте новую константу во включаемый файл.
2. Добавьте новые переменные.
.
Windows 3.0/pg/2#3 = 39 =
3. Добавьте функцию CreateWindow.
4. Модифицируйте фрагмент WM_COMMAND.
5. Добавьте фрагмент WM_SETFOCUS.
6. Добавьте фрагмент WM_SIZE.
7. Оттранслируйте и скомпонуйте программу.
Примечание: Вместо того, чтобы вводить тексты, приведенные
в следующих разделах, возможно вам будет удобнее просто
переписать исходные тексты из SDK.
8.5.1 Добавление константы во включаемый файл.
Необходимо добавить константу, которая будет
использоваться в качестве идентификатора редактируемого блока
управления во включаемый файл. Добавьте следующий оператор:
#define ID_EDIT 300
8.5.2 Добавление новых переменных.
Необходимо иметь глобальную переменную для хранения
дескриптора окна редактируемого блока управления. Добавьте
следующий оператор в начало исходного С-файла:
HWND hEditWnd; /* дескриптор редактируемого окна */
Кроме того, необходимо иметь локальную переменную в
функции WinMain для хранения координат прямоугольной области
пользователя. Эти координаты используются для определения
размера блока управления. Добавьте следующий оператор в начало
функции WinMain:
RECT Rect;
8.5.3 Добавление функции CreateWindow.
Необходимо создать редактируемый блок управления,
используя функцию CreateWindow; но перед этим нужно получить
размеры области пользователя, чтобы можно было установить
размеры блока управления. Добавьте следующие операторы к
функции WinMain сразу после создания основного окна:
GetClientRect(hWnd, (LPRECT) &Rect);
hEditWnd = CreateWindow("Edit",
NULL,
WS_CHILD | WS_VISIBLE |
ES_MULTILINE |
WS_VSCROLL | WS_HSCROLL |
ES_AUTOHSCROLL | ES_AUTOVSCROLL,
.
Windows 3.0/pg/2#3 = 40 =
0,
0,
(Rect.right-Rect.left),
(Rect.bottom-Rect.top),
hWnd,
ID_EDIT,
hInst,
NULL);
if (!hEditWnd) {
DestroyWindow(hWnd);
return (NULL);
}
Функция GetClientRect получает размеры области
пользователя основного окна и помещает эту информацию в
структуру Rect. Функция CreateWindow создает редактируемый блок
управления, используя ширину и высоту, вычисленную при помощи
этой структуры.
Функция CreateWindow создает редактируемое окно. Для
создания редактируемого блока управления необходимо
использовать встроенный класс блока управления "Edit" и
указать тип окна WS_CHILD. Встроенные блоки управления могут
быть использованы только как дочерние окна. Они не могут быть
использованы как основные или накладываемые окна. Поскольку
дочернее окно подразумевает наличие родительского окна, в
вызове функции указывается дескриптор основного окна hWnd.
Для этого блока управления также указывается ряд типов
редактируемых блоков управления. Подобно типу окон, тип
редактируемого блока управления определяет, как он будет
выглядеть и как он будет работать. Редактируемый блок
управления, описываемый в данном примере, является
многострочным, т.е. позволяющим вводить в окно более одной
строки текста. Кроме того, блок управления будет осуществлять
горизонтальную и вертикальную прокрутку, если пользователь
вводит больше текста, чем может поместиться в окне.
Верхний левый угол редактируемого блока управления
размещается в верхнем левом углу области пользователя
родительского окна (координаты дочернего окна всегда берутся
относительно области пользователя родительского окна).
Следующие два аргумента Rect.right-Rect.left и
Rect.bottom-Rect.top определяют высоту и ширину редактируемого
блока управления, давая уверенность в том, что этот блок
заполняет область пользователя при первой индикации окна.
Поскольку редактируемый блок управления посылает
уведомляющие сообщения своему родительскому окну, он должен
быть задан своим ID (идентификатром). Дочерние окна не могут
иметь меню, так что вместо него аргумент меню в функции
CreateWindow используется для указания ID блока управления. Для
.
Windows 3.0/pg/2#3 = 41 =
данного блока управления устанавливается ID, равный ID_EDIT.
Любое уведомляющее сообщение, посылаемое родительскому окну
редактируемым блоком управления, будет содержать этот ID.
Если редактируемый блок управления не может быть создан,
функция CreateWindow возвращает NULL. В этом случае прикладная
программа не может продолжать свою работу, и функция
DestroyWindow используется для разрушения основного окна перед
завершением программы.
8.5.4 Модификация фрагмента WM_COMMAND.
Дочерние блоки управления уведомляют родительское окно
посредством сообщения WM_COMMAND. Параметр wParam этого
сообщения содержит идентификатор блока управления, который
послал это сообщение.
Для распознавания сообщения о недостатке памяти для
редактируемого блока управления добавьте следующий код в
фрагмент WM_COMMAND:
case IDC_EDIT:
if(HIWORD (lParam) == EN_ERRSPACE) {
MessageBox(
GetFocus(),
"Не хватает памяти",
"Программа EditCntl",
MB_ICONHAND | MB_OK);
}
break;
8.5.5 Добавление фрагмента WM_SETFOCUS.
Для направления ввода в редактируемый блок управления при
активизации родительского окна добавьте следующие операторы в
функцию окна:
case WM_SETFOCUS:
SetFocus(hEditWnd);
break;
8.5.6 Добавление фрагмента WM_SIZE.
Необходимо добавить фрагмент WM_SIZE к функции окна.
Windows посылает сообщение WM_SIZE функции окна каждый раз,
когда изменяется ширина или высота окна. Поскольку изменение
размеров основного окна не изменяет автоматически размеров
редактируемого блока управления, то для их изменения необходим
фрагмент WM_SIZE.
Добавьте следующие операторы к функции окна:
case WM_SIZE:
.
Windows 3.0/pg/2#3 = 42 =
MoveWindow(hEditWnd, 0, 0, LOWORD(lParam),
HIWORD(lParam), TRUE);
break;
8.5.7 Трансляция и компоновка.
В файле make изменений не требуется. Оттранслируйте и
скомпонуйте программу EditCntl, затем запустите Windows и
прикладную программу. Теперь можно вставить текст, использовать
клавишу BackSpace для удаления текста и сделать выборку при
помощи мыши, а не клавиатуры. Поскольку при создании блока
управления специфицировано ES_MULTILINE, ES_AUTOVSCROLL и
ES_AUTOHSCROLL, блок управления может редактировать текст на
всем экране, а также осуществлять прокрутку.
Прикладная программа EditCntl иллюстрирует первый шаг,
требующийся для того, чтобы сделать простой текстовый редактор.
Для того, чтобы сделать полный редактор, можно добавить меню
File к основному окну для открытия и сохранения файлов текстов,
а также для копирования или поиска текста из редактируемого
блока управления и добавить меню Edit к основному окну для
копирования, разрезания и склеивания текста с помощью
системного буфера. Последующие главы проиллюсртируют некоторые
простые пути добавления этих возможностей в вашу программу.
8.6 Заключение.
В данное главе описано использование блоков управления в
прикладной программе. Блок управления - это специальное
дочернее окно, которое вы можете добалять к своей программе для
выполнения ввода от пользователя. Windows выполняет
автоматическую поддержку большинства типов блоков управления.
Например, Windows может автоматически рисовать блок управления
в указанной вами точке, при выборе пользователем блока
управления Windows посылает вашей программе сообщение,
содержащее идентификатор этого блока управления.
В данной главе также описано, как использовать наиболее
часто встречающиеся блоки управления.
Дополнительную информацию относительно блоков управления
вы найдете в:
Раздел Руководство
---------------------------------------------------------------
Обработка сообщений Руководство программиста, Глава 4, "Ввод с
ввода использованием мыши и клавиатуры"
Использование бло- Руководство программиста, Глава 9, "Панели
ков управления в диалога"
панелях дилога
.
Windows 3.0/pg/2#3 = 43 =
Управляющие функции Справочное руководство, том 1, глава 1,
"Функции интерфейса управления окнами",
Операторы описания Справочное руководство, том 2, глава 8,
ресурсов "Операторы описания ресурсов".
Демонстрационная Диск "SDK Sample Source Code Disk"
программа
OWNCOMBO.EXE,
иллюстрирует исполь-
зование каскадных
меню, меню, рисуемых
владельцем и конт-
рольных отметок, ри-
суемых владельцем.
.
Windows 3.0/pg/2#3 = 44 =
Глава 9. Панель диалога.
Панель диалога - это накладываемое окно, которое
прикладная программа использует для взаимодействия с
пользователем. Обычно панели диалога содержат один или
несколько блоков управления.
В данной главе описаны следующие разделы:
- Что такое панель диалога.
- Создание и использование модальных и немодальных панелей
диалога.
- Создание функций панелей диалога.
- Использование блоков управления в панели диалога.
В данной главе описан пример прикладной программы
FileOpen, которая иллюстрирует создание и использование
модальной панели диалога, содержащей несколько блоков
управления.
9.1 Что такое панель диалога.
Панель диалога - это накладываемое окно, которое
прикладные программы использует для индицирования или запроса
информации. Панели диалога обычно используют для запроса у
пользователя информации, необходимой для завершения команды.
Панель диалога содержит один или несколько блоков управления, с
помощью которых пользователь может ввести текст, выбрать
указания или заставить выполнить отдельную команду.
Пример панели диалога уже рассматривался в программе
Generic - это панель диалога About. Эта панель диалога содержит
текстовый блок управления, дающий информацию о прикладной
программе, а также блок управления типа альтернативная клавиша,
который может использоваться для закрытия панели диалога и
возврата в основное окно. Для обработки панели диалога
необходимо задать шаблон панели диалога, функцию диалога и
некоторые средства для вызова панели диалога.
Шаблон панели диалога - это описание панели диалога и
блоков управления, которые она содержит. Шаблон можно создать с
помощью текстового редактора или Редактора диалога среды
Windows 3.0, и затем добавить его к файлу описания ресурсов.
Функция диалога - это функция многократного вызова,
которую вызывает Windows, когда она имеет сообщение для панели
диалога. Хотя функция диалога аналогична функции окна, Windows
выполняет специальную обработку панелей диалога таким образом,
что функция диалога (по сравнению с функцией окна) отвечает за
другие действия.
.
Windows 3.0/pg/2#3 = 45 =
Обычный способ вызова панели диалога - в ответ на ввод из
меню. Например, команды "Open" и "Save As" в меню File требуют
дополнительной информации для завершения их работы. Обе они
индицируют панели диалога для запроса дополнительной
информации.
Имеется два типа панелей диалога: модальные и немодальные.
9.1.1 Модальные панели диалога.
Модальная панель диалога (About) уже использовалась в
прикладной программе Generic. Модальная панель диалога - это
накладываемое окно, которое индицирует информацию и запрос на
ввод от пользователя. Она называется модальной, поскольку
делает родительское окно временно недоступным и заставляет
пользователя закончить запрашиваемые действия перед возвратом
управления родительскому окну. Например, программа Windows
Notepad выводит модальную панель диалога в ответ на выбор
команды Open в меню File. Notepad не может продолжить
выполнение команды Open до тех пор, пока пользователь не укажет
файл.
Хотя можно дать модальной панели диалога почти любой тип,
рекомендованными типами являются DS_MODALFRAME, WS_CAPTION,
и WS_SYSMENU. Тип DS_MODALFRAME задает панели диалога в качестве
параметра двойную линию окантовки.
Модальная панель диалога запускает свой собственный цикл
обработки сообщений из очереди прикладной программы без
возврата в функцию WinMain. Для того, чтобы закрыть
родительскому окну обработку ввода, панель диалога делает его
недоступным перед этой обработкой. По этой причине модальная
панель диалога никогда не может быть создана с заданием типа
WS_CHILD, поскольку, если родительское окно делается
недоступным, также делается недоступным и окно дочернего типа,
принадлежащее этому родительскому окну.
Для отображения модальной панели диалога используется
функция DialogBox. Работа модальной панели диалога
заканчивается с помощью функции EndDialog.
9.1.2 Немодальные панели диалога.
Немодальная панель диалога - это просто накладываемое
окно, которое индицирует информацию или запрашивает ввод от
пользователя. В отличие от модальной панели диалога,
немодальная панель диалога не делает недоступным родительское
окно. Это означает, что можно продолжать работать в
родительском окне, пока немодальная панель диалога
индицируется. Например, Windows Write использует немодальную
панель диалога для команды Find. Это позволяет пользователю
продолжать редактировать текст не закрывая панель диалога Find.
.
Windows 3.0/pg/2#3 = 46 =
Большинство немодальных панелей диалога имеют типы
WS_POPUP, WS_CAPTION, WS_BORDER и WS_SYSTEMMENU. Обычно
немодальные панели диалога имеют системное меню, строку
заголовка и тонкую черную окантовку.
Хотя Windows автоматически делает недоступными некоторые
команды системного меню в панели диалога, меню все же содержит
команду Close. Пользователь может ее использовать вместо
альтернативной клавиши для завершения работы с панелью диалога.
Можно также включить в панель диалога блоки управления, такие
как редактируемые блоки управления и панели контроля.
Немодальная панель диалога получает информацию через цикл
обработки сообщений функции WinMain. Если в панели диалога
имеются блоки управления и необходимо дать пользователю
возможность переместить или выбрать блоки управления с помощью
клавиатуры, необходимо вызвать функцию IsDialogMessage в
основном цикле обработки сообщений. Эта функция определяет,
имеется ли сообщение о вводе с клавиатуры для панели диалога, и
при необходимости обрабатывает его. Цикл обработки сообщений
для программы, которая имеет немодальную панель диалога, будет
выглядеть следующим образом:
while (GetMessage(&msg, NULL, NULL, NULL) {
if (hDlg == NULL || !IsDialogMessage(hDlg, &msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Поскольку немодальная панель диалога может и не всегда
присутствовать, необходимо проконтролировать переменную hDlg,
которая содержит дескриптор, чтобы определить, допустима ли
панель. Если она допустима, функция IsDialogMessage определяет,
предназначено ли сообщение для панели диалога. Если это так,
сообщение обрабатывается и не должно в дальнейшем
обрабатываться с помощью функций TranslateMessage и
DispatchMessage.
Завершение работы немодальной панели диалога происходит с
помощью функции DestroyWindow.
9.2 Использование панели диалога.
Для создания панели диалога необходимо выполнить следующие
шаги:
1. Создать шаблон панели диалога и добавить его к файлу
описания ресурсов.
2. Создать функцию диалога для поддержки работы панели.
.
Windows 3.0/pg/2#3 = 47 =
3. Экспортировать функцию диалога.
4. Панель диалога отображается с помощью функций DialogBox
и CreateDialog. Эти функции запускают модальную и
немодальную панели диалога соответственно.
5. Закрыть панели диалога с помощью функций EndDialog или
DestroyWindow для модальной и немодальной панели
диалога соответственно.
В следующих разделах эти шаги описаны более подробно.
9.2.1 Создание функции панели дилога.
Функция диалога имеет следующий вид:
BOOL FAR PASCAL DlgFunc(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
DWORD lParam;
{
switch (message) {
/* здесь помещаются фрагменты с обработкой сообщений */
default:
return FALSE;
}
}
Это в основном функция окна за исключением того, что не
вызывается функция DefWindowProc. Обработка сообщений панелей
диалога по умолчанию осуществляется встроенными средствами
системы, поэтому функция диалога не должна вызывать функцию
DefWindowProc.
Функция диалога должна быть определена как процедура FAR
PASCAL и должна иметь указанные здесь параметры. Возвращаемое
значение должно иметь тип BOOL.
Как и в случае функций окна, среда Windows посылает
сообщения функции диалога, когда имеет для нее информацию и
когда необходимо , чтобы функция выполнила некоторые действия.
В отличие от функции окна функция диалога отвечает на сообщение
посылкой булевского значения. Если функция обрабатывает
сообщение, она возвращает TRUE. В противном случае она
возвращает FALSE.
В этой функции переменная hDlg получает дескриптор панели
диалога. Другие параметры служат тем же самым целям, что и
параметры функции окна. Оператор switch служит в качестве
фильтра для различных сообщений. Большинство функций диалога
.
Windows 3.0/pg/2#3 = 48 =
обрабатывает сообщения WM_INITDIALOG и WM_COMMAND и очень редко
другие.
Сообщение WM_INITDIALOG, посылаемое панели диалога
непосредственно перед ее индицированием, предоставляет функции
диалога возможность захватить ввод для любого блока управления.
Если функция возвращает TRUE, Windows обеспечит захват ввода
для выбранного блока управления.
Сообщение WM_COMMAND посылается в функцию диалога блоком
управления, принадлежащим панели диалога. Если в панели диалога
существуют блоки управления, они посылают уведомляющие
сообщения, когда пользователь выполняет некоторые действия с
ними. Например, функция обработки панели диалога с
альтернативными клавишами может проверять сообщения WM_COMMAND
на ID блока управления альтернативной клавиши. ID блока
управления содержится в параметре wParam. Когда функция диалога
находит ID, то выполняются соответствующие действия.
Если панель диалога создана с типом WS_SYSMENU, вы должны
включить в оператор switch обработку идентификатора IDCANCEL,
который посылается при выборе пользователем команды Close в
системном меню. Обработка этого сообщения должна включать вызов
функции EndDialog.
9.2.2 Использование блоков управления в панелях диалога.
Блоки управления в панелях диалога используются во многом
также, как они используются в обычных окнах. Однако, когда блок
управления находится в панели диалога, можно использовать
некоторые специальные функции для доступа к блоку управления и
посылки ему сообщений. Например, функция SendDlgItemMessage
посылает сообщение блоку управления в панели диалога, а функция
SetDlgItemText устанавливает текст блока управления. Не следует
задавать этим функциям дескриптор блока управления. Вместо
этого нужно задать дескриптор диалога и ID блока управления.
Для получения дескриптора блока управления можно использовать
функцию GetDlgItem.
9.3 Пример прикладной программы FileOpen.
Данный пример прикладной программы показывает, как
построить и использовать модальную панель диалога для поддержки
команды Открыть в меню Файл. Назначение и работа с панелью
диалога полностью описаны в System Application Architecture,
Common User Access: Advanced Interface Design Guide. На рисунке
9.1 показан вид панели диалога, которую отображает программа
FileOpen при выборе команды Open в меню File.
Рисунок 9.1 Панель диалога программы FileOpen.
1. Редактируемый блок управоления.
2. Статический блок управления.
3. Панель перечня.
.
Windows 3.0/pg/2#3 = 49 =
4. Альтернативные клавиши.
Панель диалога FileOpen содержит следующие блоки
управления:
1. Блок управления типа альтернативная клавиша по умол-
чанию, помеченный "Open", используемый для того,
чтобы побудить программу открыть выбранный файл.
2. Клавишный блок управления, помеченный "Cancel",
используется для отмены команды Открыть.
3. Однострочный редактируемый блок управления, в который
пользователь может вводить имя открываемого файла.
4. Панель перечня, содержащая имена файлов в текущем
каталоге, из которых пользователь может выбирать файл
для открытия.
Панель перечня также содержит имена каталогов и
устройств, которые могут быть использованы для
изменения текущего каталога или устройства.
5. Несколько статических блоков управления, используемых
для пометки панели перечня и редактируемого блока
управления, а также для индицирования текущего имени
каталога.
Для создания программы FileOpen скопируйте и переименуйте
исходные файлы прикладной программы EditCntl, а затем сделайте
следующие изменения:
1. Добавьте новые константы во включаемый файл.
2. Создайте шаблон панели диалога Open и добавьте его к
файлу описания ресурсов.
3. Добавьте новые переменные.
4. Добавьте фрагмент IDM_OPEN к фрагменту WM_COMMAND.
5. Создайте функцию диалога OpenDlg.
6. Добавьте вспомогательные функции для поддержки функции
диалога OpenDlg.
7. Экспортируйте функцию диалога OpenDlg.
8. Оттранслируйте и скомпонуйте программу.
Примечание: Вместо того, чтобы вводить тексты, приведенные
в следующих разделах, возможно вам будет удобнее просто
переписать исходные тексты из SDK.
.
Windows 3.0/pg/2#3 = 50 =
9.3.1 Добавление константы во включаемый файл.
Необходимо иметь несколько новых констант во включаемом
файле для идентификации блоков управления панели диалога
FileOpen. Добавьте следующие операторы:
#define ID_FILENAME 400
#define ID_EDIT 401
#define ID_FILES 402
#define ID_PATH 403
#define ID_LISTBOX 404
Хотя можно выбрать любое целое для ID блока управления,
для каждого блока управления в заданной панели диалога оно
должно быть уникальным. Обычно встроенные ID, такие как IDOK
или IDCANCEL, меньше 100, так что любое число, большее 100,
может использоваться для других блоков управления.
9.3.2 Создание шаблона панели диалога Open.
В файле описания ресурсов необходимо иметь шаблон для
определения размеров и внешнего вида панели диалога Open.
Оператор DIALOG специфицирует имя и размеры панели диалога, а
также блоки управления, которые она содержит. Добавьте
следующие операторы:
(1) Open DIALOG 10, 10, 148, 112
STYLE WS_MODALFRAME | WS_CAPTION | WS_SYSMENU
CAPTION "FileOpen"
(2) BEGIN
(3) LTEXT "Open File &Name", ID_FILENAME, 4, 4, 60, 10
(4) EDITTEXT ID_EDIT, 4, 16, 100, 12, ES_AUTOHSCROLL
LTEXT "&Files in", ID_FILES, 4, 40, 32, 10
(5) LISTBOX ID_LISTBOX, 4, 52, 70, 56, WS_TABSTOP
(6) LTEXT "", ID_PATH, 40, 40, 100, 10
(7) DEFPUSHBUTTON "&Открыть", IDOK, 87, 60, 50, 14
(8) PUSHBUTTON "Отменить", IDCANCEL 87, 80, 50, 14
END
В этом операторе DIALOG:
1) Панель диалога имеет ширину и высоту, равную
соответственно 148 и 112 (в единицах диалога). Единица
диалога - это доля размера символа системного шрифта по
умолчанию, которая используется в панелях диалога для
того, чтобы панель диалога имела одни и те же
относительные размеры вне зависимости от используемого
типа персональной ЭВМ.
2) Необходимы операторы BEGIN и END.
3) Первый оператор LTEXT создает выравненный влево
.
Windows 3.0/pg/2#3 = 51 =
статический блок управления, который содержит строку
"Open File &Name". Эта строка служит в качестве метки для
панели диалога. В некоторых панелях диалога все
статические блоки управления имеют один и тот же ID. Хотя
по общим правилам надо иметь уникальный ID для каждого
блока управления в панели диалога, допустимо использовать
-1 для статических блоков управления до тех пор, пока
функции диалога не надо будет различать их (например, до
тех пор, пока функция диалога не попытается изменить текст
или расположение статического блока управления).
4) Оператор EDITTEXT добавляет редактируемый блок управления
к панели диалога и идентифицирует его как ID_EDIT. Задан
тип ES_AUTOHSCROLL, так что пользователь может ввести имя
файла, которое длиннее ширины блока управления.
5) Оператор LISTBOX создает панель перечня. ID панели перечня
равен ID_LISTBOX. Ширина и высота панели перечня равны 70
и 56 соответственно (в единицах диалога). Задан тип
WS_TABSTOP, так что пользователь может захватить ввод для
панели перечня, используя клавиатуру. Если этот тип не
использовать, то единственным способом получения доступа к
панели перечня является нажатие на кнопку мыши.
6) Последний оператор LTEXT создает выравненный влево
статический блок управления, используемый для
указания текущего каталога и устройства. Блок управления
первоначально пуст; позже добавляется имя маршрута. Этот
блок управления имеет уникальный ID, равный ID_PATH, для
того, чтобы отличать его от других статических блоков
управления. Это важно, поскольку для заполнения блока
управления будет использоваться функция DlgDirList.
7) Оператор DEFPUSHBUTTON создает альтернативную клавишу по
умолчанию, которая помечена "Open" и имет ID блока
управления IDOK. В модальных панелях диалога нажатие
клавиши Enter генерирует уведомляющее сообщение, которое
использует тот же самый ID, так что для того, чтобы
открыть выбранный файл, пользователь может или нажать
мягкую клавишу, или клавишу Enter.
8) Оператор PUSHBUTTON создает альтернативную клавишу
"Cancel". Ее ID равен IDCANCEL (встроенный ID, находящийся
в файле windows.h). В модальных панелях диалога нажатие
клавиши Escape генерирует уведомляющее сообщение,
использующее тот же самый ID, так что для отмены команды
Open можно разрешить пользователю нажать или мягкую
клавишу, или клавишу Escape.
9.3.3 Добавление новых переменных.
Необходимо объявить несколько новых глобальных и локальных
переменных для хранения имени файла и отдельных частей, из
.
Windows 3.0/pg/2#3 = 52 =
которых оно строится. Добавьте следующие операторы в начало
файла ресурсов:
char FileName[128]; /* текущее имя файла */
char PathName[128]; /* текущий маршрут */
char OpenName[128]; /* имя открываемого файла */
char DefPath[128]; /* маршрут по умолчанию
для панели перечня */
char DefSpec[13] = "*.*"; /* выборка по умолчанию */
char DefExt[] = ".txt"; /* расширение имени файла
по умолчанию */
char str[255]; /* строка для вызова функ-
ции sprintf() */
Необходима также новая локальная переменная для хранения
адреса экземпляра процедуры для панели диалога FileOpen.
Добавьте следующий оператор к функции окна:
FAPROC lpOpenDlg;
9.3.4 Добавление фрагмента IDM_OPEN.
Необходимо занести фрагмент IDM_OPEN для сообщения
WM_COMMAND и индицировать панель диалога Open, когда
пользователь выбирает команду. Добавьте следующие операторы к
функции окна:
case IDM_OPEN:
lpOpenDlg = MakeProcInstance((FARPROC) OpenDlg, hInst));
DialogBox(hInst, "Open", hWnd, lpOpenDlg);
FreeProcInstance(lpOpenDlg);
break;
Функция MakeProcInstance создает адрес экземпляра
процедуры для функции OpenDlg. Это дает уверенность в том, что
при вызове функции диалога используются сегменты данных
текущего экземпляра. Функции типа OpenDlg, которые
экспортируются прикладной программой, могут быть вызваны только
через адрес экземпляра процедуры и не могут быть вызваны
непосредственно.
Функция FreeProcInstance используется для освобождения
адреса экземпляра процедуры, когда он становится не нужен.
После того, как функция DialogBox возвратит управление, адрес
экземпляра процедуры lpOpenDlg становится не нужен и может быть
освобожден. При следующем вызове панели диалога он должен быть
восстановлен.
Функция DialogBox возвращает управление только после того,
как функция диалога завершит работу с панелью диалога. Это
означает, что панель диалога должна выполнить все действия,
запрошенные пользователем, прежде чем программа может
продолжить работу. Такая панель диалога называется модальной,
.
Windows 3.0/pg/2#3 = 53 =
поскольку пока она находится на экране, программа работает в
другом режиме. Это означает, что пользователь может ответить
только панели диалога, а команды прикладной программы остаются
недоступными.
9.3.5 Создание функции OpenDlg.
Для обработки различных блоков управления необходимо
создать панель диалога Open. Когда панель диалога впервые
индицируется, функция диалога должна заполнить панель перечня и
редактируемый блок управления, а затем захватить ввод для этого
блока управления и выбрать полную спецификацию. Если
пользователь выбирает имя файла из панели перечня, функция
диалога должна скопировать имя в редактируемый блок управления.
Если пользователь нажмет клавишу Open, функция диалога должна
получить имя файла из редактируемого блока управления и
подготовить файл к открытию. Если пользователь дважды нажмет на
кнопку мыши, находясь на имени файла в панели перечня, функция
диалога должна найти имя файла, скопировать его в редактируемый
блок управления и подготовить файл к открытию.
Добавьте следующую функцию к файлу ресурсов:
HANDLE FAR PASCAL OpenDlg(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
WORD index; /* индекс имени файла в панели перечня */
PSTR pTptr; /* временный указатель */
HANDLE hFile; /* дескриптор открываемого файла */
switch (message) {
case WM_COMMAND:
switch (wParam) {
case ID_LISTBOX:
switch (HIWORD) {
case LBN_SELCHANGE:
if (!DlgDirSelect(hDlg, str,
ID_LISTBOX)) {
SetDlgItemText(hDlg,
ID_EDIT, str);
SendDlgItemMessage(hDlg,
ID_EDIT, EM_SETSEL,
NULL,
MAKELONG(0, 0x7fff));
}
else {
strcat(str, DefSpec);
DlgDirList(hDlg, str,
ID_LISTBOX, ID_PATH,
0x4010);
.
Windows 3.0/pg/2#3 = 54 =
}
break;
case LBN_DBLCLK:
goto openfile; /* конец фраг-
мента
ID_LISTBOX */
}
return (TRUE);
case IDOK:
openfile:
GetDlgItemText(hDlg, ID_EDIT, OpenName,
128);
if (strchr(OpenName, '*') ||
strchr(OpenName, '?')) {
SeparateFile(hDlg, (LPSTR) str,
(LPSTR) DefSpec,
(LPSTR) OpenName);
if (str[0])
strcpy(DefPath, str);
ChangeDefExt(DefExt, DefSpec);
UpdateListBox(hDlg);
return (TRUE);
}
if (!OpenName[0]) {
MessageBox(hDlg,
"Имя файла не задано", NULL,
MB_OK | MB_ICONQUESTION);
return (TRUE);
}
AddExt(OpenName, DefExt);
EndDialog(hDlg, NULL);
return (TRUE);
case IDCANCEL:
EndDialog(hDlg, NULL);
return (TRUE);
}
break;
case WM_INITDIALOG: /* запрос на инициали-
зацию */
UpdateListBox(hDlg);
SetDlgItemText(hDlg, ID_EDIT, DefSpec);
SendDlgItemMessage(hDlg, /* дескриптор панели
диалога */
ID_EDIT, /* куда послать сооб-
щение */
EM_SETSEL, /* выбор символов */
NULL, /* добавочная информа-
ция */
MAKELONG(0, 0x7fff)); /* прием полного со-
держимого */
SetFocus(GetDlgItem(hDlg, ID_EDIT));
return (FALSE); /* индикатор захвата ввода бло-
.
Windows 3.0/pg/2#3 = 55 =
ком управления */
}
return (FALSE);
}
Когда функция диалога получает сообщение WM_INITDIALOG,
функция SetDlgItemText копирует начальное имя файла в
редактируемый блок управления, а функция SendDlgItemMessage
посылает сообщение EM_SETSEL блоку управления для того, чтобы
выбрать его полное содержимое для редактирования. Функция
SetFocus захватывает ввод для редактируемого блока управления
(функция GetDlgItem получает дескриптор этого блока
управления). Функция UpdateListBox, заданная в начале фрагмента
WM_INITDIALOG, является локально определенной функцией, которая
заполняет панель перечня списком файлов текущего каталога.
Когда функция диалога получает сообщение WM_COMMAND, она
его обрабатывает для трех различных значений: IDOK, ID_LISTBOX
и IDCANCEL.
В случае ID_LISTBOX функция диалога проверяет тип
уведомляющего сообщения. Если он равен LBN_SELCHANGE, функция
диалога делает новую выборку с помощью функции DlgDirSelect.
Затем она копирует новое имя файла в редактируемый блок
управления, используя функцию SetDlgItem, и выбирает его для
редактирования, посылая сообщение EM_SETSEL. Если текущая
выборка не является именем файла, функция диалога копирует
спецификацию по умолчанию в панель перечня, используя функцию
DlgDirList. При этом панель перечня заполняется именами файлов
текущего каталога.
Если тип уведомляющего сообщения ID_LISTBOX равен
LBN_DBLCLK, функция диалога выполняет те же самые действия, что
для IDOK. Панель перечня посылает сообщение LBN_DBLCLK только
после того, как будет послано сообщение LBN_SELCHANGE. Это
означает, что когда пользователь получает уведомление о двойном
нажатии, не следует искать новое имя файла.
В случае IDOK функция диалога получает содержимое
редактируемого блока управления и проверяет имя файла на
корректность. Функция strchr ищет в имени универсальные
символы. Если она находит такой символ, то разделяет имя файла
на отдельные части - маршрут и имя файла, используя локально
определенную функцию SeparateFile. Функция strcpy корректирует
переменную DefPath с учетом нового маршрута, если он есть.
Локально определенная функция ChangeDefExt корректирует
переменную DefExt с учетом нового расширения имени файла по
умолчанию, если оно есть. После указанной корректировки функция
UpdateListBox корректирует содержимое панели перечня, а функция
диалога возвращает управление, чтобы дать пользователю
возможность выбрать корректное имя файла из нового перечня.
.
Windows 3.0/pg/2#3 = 56 =
Если имя файла не содержит универсальных символов, функция
диалога должна удостовериться, что файл не пуст. Если он пуст,
функция диалога индицирует предупреждающее сообщение, но не
завершает работу с панелью диалога. Это дает пользователю
возможность сделать еще одну попытку. Если имя файла не
содержит универсальных символов и файл не пуст, и если
пользователь вводит имя файла, не содержащее расширения,
функция диалога использует локально определенную функцию AddExt
для добавления расширения имени файла по умолчанию. Затем
функция диалога вызывает функцию EndDialog для завершения
работы модальной панели диалога и установки возвращаемого
значения в NULL.
В случае IDCANCEL функция диалога вызывает функцию
EndDialog для завершения работы с панелью диалога и отмены
команды. Возвращаемое значение устанавливается в NULL.
Перед завершением работы с панелью диалога функция диалога
может также проверить существование и режим доступа к заданному
файлу. Проверка на существование - дело самой прикладной
программы и в данном примере не производится. Некоторые простые
способы такой проверки приведены в главе 10 "Ввод и вывод в
файл".
9.3.6 Добавление вспомогательных функций.
Необходимо добавить несколько функций к исходному
С-файлу для поддержки функции диалога OpenDlg. Эти функции
перечислены ниже:
Функция Описание
---------------------------------------------------------------
UpdateListBox Заполняет панель перечня в панели диалога
Open именами указанных файлов.
SeparateFile Разделяет полное имя файла на имя маршрута
и имя файла.
ChangeDefExt Копирует расширение имени файла в буфер,
если только расширение не содержит универ-
сальных символов.
AddExt Добавляет расширение к имени файла, ес-
ли оно не имело расширения.
---------------------------------------------------------------
Функция UpdateListBox строит полное имя файла, используя
маршрут по умолчанию и имя файла, а затем передает его панели
перечня с помощью функции DlgDirList. Эта функция заполняет
панель перечня именами файлов и каталогов, каждый из которых
идентифицирован полным именем маршрута файла. Добавьте
следующие операторы к исходному С-файлу:
.
Windows 3.0/pg/2#3 = 57 =
void UpdateListBox(hDlg)
HWND hDlg;
{
strcpy(str, DefPath);
strcat(str, DefSpec);
DlgDirList(hDlg, str, ID_LISTBOX, ID_PATH, 0x4010);
SetDlgItemText(hDlg, ID_EDIT, DefSpec);
}
Функция SetDlgItemText копирует имя файла по умолчанию в
редактируемый блок управления панели диалога.
Функция SeparateFile разделяет полное имя файла на две
части и копирует их в раздельные буферы. Она сначала
перемещается в конец полного имени файла и использует функцию
AnsiPrev для обратного перемещения, находя при этом разделитель
перед именем драйвера или каталога. Добавьте следующие
операторы к исходному С-файлу:
void SeparateFile(hDlg,lpDestPath, lpDestFileName,
lpSrcFileName)
HWND hDlg;
LPSTR lpDestPath, lpDestFileName, lpSrcFileName;
{
LPSTR lpTmp;
CHAR cTmp;
lpTmp = lpSrcFileName + (long) lstrlen(lpSrcFileName);
while (*lpTmp != ':' && *lpTmp != '\' &&
lpTmp > lpSrcFileName)
lpTmp = AnsiPrev(lpSrcFileName, lpTmp);
if (*lpTmp != ':' && *lpTmp != '\') {
lstrcpy(lpDestFileName, lpSrcFileName);
lpDestPath[0] = 0;
return;
}
lstrcpy(lpDestFileName, lpTmp + 1);
cTmp = *(lpTmp + 1);
lstrcpy(lpDestPath, lpSrcFileName);
*(lpTmp + 1) = cTmp;
lpDestPath[(lpTmp - lpSrcFileName) + 1] = 0;
}
Функции ChangeDefExt и AddExt используют стандартные
операторы языка С для выполнения поставленной перед ними
задачи. Добавьте следующие операторы к исходному С-файлу:
void ChangeDefExt(Ext, Name)
PSTR Ext, Name;
{
PSTR pTptr;
pTptr = Name;
.
Windows 3.0/pg/2#3 = 58 =
while (*pTptr && *pTptr != '.')
pTptr++;
if (*pTptr) /* true, если это - рас-
ширение */
if (!strchr(pTptr, '*') && !strchr(pTptr, '?'))
strcpy(Ext, pTptr); /* копировать расшире-
ние */
}
void AddExt(Name, Ext)
PSTR Ext, Name;
{
PSTR pTptr;
pTptr = Name;
while (*pTptr && *pTptr != '.')
pTptr++;
if (*pTptr != '.') /* если нет расширения -
добавить расширение
по умолчанию */
strcat(Name, Ext);
}
9.3.7 Экспортирование функции диалога.
Необходимо экспортировать функцию диалога OpenDlg, т.к.
это функция многократного вызова и вызывается только Windows.
Добавьте следующую строку к оператору EXPORTS в файле
определения модуля:
OpenDlg @3
9.3.8 Трансляция и компоновка.
В файле make не требуется проводить изменений.
Оттранслируйте и скомпонуйте прикладную программу, запустите
Windows и программу FileOpen. Когда будет открыто меню File и
выбрана команда Open, панель диалога примет вид, представленный
на рис. 9.1. в начале данного раздела. Выберите файл из панели
перечня или введите имя файла в редактируемый блок управления,
а затем выберите клавишу "Open".
9.4 Заключение.
В данной главе описано как создавать и использовать в
прикладных программах панели диалога. Панель диалога - это
специальное окно, которое перекрывает основное окно прикладной
программы. Имеется два типа панелей диалога: модальные и
немодальные. Модальные панели диалога требуют завершения ввода
от пользователя до того, как они вернут управление основному
окну прикладной программы. Немодальные панели диалога не
требуют завершения ввода от пользователя для того, чтобы
передать управления другим окнам программы.
.
Windows 3.0/pg/2#3 = 59 =
Windows предоставляет набор специальных функций для работы
с блоками управления в панели диалога.
Для создания панелей диалога можно использовать Dialog
Editor.
Дополнительную информацию относительно панелей диалога вы
найдете в:
Раздел Руководство
---------------------------------------------------------------
Обработка сообщений Руководство программиста, Глава 4, "Ввод с
ввода использованием мыши и клавиатуры".
Блоки управления Руководство программиста, Глава 8, "Блоки
управления".
Функции блоков уп- Справочное руководство, том 1, глава 1,
равления и панелей "Функции интерфейса управления окнами".
диалога
Операторы описания Справочное руководство, том 2, глава 8,
ресурсов "Операторы описания ресурсов".
Использование "Tools", Глава 5, "Создание панелей диа-
Dialog Editor лога: The Dialog Editor".
Демонстрационная Диск "SDK Sample Source Code Disk".
программа
OWNCOMBO.EXE,
иллюстрирующая ис-
пользование комби-
нированных блоков и
рисуемых блоков уп-
равоения.
.
Windows 3.0/pg/2#3 = 60 =
Глава 10. Ввод и вывод из файлов.
Ввод и вывод файлов в среде Windows аналогичен вводу и
выводу файлов в стандартных программах исполняющей системы С.
Однако имеются и существенные отличия. Например, хотя во время
выполнения программ в Windows можно использовать поточные
функции ввода и вывода исполняющей системы С, предпочтительнее
оказываются функции ввода и вывода низкого уровня. Кроме того,
поскольку Windows является многозадачной средой, необходимо
особенно внимательно следить за открытыми файлами.
Для того, чтобы поддерживать указанные различия, имеется
функция OpenFile. Функция OpenFile открывает файлы и управляет
ими, возвращая дескриптор файла, который можно использовать в
функциях низкого уровня исполняющей системы С для чтения и
записи данных.
В данной главе описаны следующие темы:
- Работа с файлами в среде Windows.
- Как использовать функцию OpenFile для создания,
открытия, повторного открытия, запроса и проверки
состояния файлов.
- Работа с низкоуровневыми функциями исполняющей системы С
для чтения и записи в файлы.
В данной главе описано создание простой прикладной
программы EditFile, которая иллюстрирует использование этих
возможностей.
10.1 Правила работы с файлами в среде Windows.
Многозадачность накладывает некоторые специальные
ограничения на доступ к файлам, с которыми не сталкиваются в
обычных С-программах. Поскольку может быть несколько программ,
одновременно работающих с файлами, необходимо следовать
некоторым простым правилам для того, чтобы избежать конфликтов
и возможного затирания файлов.
Держите файл открытым только когда ваша программа имеет
управление.
Необходимо закрывать файлы перед вызовом функции
GetMessage или любой другой функции, которая берет на себя
управление выполнением программы. Закрытие файла предотвратит
его от влияния изменений файловой среды, которые могут быть
результатом работы другой программы. Предположим ваша программа
производит запись на гибкий диск и временно передала управление
другой программе, которая может дать указание удалить гибкий
диск и заменить его другим. Если первая программа вновь получит
управление и попытается писать на диск, как делала это ранее,
.
Windows 3.0/pg/2#3 = 61 =
то без закрытия и повторного открытия файла она разрушит данные
на новом диске.
Другая причина держать файлы закрытыми состоит в
ограниченном числе открытых файлов (ограничение операционной
системы). Если сразу большое число программ попытается открыть
и использовать файлы, то указанный предел может быстро
исчерпаться.
Для решения проблемы открытых файлов функция OpenFile
имеет параметр OF_REOPEN, который позволяет легко закрывать и
повторно открывать файлы. Как только файл открывается или
создается, функция OpenFile автоматически копирует
соответствующую информацию о файле, включающую полное имя файла
и текущую позицию указателя файла, в структуру OFSTRUCT. Это
означает, что можно закрыть файл, а затем его повторно открыть,
задавая только эту структуру.
Если диск был изменен во время работы с другой программой,
функция OpenFile выдает ошибку при повторном открытии файла.
Если при повторном открытии файла было специфицировано указание
OF_PROMPT, функция OpenFile автоматически индицирует панель
сообщений, делая запрос на установку нужного диска.
При выполнении операций над файлами необходимо следовать
соглашениям DOS.
В конечном счете, при вводе и выводе файлов Windows
зависит от функций управления файлами операционной системы. Это
означает, что при выполнении операций над файлами необходимо
следовать соглашениям, принятым в операционной системе.
Например, имя файла может иметь от одного до восьми символов, а
число символов в расширении файла может изменяться от нуля до
трех. Имя файла не должно содержать пробелов или специальных
символов. Более того, имена файлов должны быть специфицированы
набором символов OEM, а не набором символов по умолчанию
(ANSI).
Дело программиста - следить за тем, чтобы имя файла имело
определенную длину или состояло из соответствующих знаков, но
он может не беспокоиться о преобразовании набора знаков, если
использует функцию OpenFile. Для удобства эта функция
автоматически преобразует имена файлов из набора символов ANSI
в набор символов OEM. Делается это с помощью функции AnsiToOem.
Примечание: Все редактируемые блоки управления и панели
перечней по умолчанию используют набор символов ANSI, так что,
если планируется индицировать имена файлов DOS или позволить
пользователю ввести имена файлов, можно получить
непредсказуемые символы там, где символ OEM не идентичен
символу ANSI.
Если необходимо работать с международными именами файлов,
.
Windows 3.0/pg/2#3 = 62 =
необходимо подготовить для обработки имена файлов, которые
содержат многобайтные значения символов (например, иероглифы).
Для таких имен файлов следует использовать функции AnsiNext и
AnsiPrev для перемещения по строке. Эти функции правильно
управляют строками, которые содержат символы, длина которых не
равна одному байту, например, как строки из символов японского
алфавита.
Используйте в каждом экземпляре вашей программы уникальные
имена файлов.
Поскольку несколько экземпляров одной программы могут
работать одновременно, один из них может стереть временный или
рабочий файл другого экземпляра, если не использовать
уникальное имя файла для каждого экземпляра.
Уникальное имя файла можно создать с помощью функции
GetTempFilename. Эта функция создает уникальное имя, объединяя
уникальное целое с префиксом и расширением имени файла,
задаваемыми пользователем. Временные имена удовлетворяют
требованиям, предъявляемым к именам файлов операционной
системой.
Примечание: Функция GetTempFilename использует переменную
среды TEMP для создания полного имени временного файла. Если
пользователь не задаст эту переменную, временный файл будет
помещен в корневой каталог текущего устройства. Если переменная
определяет недоступный каталог, пользователь не сможет создать
временный файл.
Закрывайте файлы перед отображением панели сообщения или
используйте системные модальные панели сообщений об
ошибках.
Как было сказано выше, программа не должна передавать
управление, пока держит файлы открытыми. Если ваша программа
использует не системную модальную панель выдачи сообщений, то
пользователь может перейти к другой программе, когда на экране
индицируется панель сообщений. Если в программе есть открытые
файлы, то переключение на другую программу может вызвать
проблемы ввода вывода.
Для исключения этих проблем, ваша программа при
отображении панели сообщений должна делать по крайней мере одно
из:
- Закрыть открытые файлы перед отображением панели
сообщений.
- Если закрытие файлов неудобно, то необходимо сделать
панель диалога системно-модальной.
.
Windows 3.0/pg/2#3 = 63 =
10.2 Создание файлов.
Для создания нового файла можно использовать функцию
OpenFile с ключем OF_CREATE. При вызове функции OpenFile
необхожимо указать:
- Оканчивающееся нулем имя файла.
- Буфер типа OFSTRUCT.
- Ключ OF_CREATE.
В приведенном ниже примере создается файл file.txt и
возвращается дескриптор файла, который может быть использован в
функциях ввода/вывода низкого уровня библиотеки С:
int hFile;
OFSTRUCT OfStruct;
.
.
.
hFile=OpenFile("file.txt", &OfStruct, OF_CREATE);
Функция OpenFile создает файл (если это необходимо) и
открывает его для записи. Если файл уже существует, функция
усекает его до нулевой длины и открывает для записи.
Если не допускается стирание существующего файла, то перед
созданием нового файла можно проверить, существует ли данный
файл, вызвав функцию OpenFile, как это показано ниже:
hFile = OpenFile("file.txt", &OfStruct, OF_EXIST);
if (hFile >= 0) {
wAction = MessageBox(hWnd,
(LPSTR) "Файл существует. Переписать?",
(LPSTR) "File",
MB_OKCANCEL);
if (wAction == IDCANCEL)
/* закончить эту обработку */
}
}
/* открыть файл */
10.3 Открытие существующих файлов.
Можно открыть существующий файл, использовав параметры
OF_READ, OF_WRITE или OF_READWRITE. Эти параметры побуждают
функцию OpenFile открыть существующие файлы для чтения, записи
или чтения и записи. В приведенном ниже примере файл file.txt
открывается для чтения:
hFile = OpenFile("file.txt", &OfStruct, OF_READ);
Если произошла ошибка при открытии файла, можно
.
Windows 3.0/pg/2#3 = 64 =
индицировать панель диалога и указать, что файл не был найден.
Можно также использовать функцию OpenFile для подсказки
пользователю о файле, как это описано в подразделе 10.6 "Запрос
имени файла".
10.4 Чтение и запись файлов.
Как только файл открыт, то можно из него читать или в него
записывать, используя функции С низкого уровня. В приведенном
ниже примере файл file.txt открывается для чтения и затем из
него считывается 512 байтов:
char buffer[512];
int count;
.
.
.
hFile = OpenFile("file.txt", &OfStruct, OF_READ);
if (hFile >= 0) {
count = read(hFile, buffer, 512);
close(hFile);
}
В этом примере перед считыванием из файла проверяется
дескриптор файла. Функция OpenFile возвращает -1, если файл не
может быть найден или открыт. Функция close закрывает файл
сразу же после чтения.
В приведенном ниже примере файл file.tmp открывается для
записи, и, затем, в него записывается содержимое буфера в виде
массива символов:
hFile = OpenFile("file.tmp", &OfStruct, OF_READ);
if (hFile >= 0) {
write (hFile, buffer, count);
close (hFile);
}
Всегда необходимо закрывать файлы на гибких дисках после
чтения или записи. Это необходимо делать для того, чтобы обойти
проблемы, возникающие при удалении текущего диска во время
работы с другой программой. Всегда можно повторно открыть файл
на диске, используя параметр OF_REOPEN.
10.5 Повторное открытие файлов.
Если вы открыли файл на гибком диске, его необходимо
закрыть перед тем, как передать управление другой программе.
Наиболее подходящий для этого момент - непосредственно после
чтения или записи. Файл всегда можно повторно открыть с помощью
функции OpenFile с ключем OF_REOPEN:
hFile=OpenFile((LPSTR)NULL, &OfStruct, OF_REOPEN | OF_READ);
.
Windows 3.0/pg/2#3 = 65 =
В этом примере функция OpenFile использует имя файла из
структуры OfStruct для открытия файла. При повторном открытии
файла его указатель, отслеживающий текущую позицию в файле,
перемещается в ту же самую точку файла, в которой он находился
непосредственно перед закрытием файла.
10.6 Запрос имени файла.
С помощью ключа OF_PROMPT можно автоматически подсказать
пользователю вставить нужную дискету перед повторным открытием
файла. Функция OpenFile использует имя файла для создания
строки подсказки. При повторном открытии файла надо в
добавление к режиму открытия использовать параметры OF_REOPEN
или OF_PROMPT:
hFile = OpenFile((LPSTR)NULL, &OfStruct, OF_PROMPT |
OF_REOPEN | OF_READ);
Если файл повторно открыт только для чтения, Windows будет
проверять, соответствует ли дата и время той дате и времени,
когда файл был открыт впервые.
10.7 Проверка состояния файла.
Можно определить текущее состояние открытого файла,
использовав функцию С низкого уровня fstat. Эта функция
заполняет структуру информацией о файле, такой как длина файла
в байтах (специфицирована полем size), дата и время его
создания. В приведенном ниже примере структура FileStatus
заполняется информацией о файле file.txt:
stat FileStatus;
.
.
.
fstat(hFile, FileStatus);
10.8 Простой редактор файлов EditFile.
В данном примере показано, как создать простую программу,
которая использует функцию OpenFile и функции исполняющей
системы С для открытия и сохранения небольших текстовых файлов.
Для создания программы EditFile необходимо скопировать и
переименовать ресурсы программы FileOpen, описанные в главе 9
"Панели диалога" и модифицировать их следующим образом:
1. Добавить константы во включаемый файл.
2. Создать шаблон панели диалога SaveAs и добавить его к
файлу описания ресурсов.
3. Добавить новые операторы включения в исходный С-файл.
.
Windows 3.0/pg/2#3 = 66 =
4. Добавить новые переменные.
5. Заменить фрагмент WM_COMMAND.
6. Добавить фрагменты WM_QUERYENDSESSION и WM_CLOSE.
7. Модифицировать функцию диалога OpenDlg.
8. Создать функцию диалога SaveAs.
9. Создать вспомогательные функции для функции диалога
SaveAs.
10. Экспортировать функцию диалога SaveAs.
11. Модифицировать оператор HEAPSIZE.
12. Оттранслировать и скомпоновать программу.
Когда прикладная программа завершена, можно просмотреть
текстовые файлы в редактируемом блоке управления. Команда
прикладной программы Open из меню File позволяет указать
открываемый файл. Можно также делать изменения в файле или
вводить новый текст, а также сохранять текст, используя команды
"Save" или "SaveAs" в панели диалога.
Примечание: Вместо того, чтобы вводить тексты, приведенные
в следующих разделах, возможно вам будет удобнее просто
переписать исходные тексты из SDK.
10.8.1 Добавление констант во включаемый файл.
Для поддержки панели диалога SaveAs необходимо добавить
определения констант во включаемый файл. Добавьте следующий
оператор в этот файл:
#define MAXFILESIZE 0x7FFF
10.8.2 Добавление панели диалога SaveAs.
Для поддержки команды "SaveAs" необходима новая панель
диалога. Панель диалога "SaveAs" запрашивает имя файла и дает
возможность пользователю ввести имя в редактируемый блок
управления. Добавьте оператор DIALOG к файлу ресурсов: SaveAs
Saveas DIALOG 10, 10, 180, 53
STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
CAPTION "Save As "
BEGIN
LTEXT "Save As File &Name:", IDC_FILENAME, 4, 4, 72, 10
LTEXT "", IDC_PATH, 84, 4, 92, 10
EDITTEXT IDC_EDIT, 4, 16, 100, 12
.
Windows 3.0/pg/2#3 = 67 =
DEFPUSHBUTTON "Save", IDOK, 120, 16, 50, 14
PUSHBUTTON "Cancel", IDCANCEL, 120, 36, 50, 14
END
Константы ID_PATH, ID_FILENAME, ID_EDIT, IDCANCEL и IDOK -
те же самые, что использовались в панели диалога Open.
Поскольку панели диалога Open и SaveAs никогда не будут открыты
одновременно, нет необходимости беспокоиться о конфликтах ID
блоков управления.
10.8.3 Добавление операторов include.
Для поддержки операций ввода и вывода файлов необходимо
включить дополнительные включаемые файлы. Добавьте следующие
операторы в начало исходного С-файла:
#include
|
| ::Главная ->Литература ->Руководство по программированию в Windows | |
|
|
|
(c) 2000 by AlmigoR
|
|