47816 (597361), страница 13
Текст из файла (страница 13)
#define WM_COPYDATA 0x004A
typedef struct tagCOPYDATASTRUCT {
DWORD dwData;
DWORD cbData;
LPVOID lpData;
} COPYDATASTRUCT, FAR* PCOPYDATASTRUCT;
Хендл модуля (HMODULE)
В Windows 3.x под модулем понимается отдельный выполняемый файл или библиотека динамической компоновки. Для описания модуля создается специальный сегмент описания модуля, содержащий информацию о всех сегментах данного модуля и их атрибутах. Хендл модуля идентифицирует этот сегмент. Для получения хендла модуля Вы можете воспользоваться функциями:
HMODULE GetModuleHandle( lpszFileName );
int GetModuleFileName( hInstance, lpsBuffer, cbMaxSize );
В Windows 3.x хендл модуля часто может быть заменен на хендл копии приложения. В Win32 хендл модуля вообще является синонимом хендла копии приложения. В документации еще встречаются оба термина, как они перекочевали из 16ти битовых Windows, хотя теперь они тождественны.
Подробнее о приложении (2)
Итак, в предыдущих разделах мы рассмотрели основы организации приложения в среде Windows. Это было первое знакомство с простейшим приложением, которое было лишь поводом для разговора об основах работы оконных систем.
Приложение в среде Windows, как и в среде DOS, содержит так называемую главную функцию — WinMain, вызываемую при запуске приложения. Приложение завершается при окончании работы этой функции.
Обычно, хотя это и не обязательно, функция WinMain реализует следующую схему:
-
выполняются требуемые инициализационные действия
-
создается главное окно приложения, для чего часто регистрируется новый класс окон (оконная функция);
-
организуется цикл обработки сообщений приложения. Обычно цикл завершается при закрытии главного окна приложения;
-
после завершения цикла обработки сообщений выполняется освобождение занятых ресурсов, после чего функция WinMain заканчивается.
Замечание 1. Если приложение содержит непродолжительные (порядка 1 сек.) операции, не требующие взаимодействия с пользователем (например, только файл–ориентированный ввод–вывод или настройка другого приложения), то эти действия могут быть выполнены непосредственно функцией WinMain без создания окон и без организации цикла обработки сообщений.
Замечание 2. В некоторых случаях приложение может обойтись без регистрации класса окон и организации цикла обработки сообщений, применяя в качестве главного окна модальный диалог.
Замечание 3. В момент вызова функции WinMain ей, через аргументы, передается несколько параметров, например хендл копии приложения hInstance. До вызова WinMain приложение “не знает” этих данных. Поэтому могут возникать сложности с использованием статических конструкторов объектно–ориентированных языков (C++).
!!!!!!!!Фокус ввода!!!!!!
В Windows существует определенная путаница терминов. Попробуем разобраться с некоторыми из них. Как известно, окно может находиться в нескольких состояниях:
Максимизированном, то есть быть “распахнутым” на весь экран — при этом внутренняя область окна занимает весь экран, кроме небольших полос сверху — где размещается заголовок и меню, снизу — горизонтальная полоса прокрутки и справа — вертикальная полоса прокрутки; рамка окна находится за пределами экрана, мы ее не видим, перемещение окна невозможно.
Для максимизации окна мы можем воспользоваться функцией ShowWindow со следующими возможными параметрами:
ShowWindow( hWnd, SHOW_FULLSCREEN );
ShowWindow( hWnd, SW_SHOWMAXIMIZED );
ShowWindow( hWnd, SW_MAXIMIZE );
максимизированное окно всегда активно и имеет фокус ввода. Когда какое–либо окно максимизируется, все остальные верхние окна получают сообщение WM_SIZE, информирующее о том, что они “закрыты” сверху максимизированным окном.
Мы можем узнать, является ли наше окно максимизированным с помощью функции
BOOL IsZoomed( hWnd );
При использовании системного меню операции максимизации окна соответствует пункт Maximize, выбор которого порождает системную команду SC_MAXIMIZE (или синоним SC_ZOOM). (см. сообщение WM_SYSCOMMAND)
Здесь вместо термина maximize может использоваться zoom.
Минимизированным, то есть представленным в виде пиктограммы. Для того, что бы превратить окно в пиктограмму, мы должны воспользоваться одним из способов:
ShowWindow( hWnd, SHOW_ICONWINDOW );
ShowWindow( hWnd, SW_SHOWMINIMIZED );
ShowWindow( hWnd, SW_SHOWMINNOACTIVE );
ShowWindow( hWnd, SW_MINIMIZE );
CloseWindow( hWnd );
Разные способы, использующие ShowWindow, отличаются только правилами активации окна. SW_SHOWMINIMIZED и SHOW_ICONWINDOW отображает окно в виде пиктограммы, делая его активным; SW_SHOWMINNOACTIVE не изменяет текущего активного окна; SW_MINIMIZE (как и функция CloseWindow) делает активным следующее окно в списке Windows. Последний способ эффективен при минимизации главного окна приложения — так как минимизированное главное окно обычно обозначает передачу активности другому приложению.
Проверить состояние окна можно с помощью функции
BOOL IsIconic( hWnd );
При использовании системного меню превращению окна в иконку соответствует пункт Minimize, порождающий системную команду SC_MINIMIZE (или синоним SC_ICON). (см. сообщение WM_SYSCOMMAND)
В этом случае используется сразу три разных термина для обозначения одного и того–же: minimize, close и iconic. При этом функция CloseWindow является единственной, интерпретирующей термин close таким способом; в остальных случаях close означает действительно закрытие (иногда уничтожение) окна. Здесь же надо, что термин open, применяемый к минимизированному окну обозначает его максимизацию или восстановление нормальных размеров.
Нормальным, то есть мы видим (или можем увидеть) его рамку, мы можем перемещать окно по экрану. Когда окно находится в нормальном состоянии, то для него определены максимально и минимально допустимый размеры. Эти размеры нельзя путать с максимизированным и минимизированным состояниями. Максимальный размер нормального окна может даже превышать размер окна в максимизированном состоянии, минимальный размер это обычно такой размер, при котором окно еще может быть корректно представлено в виде окна.
Для перехода из минимизированного состояния к нормальному можно воспользоваться функцией
OpenIcon( hWnd );
или, как из минимизированного, так и из максимизированного состояния можно пользоваться функцией ShowWindow с параметрами:
ShowWindow( hWnd, SHOW_OPENWINDOW );
ShowWindow( hWnd, SW_SHOWNORMAL );
ShowWindow( hWnd, SW_RESTORE );
ShowWindow( hWnd, SW_SHOWNOACTIVATE );
В документации (SDK Help) указано, что SW_RESTORE и SW_SHOWNORMAL эквивалентны, но это далеко не так — SW_RESTORE восстанавливает предыдущее состояние, а не нормальное. То есть, если Вы минимизировали окно из максимизированного, то SW_RESTORE вернет Вас к максимизированному окну, а SW_SHOWNORMAL — к нормальному. SW_SHOWNORMAL имеет синоним SHOW_OPENWINDOW.
Если окно восстанавливается или максимизируется из минимизированного состояния, то Ваше окно получит сообщение WM_QUERYOPEN — обрабатывая которое Вы можете разрешить или запретить дальнейшие действия. Если Вы возвращаете TRUE, то окно будет раскрыто, а если Вы вернете FALSE, то окно останется минимизированным.
Несколько замечаний: На самом деле Windows не является настоящей объектно–ориентированной средой. Хотя окно и может быть названо объектом ООП, но лишь с достаточной натяжкой. Самое существенное отличие окна в Windows от объекта ООП заключается в том, что сообщение, обрабатываемое оконной функцией, во многих случаях не выполняет действий, а является “информационным”, указывая на то, что над окном выполняется та или иная операция какой–либо внешней функцией.
Поясним это на примере создания окна. В случае ООП для уничтожения объекта он должен получить сообщение “destroy”, обработка которого приведет к его уничтожению. В Windows сообщение WM_DESTROY не выполняет никаких функций по уничтожению окна. Оно только информирует окно о том, что в это время окно уничтожается средствами обычной функциональной библиотеки, например посредством функции DestroyWindow. Вы можете вообще игнорировать это сообщение, возвращать любое значение, вызывать или не вызывать функцию обработки по умолчанию — окно все равно будет уничтожено.
Если бы все сообщения, получаемые окном были только информационными, то к этому легко можно было бы приспособиться. Однако для некоторых сообщений должна выполняться обработка по умолчанию, если Вы ее не выполнили сами, а для других такая обработка должна выполняться обязательно, даже если Вы уже обработали это сообщение. Все это заметно усложняет написание приложений в среде Windows.
Ситуация дополнительно усугубляется тем, что в документации, как правило, ничего не сообщается о том, какая обработка сообщения выполняется по умолчанию и, кроме того, по некоторым сообщениям приводятся некорректные (или неполные) сведения об их параметрах, выполняемым функциям, условиям возникновения и возвращаемом результате.
Для окон, использующих в качестве процедуры обработки сообщений по умолчанию не DefWindowProc, а иную функцию (например, DefMDIChildProc), можно уточнить список сообщений обязательно подлежащих обработке по умолчанию. Однако это уточнение касается только тех сообщений, обработку которых для DefWindowProc можно игнорировать, а для иных функций нельзя, список же того, что можно игнорировать для DefWindowProc, а что нельзя остается неизвестным.
Настройка приложений
Под настройкой (иногда "профилированием") понимается задание характеристик приложения и их сохранение для использования при следующем запуске.
Обычно такие задачи решаются с помощью создания настроечных файлов. Однако конфигурация описывается каждой задачей по–своему, что не всегда удобно. Windows предлагает общий для всех приложений механизм описания их характеристик, с использованием файлов настройки.
Такие файлы (обычно имеющие расширение .INI) являются обычными ASCII–файлами, разделенными на секции, начинающиеся с имени секции, заключенного в квадратные скобки. Далее следует список параметров в виде параметр=значение, каждый параметр размещается в отдельной строке. В этот файл можно вставлять комментарии — строки начинающиеся с ‘;’.
Пример взят из файла WORKSHOP.INI:
[User Controls]
BorShade=E:\BORLANDC\WORKSHOP\BWCC.DLL
[RWS_Bitmap]
PercentLeft=50
ZoomLeft=1
ZoomRight=1
bVert=0
[RWS_Font]
PercentLeft=50
ZoomLeft=4
ZoomRight=1
bVert=1
Для работы с такими файлами Windows предоставляет набор функций, осуществляющих запись и чтение параметров:
int GetProfileInt(lpszSection, lpszEntry, nDefault);
int GetProfileString(
lpszSection, lpszEntry, lpszDefault, lpsBuffer, nMaxBuffer
);
BOOL WriteProfileString(lpszSection, lpszEntry, lpszString);
Параметр lpszSection задает имя секции (квадратных скобок в имени указывать не надо), lpszEntry — имя параметра. Если мы получаем значение параметра, то можем указать значение по умолчанию, которое возвращается, если данный параметр не найден.
С помощью функции GetProfileString можно получить список имен всех параметров в секции, указав lpszEntry равным NULL. При этом имена параметров секции будут скопированы в буфер последовательно друг за другом, каждое имя будет заканчиваться байтом '\0' и после последнего имени будут стоять два байта '\0'.
Функция WriteProfileString позволяет не только записывать параметры, но и удалять, для чего надо указать lpszString равным NULL. Можно удалить целиком всю секцию, указав для этого lpszEntry равным NULL.
Все три рассмотренных функции используют файл WIN.INI. При этом имя секции часто ассоциируется с именем приложения, поэтому в документации имя секции часто называется именем приложения.
Конечно, часто бывает неудобно использовать общий файл настроек для всех существующих приложений (при этом, в частности, трудно организовать удаление приложений). Windows предоставляет возможность использовать собственный файл настройки. Для работы с собственными файлами настройки предусмотрены еще три функции:
int GetPrivateProfileInt( lpszSection, lpszEntry, nDefault, lpszIniFile );
int GetPrivateProfileString(
lpszSection, lpszEntry, lpszDefault, lpsBuffer, nMaxBuffer, lpszIniFile
);
BOOL WritePrivateProfileString( lpszSection, lpszEntry, lpszString, lpszIniFile );
Последний параметр этих функций lpszIniFile задает имя файла настройки. Если вы не указываете путь к файлу, то он размещается в каталоге Windows.
Реестр Windows
RegOpenKey Opens a specified key
RegCreateKey Creates a specified key
RegCloseKey Closes a key and releases the key's handle
RegQueryValue Retrieves the text string for a specified key
RegSetValue Associates a text string with a specified key















