Смекни!
smekni.com

Ознакомление с приложениями Windows (стр. 17 из 18)

Проверить состояние окна можно с помощью функции

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

RegDeleteKey Deletes a specified key

RegEnumKey Enumerates the subkeys of a specified key

#include shellapi.h

LONG RegOpenKey(hkey, lpszSubKey, lphkResult);
HKEY hkey; /* handle of an open key */
LPCSTR lpszSubKey; /* address of string for subkey to open */
HKEY FAR* lphkResult; /* address of handle of open key */

The RegOpenKey function opens the specified key.

Parameter Description

hkey Identifies an open key (which can be HKEY_CLASSES_ROOT). The key opened by the RegOpenKey function is a subkey of the key identified by this parameter. This value should not be NULL.

lpszSubKey Points to a null-terminated string specifying the name of the subkey to open.

lphkResult Points to the handle of the key that is opened.

Returns

The return value is ERROR_SUCCESS if the function is successful. Otherwise, it is an error value.

Comments

Unlike the RegCreateKey function, the RegOpenKey function does not create the specified key if the key does not exist in the database.

Example

char szBuff[80];
LONG cb;
HKEY hkStdFileEditing;

if (
RegOpenKey(
HKEY_CLASSES_ROOT,
"NewAppDocument\protocol\StdFileEditing",
&hkStdFileEditing
) == ERROR_SUCCESS
) {

cb = sizeof(szBuff);
if (
RegQueryValue(
hkStdFileEditing,
"handler",
szBuff,
&cb
) == ERROR_SUCCESS
&& lstrcmpi("nwappobj.dll", szBuff) == 0
) RegDeleteKey(hkStdFileEditing, "handler");
RegCloseKey(hkStdFileEditing);
}


[1] Так как процессор, обычно, только один, то в данный момент времени будет работать только одно приложение. Однако, так как переключение между приложениями осуществляется достаточно быстро, то возникает впечатление одновременной работы нескольких приложений. Эта оговорка не влияет на последующие рассуждения.

[2] В принципе требования могут и нарушаться. Так приложения под Windows 3.x сравнительно легко могут получить доступ к аппаратуре, хотя делать это не рекомендуется. Приложениям Win32 уже значительно сложнее получить доступ — система лучше защищена от таких попыток, особенно Windows NT.

[3] Строго говоря, обычный DOS тоже может работать с различными файловыми системами — для CD‑ROM дисков специально спроектирована своя собственная файловая система (CDFS). При этом надо установить драйвер CD–ROM, обеспечивающий физический доступ к диску, и программу MSCDEX, которая осуществляет работу с дисками в формате CDFS.

[4] Кроме некоторых особых случаев, связанных с обработкой критичных по времени процессов, скажем некоторых операций ввода/вывода, взаимодействия с периферией и пр. Однако обычно такие задачи решаются драйверами устройств, так что приложение об этом опять–же не ведает.

[5] Точнее при уничтожении. Термин “закрытие” в Windows часто имеет другой смысл, в том числе — сворачивание окна в пиктограмму.

[6] В Win32 APIзаголовочный файл windows.h просто включает в себя набор директив #include для включения необходимых заголовочных файлов и директив условной компиляции.

[7] Строка ASCII — строка символов таблицы ASCII, то есть обычный текст. Однако при программировании часто используются строки либо со специальным завершающим символом (в C это байт с кодом 0 — ASCIIZ), либо с указанием длины строки в виде лидирующего байта (ASCIIB) или слова (ASCIIW).