Первые шаги

http://www.firststeps.ru/

Всё для начинающих программистов. На сайте вы найдёте информацию по следующим темам:

  • TASM
  • Html&WEB
  • PHP
  • VRML
  • Java
  • CGI
  • Perl
  • Linux
  • Visual C++
  • Справка WinAPI
  • Visual Basic
  • Visual FoxPro
  • C Sharp & .NET
  • C++ Builder
  • VBA by Step
  • 1C
  • GIS
  • SQL by Step
  • Алгоритмы
  • Безопасность
  • Протоколы
  • MS Office


Авторы сайта

artem.jpg (17465 b)

Каев Артем Геннадьевич (E-mail)

Родился: 13 октября 1972 года.

Московский геологоразведочный техникум. Московская Государственная Геологоразведочная Академия (бывший MГРИ), горный инженер геолог, специализация геоинформатика, математические методы в геологии. В 1996 - 1997 служба в армии. Одиннадцатая отдельная воздушно-десантная бригада. г.Улан-Удэ.

Специализированное обучение: разработка приложений - VC++, геоинформационные системы - ArcInfo.

Верхне-Индигирская геологоразведочная экспедиция, руководитель ВЦ.

С 1 января 2002 года, начальник ГИЦ Верне-Индигирской экспедиции

Увлечений практически нет. Работа и сайт - Первые шаги.

dron.jpg (12417 b)

Кузин Андрей Владимирович (E-mail)

Родился: 9 апреля 1980 года.

Московский Институт Электронной Техники - МИЭТ. Специализация - "Организация и технология защиты информации". Защитил диплом на отлично 7 июня 2002 года, тема "Контроллер защищенного канала передачи данных в сети Ethernet".

Вебмастер сайта "Первые Шаги". Системный администратор сети МЖК "Зеленоград".

vladimir.jpg (13126 b)

Соковиков Владимир Александрович (E-mail)

Родился: 26 марта 1945 года.

Костромской химико-механический техникум. Дальневосточный государственны университет, историк - преподаватель общественных наук. Высшее военное образование. В 1969 -1991 служба в Вооруженных Силах СССР.

Спецализированного обучения не имею. Самостоятельное изучение программирования на ассемблере и С++.

Пенсионер, работаю электромехаником по обслуживанию ведомственной АТС "Definity", телефонной и компьютеной сети учреждения.

Люблю читать фантастику, создавать на ассемблере Windows - программы.


Шаг 1 - Окна Windows и функции доступа к ним

Мы с Вами в этом шаге каснемся работы с окнами в Windows. У каждого окна есть уникальный идентификатор HWND. Этот идентификатор указывает на окно. Окна в Windows можно представить в виде дерева с корнем в DeskTop. Это легко увидеть запустив SPY (см. "Шаг 47 - Как пользоваться SPY").

1.gif (7184 b)

Итак, как и у любого дерева, у дерева окон есть корень. Получить указатель на него можно функцией GetDesktopWindow(), которая вернет HWND корня в виде рабочего стола. Ага начало есть. Дальше как у того богатыря на картинке. Налево, направо или куда. От текущего HWND можно получить HWND либо ребенка, вот так GetWindow(hwnd, GW_CHILD), либо соседа вот так GetWindow(hwnd, GW_HWNDNEXT). И так далее. Дерево господа и алгоритм его обхода. Имея HWND можно получить заголовок окна GetWindowText. Ну пора. Вот код получения имен окон первого уровня.

// GetWindow.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    HWND hwnd;
    char p[100];
    hwnd = GetDesktopWindow();
    hwnd = GetWindow(hwnd, GW_CHILD);
    while (hwnd !=0)
    {
     hwnd = GetWindow(hwnd, GW_HWNDNEXT);
     GetWindowText(hwnd,p,100);
     if (strlen(p)>0)  cout << p << endl;
    }

}
А вот результат работы у меня
GetWindow									// это программа наша !!!!
Source File Properties
GetWindow - Microsoft Visual C++ - [GetWindow.cpp]				// Это я делаю программу :-))))
Step1.htm - -ыюъэюЄ							// Это редактируется страница которую вы читаете
C:\WINDOWS\-рсюўшщ ёЄюы\Step1\Step1.htm - Microsoft Internet Explorer 		// Смотрю на то что пишу
Step1									// каталог с нашим шагом
OLEChannelWnd
OLEChannelWnd
OLEChannelWnd
DDE Server Window
OleMainThreadWndName
-юъЁрЄ 97
OLEChannelWnd
-ряюьшэрэшх
+эфшърЄюЁ срЄрЁхщ
WIN95 RPC Wmsg Window
DDE Server Window
OleMainThreadWndName
RPCSSWindow
OleMainThreadWndName
MS_WebcheckMonitor
Program Manager
Press any key to continue
Загрузить проект | Следующий Шаг
Автор Каев Артем.


Шаг 2 - Запуск почтовой программы

В этом примере для открытия почтовой программы мы используем функцию ShellExecute. Это очень интересная функция. Для её использования необходимо подключить её описание Shellapi.h. Вот её описание:

HINSTANCE ShellExecute(
    HWND hwnd,
    LPCTSTR lpOperation,
    LPCTSTR lpFile,
    LPCTSTR lpParameters,
    LPCTSTR lpDirectory,
    INT nShowCmd
);

Параметров у неё девать некуда и им место в подробностях, но вот главные для lpOperation.

"open"
"print"
"explore"

В lpFile мы указываем файл, вот если написать mailto:, то среагирует Outlook. Да вот и сам код куда яснее. Удачное выполнение возврашает число большее 32, остальные относятся к кодам ошибок.

// Test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "Shellapi.h"

void main()
{
    ShellExecute(0, "Open", "mailto: tt@tts" , "", "", 1);
}
Предыдущий Шаг | Следующий Шаг


Шаг 3 - GetMenu

То, что мы умеем получать HWND окна дарит нам большую власть над этим окном. Теперь имея HWND мы получим доступ к меню окна, например, Калькулятор, который есть в стандартной поставке Windows.

Итак, создаем проект Win32 Console, как Hello Word с именем Getmenu. Вот код.

// Getmenu.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
  HWND hwnd;
  hwnd=FindWindow("SciCalc","Калькулятор");
  if (hwnd!=NULL)
  {
      HMENU hMenu;
      hMenu=GetMenu(hwnd);
      if (hMenu!=NULL)
      {
          int iCount;
          iCount=GetMenuItemCount(hMenu);
          cout << "Menu Item - " << iCount << endl;
      }
      else cout << " Error Loading Menu" << endl;
  }
  else cout << " Error Find Windows" << endl;

}

Как всегда я ищу окно с помошью FindWindow указывая класс окна и имя окна. Где я их взял ? В SPY смотрите сами.

3.gif (4564 b)

Имея HWND мы можем добраться до меню. Для этого есть GetMenu. Если он не NULL, то тут я могу повеселиться на славу. Например, получить количество пунктов GetMenuItemCount. По секрету я могу получать названия, удалять и вставлять свои пункты меню в чужую программу :-)))

Испытавая программу незабудьте запустить калькулятор, а то будете писать письма...

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 4 - Окно Windows на С

В этом шаге мы создадим окно используя только структуры и функции Win Api. Это позволит нам посмотреть как все-таки устроена программа для Windows на другом уровне. Создаем приложение Win 32 Application и далее как Simple application. А вот код:

// СWin.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "windows.h"
#include "windowsx.h"

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,LPARAM);

int APIENTRY WinMain(
        HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        LPSTR lpCmdLine,
        int nCmdShow)
{
    HWND hwnd;
    MSG msg;
    WNDCLASS w;
        memset(&w,0,sizeof(WNDCLASS));
    w.style = CS_HREDRAW | CS_VREDRAW;
    w.lpfnWndProc = WndProc;
    w.hInstance = hInstance;
    w.hbrBackground = GetStockBrush(WHITE_BRUSH);
    w.lpszClassName = "C Windows";
    RegisterClass(&w);
    hwnd = CreateWindow("C Windows","C Windows", WS_OVERLAPPEDWINDOW,
        10,10,600,480,NULL,NULL,hInstance,NULL);
    ShowWindow(hwnd,nCmdShow);
    UpdateWindow(hwnd);
    while(GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wparam,LPARAM lparam)
{
    if (Message == WM_DESTROY )
    {
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd,Message,wparam,lparam);
}

Как видите приложение начинается с функции WinMain. Далее мы заполняем структуру окна WNDCLASS, в которую передаем функцию обработки сообщений w.lpfnWndProc = WndProc; после этого создаем окно CreateWindow, выводим на экран ShowWindow(hwnd,nCmdShow); и запускаем обработчик сообщений. Сначала сообщения попадают на обработку в окно, и если это сообщение закрытия, то if (Message == WM_DESTROY ) прекращает выполнение программы.

Этот код можно компилировать и запускать.

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 5 - GetWindowDC и рабочий стол

Я уже говорил, что HWND это ключ к интерфейсу любой программы. Вот теперь мы воспользуется функцией GetWindowDC, чтобы получить контекст рабочего стола и нарисовать на нем чего-нибудь.

HDC GetWindowDC
(
 HWND hWnd
);

А вот и код:

// TestDeskTop.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "iostream.h"
#include "afxwin.h"

void main()
{
    HWND hwnd;
    hwnd = GetDesktopWindow();
    HDC hdc;
    hdc=GetWindowDC(hwnd);
    int i;
    cin >> i;
    CPen pen(PS_SOLID,4,RGB(255,0,0));
    SelectObject(hdc,pen);
    Ellipse(hdc,-100,-100,100,100);
}

Идея очень простая. Получаем HWND окна, в данном случае рабочего стола. Получем его HDC и пользуясь функциями API в этом контексте творим чего хотим :-)))

Вот так выглядит рабочий стол после работы программы.

5.gif (4400 b)

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 6 - Рисуем в консольном окне

Куда-то делось письмо человека, который спрашивал как можно
нарисовать в консольном приложении.
Вот примерно так. - "Неужели такой сильный язык как С++ не
может это сделать".
Дело далеко не в языке, а в операционной системе. Я думаю это
не только мое мнение. Данный пример можно сделать и на VBA
для Word например :-)))

Итак, как нарисовать чего-нибудь в консольном окне ? Консольное окно такое же окно, как и все остальные. Его нужно найти, получить контекст и рисовать в нем.

// TestConsole.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "afxwin.h"
#include "iostream.h"

void main()
{
    HWND hwnd;
    hwnd=FindWindow("tty","TestConsole");
    int i;
    cin >> i;
    if (hwnd!=NULL)
    {
        HDC hdc;
        hdc=GetWindowDC(hwnd);
        if (hdc!=0)
        {
            CPen pen(PS_SOLID,4,RGB(255,0,0));
            SelectObject(hdc,pen);
            Ellipse(hdc,90,90,120,120);
            int i;
            cin >> i;
        }
        else cout << "Error DC Window" << endl;
    }
    else cout << "Error Find Window" << endl;
}

А вот результат.

6.gif (2216 b)

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 7 - Информация о диске GetVolumeInformation

Нам может понадобиться получить информацию о файловой системе диска. Это делается с помошью GetVolumeInformation. Кроме того эта же функция может получить серийный номер диска. Серийным номером можно воспользоваться, например, привязять программу к конкретному жескому диску :-))). Есть и дополнительная иформация.

Попробуем запрограммировать ????

// TestVolume.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{

    char NameBuffer[MAX_PATH];
    char SysNameBuffer[MAX_PATH];
    DWORD VSNumber;
    DWORD MCLength;
    DWORD FileSF;

    if (GetVolumeInformation("C:\\",NameBuffer, sizeof(NameBuffer),
        &VSNumber,&MCLength,&FileSF,SysNameBuffer,sizeof(SysNameBuffer)))
    {
        cout <<  NameBuffer << endl;
        cout <<  SysNameBuffer << endl;
        cout <<  VSNumber << endl;
    }
}

Вот что выдало у меня по поводу диска C:

WIN98
FAT
860363753
Press any key to continue
Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 8 - Получение сетевого имени WNetGetUser

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

DWORD WNetGetUser(
    LPCTSTR lpName,
    LPTSTR lpUserName,
    LPDWORD lpnLength
);

В случае удачного выполнения функция вернет NO_ERROR, вот пример:

// TestUsert.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    char Name[255];
    char Test[255];
    DWORD size=255;
    if (WNetGetUser(Test,Name,&size)==NO_ERROR)
    {
        cout << Name << endl;
    }
}
Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 9 - Синхронизация файловых операций Mutex

Задача сводится к тому как заставить две программы работать с одним файлом, когда одна программа может писать, а вторая должна читать. Задача как избежать конфликтов при данной ситуации. Создадим два проекта, как Win32 console, один с именем WriteData, а другой с именем ReadData в каталоге TestMutex. Так будет и в прилагаемом проекте.

Код WriteFile:

// WriteData.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "fstream.h"
#include "iostream.h"

void main()
{
    HANDLE hShared = CreateMutex(NULL, TRUE, "WriteData");
    ofstream ofs("d:\\write.txt");
    ofs << "TestDataWrite" << endl;
    ofs.close();
    int i;
    cout << "Press Key and Enter for access to file " << endl;
    cin >> i;
    ReleaseMutex(hShared);
    CloseHandle(hShared);
}

Основа программы функция CreateMutex:

HANDLE CreateMutex(
    LPSECURITY_ATTRIBUTES,	// атрибуты
    BOOL bInitialOwner,	// инициализация
    LPCTSTR lpName		// имя обьекта
);

Теперь весь этот механизм запускается с помошью ReleaseMutex после использования указатель HANDLE нужно закрыть CloseHandle.

Код ReadData:

// ReadData.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "fstream.h"
#include "iostream.h"

void main()
{
    HANDLE hShared = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "WriteData");
    cout << "Wait !!!! Write File Data Proccess " << endl;
    WaitForSingleObject(hShared, INFINITE);
    ifstream ifs("d:\\write.txt");
    char buffer[100];
    ifs >> buffer;
    cout << "Read File Data  -  " << buffer << endl;
    CloseHandle(hShared);
}

Для доступа к Mutex теперь его нужно открыть с тем же именем. И поставить флаг MUTEX_ALL_ACCESS. Функция WaitForSingleObject будет стоять пока доступ не будет получен.

Запустите одновременно две программы. Программа чтения будет ждать пока программа записи не разрешит доступ. Вот примерно так как на экране.

9.gif (4757 b)

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

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 10 - Информация и языке системы GetLocaleInfo

// GetLocale.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    char buffer[255];
    LCID lc=GetSystemDefaultLCID();
    GetLocaleInfo(lc,LOCALE_SENGLANGUAGE,
        buffer,sizeof(buffer));
    cout << buffer << endl;
}

Для получения информации нам необходимо получить идентифкатор системы. Для этого мы используем GetSystemDefaultLCID. После этого мы можем имея этот идентификатор запросить параметры системы используя GetLocaleInfo:

int GetLocaleInfo(
    LCID Locale,	// идентификатор системы
    LCTYPE LCType,	//  тип информации
    LPTSTR lpLCData,	//  указатель на буфер
    int cchData	//  размер буфера
);

Типов информации много. Может быть когда-нибудь опишу в подробностях. А в данном случае я выбрал язык в английском написании - LOCALE_SENGLANGUAGE

Запустите и посмотрите. Вот что у меня появляется:

Russian
Press any key to continue
Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 11 - Информация о типе диска GetDriveType

Для получения информации о типе диска можно использовать GetDriveType эта очень простая функция.

UINT GetDriveType(
    LPCTSTR lpRootPathName	// указатель на строку.
);

А вот так её можно использовать:

// TestGetDriveType.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    if (GetDriveType("F:")==DRIVE_CDROM)
        cout << "CD" << endl;
}

Возвращает она типы дисков:

DRIVE_UNKNOWN	// неизвестен
DRIVE_NO_ROOT_DIR	// нет :-(((
DRIVE_REMOVABLE	// извлекаемый диск
DRIVE_FIXED	// нормальный жеский диск
DRIVE_REMOTE	// удаленный, т.е. сетевой
DRIVE_CDROM	// СD ROM
DRIVE_RAMDISK	// В оперативной памяти

Эта функция позволяет решать многие вопросы типа ?

Какая буква CD, есть ли у меня сетевой диск, сколько и так делее. Метод ? Переберите все диски от А до Я :-)) или если знаете то все, что знаете и посмотрите информацию.

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 12 - Работа с COM и LPT портом CreateFile

Привет.
Подскажи пожалуйста ,где можно найти информацию по
программированию COM порта под win.
В win32 SDK я нашел список функций ,но ни примеров ,ни толкового
описания нет. И еще : можно ли найти под C++Builder такие компоненты?
Или хотя бы ActiveX управлялки?
Зарание благодарен за помощь.
DemonSerj,Feb,2000
mailto:DemonSerj@usa.net

Работать с LPT и COM портом для Windows можно использовав функцию CreateFile. В Windows, как и в DOS остались имена файлов, которые давать нельзя типа:

COM
LPT
CON
AUX
...

Попытка создать файл с таким именем приводит к перенаправлению информации на соответствующий порт или устройство. Вот на этом не всегда удобном свойcтве и основанна работа с устройствами. Надо создать файл с таким именем и выводить в него информацию. Смотрите пример ниже:

// CreateFile.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    HANDLE  hLPT=CreateFile("LPT1",GENERIC_WRITE,0,NULL,
        OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    if (hLPT!=INVALID_HANDLE_VALUE)
    {
        cout << " Ok Open LPT1" << endl;
        char buffer[25];
        memset(buffer,0,sizeof(buffer));
                strcpy(buffer,"Hello LPT ");
         DWORD dw;
        OVERLAPPED ov;
        for (int x=0;x < 3;x++)
            WriteFile(hLPT,buffer,sizeof(buffer),&dw,&ov);
        CloseHandle(hLPT);
    }
    else cout << "Error Open" << endl;
}

Как видите, я создаю файл с именем LPT1 и вывожу туда информацию. Что я получу ?? Зависит от принтера. Я проверял на Epson Stylus 1000. Запускал программу, а потом печатал пустой лист из блокнота. В результате на принтер выводилась строка Hello LPT. Почему я печатал из блокнота пустой лист ?? Дело в том, что у принтера есть буфер и он не напечатает ничего пока этот буфер не переполнится или не поступит команда конец страницы !! Так как я ESC коды этого принтера не помню :-)))) я просто начал печатать из блокнота новый документ, а это подразумевает, что старый надо завершить печатать кстати. Вот он и напечатал.

Таким образом зная протокол обмена между портами и устройствами можно создавать программы, которые будут работать без драйверов или сами драйвера создавать :-)))

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 13 - Именованные каналы (PIPE)

Именованные каналы PIPE используются для гарантированной передачи данных по сети. Создать именованный канал можно только на NT, в операционной среде Windows 95 можно использовать именованный канал только со стороны клиента. Поэтому для проверки данных примеров вам нужен NT. Можно сказать, что это выделенная линия для обмена данными между процессами. В NT можно посмотреть подобные выделенные линии. То есть их количество. Зайдите в Control Panel, выберите Server и щелкните на нем. Появится окно как ниже:

13_1.gif (3467 b)

Пункт Open Named Pipes может быть и не такой. Дело в том, что данным механизмом пользуются многие серьезные приложения, например, MS SQL Server. Мы с Вами создадим две простые консольные программы, которые будут эмулировать клиента и сервера. Итак сервер:

// CreateNamedPipe.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    HANDLE hp;
    hp=CreateNamedPipe("\\\\.\\pipe\\ipctest",PIPE_ACCESS_OUTBOUND,
        PIPE_TYPE_BYTE | PIPE_NOWAIT,1,0,0,NMPWAIT_USE_DEFAULT_WAIT,NULL);
    if (hp!=INVALID_HANDLE_VALUE)
    {
        int i;
        cin >> i;
    }
    else cout << "Error Create Name Pipe " << endl;
}

А теперь клиент:

// CreateFile.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    HANDLE hp;
    hp=CreateFile("\\\\Server\\pipe\\ipctest", GENERIC_READ,
        FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hp!=INVALID_HANDLE_VALUE)
    {
        int i;
        cin >> i;
    }
    else cout << "Error pipe" << endl;
}

Как видите для создание канала надо вызвать функцию CreateNamedPipe, а для клиента создать файл указав сервер Server. Вы должны указывать свой сервер. То есть его имя в домене. А имя \\pipe\\ipctest должно совпадать и в клиенте и в сервере. Это имя канала.

Вот после запуска прогаммы видно, что количество именованных каналов увеличилось на единицу.

13_2.gif (7814 b)

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 14 - Перечисление сервисов NT EnumServicesStatus

В Windows NT есть понятие сервисов. Сервис - это исполняемый объект. Простым языком это модуль или драйвер, но сделанный так, что его работой можно управлять - запускать и останавливать в любое время. Посмотреть существующие сервисы можно здесь - Control Panel -> Services.

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

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

#define SIZE_BUF 4096

void main()
{
    ENUM_SERVICE_STATUS Status[SIZE_BUF];
    DWORD Size = sizeof(Status);
    DWORD Needed = 0;
    DWORD Return = 0;
    DWORD Handle = 0;
    SC_HANDLE Manager;

    Manager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);

    if (Manager!=NULL)
    {
        if (EnumServicesStatus(Manager,SERVICE_WIN32,SERVICE_ACTIVE,
        (LPENUM_SERVICE_STATUS)&Status,Size,&Needed,&Return,&Handle))
        {
            for (unsigned int x=0; x < Return; x++)
                cout << Status[x].lpServiceName << endl;
        }
        else cout << "Error Open Manager " << endl;
    }
    else cout << "Error enum Services" << endl;
}

Давайте попробуем разобраться. Первая функция, которую мы вызываем это OpenSCManager. Эта функция устанавливает связь с менеджером NT ответственным за работу с сервисами. Вот она:

SC_HANDLE OpenSCManager(
    LPCTSTR lpMachineName,	// имя машина
    LPCTSTR lpDatabaseName,	// имя менеджера
    DWORD dwDesiredAccess	// тип доступа
);

Как видите некоторые значения можно устанавливать в NULL. Функция EnumServicesStatus перебирает все сервисы и заносит их в буфер. Но нужно указать менеджера, тип сервисов, буфер, размер буфера и так далее.

А вот результат работы.

14.gif (6174 b)

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 15 - Обнаружение нажатия клавиш

В WIN 32 API есть функция GetKeyState, которая умеет определять нажата клавиша или нет. Вот её описание:

WINUSERAPI SHORT WINAPI
GetKeyState
(
    int nVirtKey
);

А вот её применение. Это программа Win32 Console, которая определяет нажат NumLock или нет.

// GetKeyState.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    if (GetKeyState(VK_NUMLOCK)==1)
        cout << "NumLock ON" << endl;
    else
        cout << "NumLock OFF" << endl;
}

Как видите она использует виртуальные клавиши типа VK_. Если эта клавиша нажата, то вернется 1. Виртуальных клавиш много. То есть они описаны практически все.

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 16 - Программно меняем разрешение экрана

Для изменения разрешения экрана есть специальная функция WIN32 API с именем ChangeDisplaySettings в неё необходимо передать указатель на структуру типа DEVMODE, где указывается желаемое разрешение. Естественно, что Ваш монитор и видеокарта должны это разрешение поддерживать.

// Screen.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"

void main()
{
    DEVMODE dm;
    memset(&dm,0,sizeof(DEVMODE));
    dm.dmSize=sizeof(DEVMODE);
    dm.dmPelsWidth=800;
    dm.dmPelsHeight=600;
    dm.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT|DM_DISPLAYFREQUENCY;
    ChangeDisplaySettings(&dm,CDS_UPDATEREGISTRY);
}
Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 17 - Посылаем сообщение закрытия приложения

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

PostMessage
(
    HWND hwnd,			// дискриптор окна
    UINT message,			// сообщение
    WPARAM wParam = 0, 		// параметры
    LPARAM lParam = 0
);

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

// Post.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
   PostMessage(FindWindow(NULL, "Калькулятор"), WM_QUIT, 0, 0);
}

Соберите программу. Запустите калькулятор, а потом нашу программу. Калькулятор будет закрыт.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 18 - Как узнать имя EXE файла программы

В этом нам может помочь функция GetModuleFileName. Эта функция вернет имя файла и путь. Вот её описание:

DWORD GetModuleFileName(
    HMODULE hModule,	// указатель на модуль
    LPTSTR lpFilename,	// буфер
    DWORD nSize	// размер буфера
);

А вот и пример кода:

// GetFileName.cpp : Defines the entry point for the application.
//

#include "stdafx.h"

int APIENTRY WinMain(HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        LPSTR lpCmdLine,
        int nCmdShow)
{
    char buffer[MAX_PATH];
    GetModuleFileName(hInstance,buffer,MAX_PATH);
    MessageBox(NULL,buffer,"INFO",NULL);
    return 0;
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 19 - Запуск программ WinExec

Запускать внешние программы бывает нужно не часто. Но вот есть такое техническое решение. Я знаком с несколькими программами имеющими понятие горячей связи. То есть вы можете к своим объектам привязать данные из других программ. Например, такой подход есть в ГИС системе ArcView Вы заполняете поле в базе данных именем файла и пишите скрипт на языке AVENUE, в котором вызываете программу и передаете в параметры имя файла для открытия. Идея хороша тем, что позволяет внутри одной программы связать много разных данных.

Реализуется данная возможность на основе функции Windows с названием WinExec. Вот её описание.

UINT WinExec(
    LPCSTR lpCmdLine,	// строка с именем программы
    UINT uCmdShow	// вид вывода на экран в смысле
            //скрытая или нормальная и так далее
);

А вот и код с примером, который запускает обычный калькулятор:

// ExecTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    cout << WinExec("c:\\windows\\calc.exe",SW_SHOW) << endl;
}

Да эта функция реализованна только для совместимости с Win 16 приложениями, а приложения Win 32 должны реализовывать данную возможность через CreateProcess.

Результатом этой функции может быть несколько кодов, но если код возврата больше 31, то функция выполнена успешно. Вот некоторые коды:

ERROR_BAD_FORMAT		формат exe файла неверен
ERROR_FILE_NOT_FOUND	файл не найден
ERROR_PATH_NOT_FOUND	путь не найден
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 20 - Узнаем специальные папки Windows

У Windows'а целая куча специальных папок. Ну, например, папка под принтеры или папка под рабочий стол. Конечно можно зайти в каталог Windows и посмотреть где и что. Только во всех этих рассуждениях есть одно слабое место. Вы не можете заранее предполагать где эти папки находятся и как называются. Если не верите, то почитайте Windows 95 Resource там есть такое понятие как системная политика, которая реализуется с помощью программы PolEdit, которая позволяет устанавливать эти папки самому под конкретного пользователя. Раз дела обстоят так плохо, то должен быть механизм определения этих папок. И он есть. Можно воспользоваться функцией SHGetSpecialFolderLocation, которая и даст Вам возможность узнать их. Смотрим пример:

#include "stdafx.h"
#include "Shlobj.h"
#include "iostream.h"

void main()
{
    LPITEMIDLIST pidl;
    char buffer[256];

    SHGetSpecialFolderLocation(NULL,CSIDL_RECENT  ,&pidl);
    if (pidl==NULL)
    {
        cout << "Error" << endl;
        return;
    }
    SHGetPathFromIDList(pidl,buffer);
    cout << buffer << endl;
}

В функцию SHGetSpecialFolderLocation передается константа, которая характеризует имя какой папки нужно получить и возвращает указатель на данные (pidl), на основе которого используя функцию SHGetPathFromIDList можно получить само имя. Вот описания функций:

WINSHELLAPI HRESULT WINAPI SHGetSpecialFolderLocation
(
    HWND hwndOwner,
    int nFolder,
    LPITEMIDLIST *ppidl
);

WINSHELLAPI BOOL WINAPI SHGetPathFromIDList
(
    LPCITEMIDLIST pidl,
    LPSTR pszPath
);
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 21 - Создаем LOG файл SetupInitializeFileLog

Ну давайте сразу глянем код:

// TestLog.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "afxwin.h"
#include "setupapi.h"
#include "iostream.h"

#pragma comment(lib,"setupapi.lib")

void main()
{
    HSPFILELOG hp;
    hp=SetupInitializeFileLog("my.log",SPFILELOG_FORCENEW);
    if (hp!=INVALID_HANDLE_VALUE)
    {
    }
    else
        cout << "Error Create File Log" << endl;
}

Сначала мы создаем переменную типа HSPFILELOG. Она определена так:

typedef PVOID HSPFILELOG;

В нее и будет помещен результат выполнения функции SetupInitializeFileLog куда передается имя LOG файла и флаг. Это флаг SPFILELOG_FORCENEW, говорит о том, что перезаписывать файл если он есть. Какие еще флаги есть ???

SPFILELOG_SYSTEMLOG Использовать системный LOG файл
SPFILELOG_FORCENEW  Перезаписывать если есть
SPFILELOG_QUERYONLY Только для запроса информации

Ну и естественно, что если результат не равен INVALID_HANDLE_VALUE все нормально. Кстати знаете зачем вот эти флаги ? Ну во-первых системный LOG нельзя перезаписывать. А флаг на выборку - это для продолжения инсталляции после прерывания. Сталкивались в Windows при поиске оборудования ??? Вот примерно тоже самое сделать можете и Вы.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 22 - Вызов функций из DLL - GetModuleHandle и GetProcAddress

Итак, мы с Вами все время в разделе MFC пользуемся DLL только это использование скрыто за LIB и H файлами. Но ведь любой DLL можно вызывать и динамически. Вот пример вызова функции Win 32 API для удаления файлов - DeleteFile. Тип приложения Win32 Application.

// TestAPI.cpp : Defines the entry point for the application.
//

#include "stdafx.h"

typedef BOOL (WINAPI *hDeleteFunc)(LPSTR lpStr);

int APIENTRY WinMain(HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        LPSTR lpCmdLine,
        int nCmdShow)
{
    hDeleteFunc hDelete=NULL;
    HMODULE hKernel32=NULL;
    hKernel32=GetModuleHandle("Kernel32");
    if (hKernel32==NULL)
    {
        MessageBox(NULL,"Error Load Kernel32","Error",MB_OK);
        return FALSE;
    }
    hDelete=(hDeleteFunc)GetProcAddress(hKernel32,"DeleteFileA");
    if (hDelete==NULL)
    {
        MessageBox(NULL,"Error Load hDelete","Error",MB_OK);
        return FALSE;
    }
    if ((*hDelete)((LPSTR)"c:\\1.txt"))
        MessageBox(NULL,"Deleted","Message",MB_OK);
    else
        MessageBox(NULL,"Not Deleted","Message",MB_OK);

    return 0;
}

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

HMODULE GetModuleHandle
(
    LPCTSTR lpModuleName	// Имя модуля
);

Эта функция возврашает указатель на модуль, если он загружен. Но Kernel32.Dll - это системная библиотека Windows и она находится в памяти всегда. Если это не так, то нужно использовать LoadLibrary:

HINSTANCE LoadLibrary
(
    LPCTSTR lpLibFileName	// Имя файла DLL
);

Вооружившись указателем на модуль мы можем получить адрес функции с помощью GetProcAddress:

FARPROC GetProcAddress
(
    HMODULE hModule,		// указатель на модуль
    LPCSTR lpProcName		// имя функции
);
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 23 - IMAGE_DOS_HEADER

Эта структура описывает заголовок MS DOS для программ Windows, которые имеют обозначение PE - Portable Executable. Данный заголовок сделан для того, чтобы программы созданные для Windows не запускались из MS DOS. И этого не происходит. Вместо запуска вы видите примерно вот что:

This program cannot be run in DOS mode
Эта программа не может быть запущена в DOS

Общая структура начала программы для Windows выглядит так:

MS-DOS MZ Сигнатура и заголовок
MS-DOS MS DOS программа
PE File PE Сигнатура и заголовок
......

Структура IMAGE_DOS_HEADER как раз и описывает этот заголовок. Этот заголовок используется начиная с MS DOS 2.0. Он занимает 64 байта и вот его описание из WinNT.h:

typedef struct _IMAGE_DOS_HEADER {
    USHORT e_magic;		// Сигнатура заголовка
    USHORT e_cblp;		// количество байт на последней странице файла
    USHORT e_cp;		// количество страниц в файле
    USHORT e_crlc;		// Relocations
    USHORT e_cparhdr;		// Размер заголовка в параграфах
    USHORT e_minalloc;		// Минимальные дополнительные параграфы
    USHORT e_maxalloc;		// Максимальные дополнительные параграфы
    USHORT e_ss;		// начальное  относительное значение регистра SS
    USHORT e_sp;		// начальное значение регистра SP
    USHORT e_csum;		// контрольная сумма
    USHORT e_ip;		// начальное значение регистра IP
    USHORT e_cs;		// начальное относительное значение регистра CS
    USHORT e_lfarlc;		// адрес в файле на таблицу переадресации
    USHORT e_ovno;		// количество оверлеев
    USHORT e_res[4];		// Зарезервировано
    USHORT e_oemid;		// OEM идентифкатор
    USHORT e_oeminfo;		// OEM информация
    USHORT e_res2[10];		// Зарезервировано
    LONG   e_lfanew;		// адрес в файле нового .exe заголовка (PE)
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

Ну давайте попробуем поработать с этой структурой. Посмотрим, что у нас в заголовке user32.dll. Вот приложение:

// TestAPI.cpp : Defines the entry point for the application.
//

#include "stdafx.h"

int APIENTRY WinMain(HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        LPSTR lpCmdLine,
        int nCmdShow)
{
    HMODULE hUser32=NULL;
    hUser32=GetModuleHandle("user32");

    if (hUser32==NULL)
    {
        MessageBox(NULL,"Error Load User32","Error",MB_OK);
        return FALSE;
    }

    PIMAGE_DOS_HEADER pDOSHead;
    pDOSHead = (PIMAGE_DOS_HEADER)hUser32;

    if ( pDOSHead->e_magic != IMAGE_DOS_SIGNATURE )
    {
        MessageBox(NULL,"Error Dos Header signature MZ","Error",MB_OK);
        return FALSE;
    }
    return TRUE;
}

Как видите мы получаем модуль. Начало этого модуля - это заголовок MS DOS. Для того, чтобы убедиться, что все правильно мы проверяем сигнатуру MS DOS, которая для EXE файлов должна быть MZ. Сигнатуры описаны в файле WinNt.h:

#define IMAGE_DOS_SIGNATURE		0x4D5A		// MZ
#define IMAGE_OS2_SIGNATURE		0x4E45		// NE
#define IMAGE_OS2_SIGNATURE_LE	0x4C45		// LE
#define IMAGE_NT_SIGNATURE		0x50450000	// PE00

Поле из структуры и сравниваем с одной из этих сигнатур. Заголовок это MS DOS или нет. Если да, то спокойно можно пользоваться полями структуры для получения дополнительной информации.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 24 - PIMAGE_NT_HEADERS

В прошлом шаге мы научились получать заголовок MS DOS. За ним следует MS DOS Stub, то есть заглушка MS DOS, а за ней PE заголовок, который описывается структурой PIMAGE_NT_HEADERS. Для того, чтобы добраться до PE заголовка в структуре MS DOS есть поле со смещением до этого заголовка.

typedef struct _IMAGE_DOS_HEADER
{
    ......
    LONG  e_lfanew;	// адрес в файле нового .exe заголовка (PE)
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

Нам надо научиться вычислять смещение до этого заголовка. Создадим для этого макрос.

#define NTSIGNATURE(a) ((LPVOID)((BYTE *)a + ((PIMAGE_DOS_HEADER)a)->e_lfanew))

И получим заголовок PE.

// TestAPI.cpp : Defines the entry point for the application.
//

    ......
    if ( pDOSHead->e_magic != IMAGE_DOS_SIGNATURE )
    {
        MessageBox(NULL,"Error Dos Header signature MZ","Error",MB_OK);
        return FALSE;
    }

    PIMAGE_NT_HEADERS pPEHeader;
    pPEHeader=(PIMAGE_NT_HEADERS) NTSIGNATURE(pDOSHead);

    return TRUE;
}

Теперь нужно проверить сигнатуру, что это заголовок именно PE.

if ( pPEHeader->Signature != IMAGE_NT_SIGNATURE )
{
    MessageBox(NULL,"Error PE Header signature PE","Error",MB_OK);
    return FALSE;
}

Давайте посмотрим, что еще есть в этой структуре.

typedef PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS;

typedef struct _IMAGE_NT_HEADERS
{
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

Как видите первое поле это сигнатура, которая должна быть PE, а потом ссылка еще на две структуры.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 25 - IMAGE_FILE_HEADER

В прошлом шаге мы получили ссылку на структуру PIMAGE_NT_HEADERS, которая включает две структуры. Одна из них IMAGE_FILE_HEADER. Вот так ее мы получим.

......
    if ( pPEHeader->Signature != IMAGE_NT_SIGNATURE )
    {
        MessageBox(NULL,"Error PE Header signature PE","Error",MB_OK);
        return FALSE;
    }

    IMAGE_FILE_HEADER FileHeader;
    FileHeader=(IMAGE_FILE_HEADER) pPEHeader->FileHeader;

    return TRUE;
}

Что находится в этой структуре ??? Вот ее описание.

typedef struct _IMAGE_FILE_HEADER
{
    USHORT  Machine;
    USHORT  NumberOfSections;
    ULONG   TimeDateStamp;
    ULONG   PointerToSymbolTable;
    ULONG   NumberOfSymbols;
    USHORT  SizeOfOptionalHeader;
    USHORT  Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

#define IMAGE_SIZEOF_FILE_HEADER 20

Последнее определение - это ее размер. Что мешает сделать нам sizeof я не понимаю. Наверно лучше этим размером не пользоваться. Первое поле Machine говорит нам о том, для какого процессора программа. Что там может быть ??? Ну, например:

Intel
MIPS
Alpha
IBM PowerPC
и так далее.

Вот мы и проверим:

......
    IMAGE_FILE_HEADER FileHeader;
    FileHeader=(IMAGE_FILE_HEADER) pPEHeader->FileHeader;

    if (FileHeader.Machine!=IMAGE_FILE_MACHINE_I386)
    {
        MessageBox(NULL,"Error Not 386 Proccesor","Error",MB_OK);
        return FALSE;
    }

    return TRUE;
}

Отсюда напрашивается интересный вывод. У меня стоит Windows 98 на процессоре Pentium 200MMX. А операционная система скомпилирована для команд 386. Значит она не использует новые классные команды процессора Pentium. То есть ядро операционной системы их не использует. Следующее поле это NumberOfSections. Это количество заголовков сегментов в исполнимом файле. Сегменты расположены в файле последовательно и это число позволяет опеределить когда они закончатся. В поле TimeDateStamp находится время создания модуля компоновщиком. Только это время хитрое. Это число секунд, которые прошли от полночи 1 января, 1970, по Greenwich (Англия). Поле Characteristics содержит признак наличия отладочной информации. Дело в том, что отладочная информация может находиться как в самом PE файле, так и в отдельном .DBG или вообще ее может на быть. Все это описано в этом поле.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 26 - IMAGE_OPTIONAL_HEADER32

В позапрошлом шаге мы получили ссылку на структуру PIMAGE_NT_HEADERS, которая включает две структуры. Одна из них IMAGE_FILE_HEADER. С ней мы познакомились. Вторая структура - это IMAGE_OPTIONAL_HEADER32. Вот так ее мы получим:

    ......
    if (FileHeader.Machine!=IMAGE_FILE_MACHINE_I386)
    {
        MessageBox(NULL,"Error Not 386 Proccesor","Error",MB_OK);
        return FALSE;
    }

    IMAGE_OPTIONAL_HEADER32 OptionHeader;
    OptionHeader = (IMAGE_OPTIONAL_HEADER32) pPEHeader->OptionalHeader;

    return TRUE;
}

Эта структура довольна большая. Вот ее описание:

typedef struct _IMAGE_OPTIONAL_HEADER {
//
// стандартные поля
//

    WORD    Magic;
    BYTE    MajorLinkerVersion;
    BYTE    MinorLinkerVersion;
    DWORD   SizeOfCode;
    DWORD   SizeOfInitializedData;
    DWORD   SizeOfUninitializedData;
    DWORD   AddressOfEntryPoint;
    DWORD   BaseOfCode;
    DWORD   BaseOfData;

//
// NT дополнительные поля.
//

    DWORD   ImageBase;
    DWORD   SectionAlignment;
    DWORD   FileAlignment;
    WORD    MajorOperatingSystemVersion;
    WORD    MinorOperatingSystemVersion;
    WORD    MajorImageVersion;
    WORD    MinorImageVersion;
    WORD    MajorSubsystemVersion;
    WORD    MinorSubsystemVersion;
    DWORD   Win32VersionValue;
    DWORD   SizeOfImage;
    DWORD   SizeOfHeaders;
    DWORD   CheckSum;
    WORD    Subsystem;
    WORD    DllCharacteristics;
    DWORD   SizeOfStackReserve;
    DWORD   SizeOfStackCommit;
    DWORD   SizeOfHeapReserve;
    DWORD   SizeOfHeapCommit;
    DWORD   LoaderFlags;
    DWORD   NumberOfRvaAndSizes;
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

Чего здесь только не содержится относительно модуля. Куча всякой информации. Все ее мы рассматривать пока не будем. Я скажу к чему я веду. Я веду к тому, чтобы вычислить адрес конкретной экспортируемой функции из модуля User32.Dll. Зачем ??? Узнаем потом. А пока я хочу добраться до этого адреса через структуру заголовков модулей. Нас интересует IMAGE_DATA_DIRECTORY. Это массив записей о каталогах с информацией.

//
// Directory format.
//

typedef struct _IMAGE_DATA_DIRECTORY {
    DWORD   VirtualAddress;
    DWORD   Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES    16

Как видите этих каталогов 16. Вот они:

// Каталоги данных
// Каталог экспортируемых объектов
#define IMAGE_DIRECTORY_ENTRY_EXPORT         0
// Каталог импортируемых объектов
#define IMAGE_DIRECTORY_ENTRY_IMPORT         1
// Каталог ресурсов
#define IMAGE_DIRECTORY_ENTRY_RESOURCE       2
// Каталог исключений
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION      3
// Каталог безопасности
#define IMAGE_DIRECTORY_ENTRY_SECURITY       4
// Таблица переадресации
#define IMAGE_DIRECTORY_ENTRY_BASERELOC      5
// Отладочный каталог
#define IMAGE_DIRECTORY_ENTRY_DEBUG          6
// Строки описания
#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT      7
// Машинный значения (MIPS GP)
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR      8
// Каталог TLS (Thread local storage - локальная память потоков)
#define IMAGE_DIRECTORY_ENTRY_TLS            9
// Каталог конфигурации загрузки
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG    10
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT    11
// таблица адресов импорта
#define IMAGE_DIRECTORY_ENTRY_IAT            12
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT   13
// информация COM объектов
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14

Все импортируемые объекты находятся в каталоге IMAGE_DIRECTORY_ENTRY_IMPORT. Там же находится и функция ExitWindowEx, которая перегружает Ваш компьютер :-)

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 27 - Каталог IMAGE_DIRECTORY_ENTRY_EXPORT и истинное имя DLL

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

Сейчас нам интересен раздел IMAGE_DIRECTORY_ENTRY_EXPORT, в котором находится список экспортированных функций. Этот каталог типичен для DLL и в нем обычно находятся ссылки на функции, которые DLL предоставляет системе. Но для начала нам нужно создать макрос, который поможет нам получать адреса в памяти, так как структуры полны всяких ссылок. Этот макрос такой.

#define MakePtr(Type, Base, Offset) ((Type)(DWORD(Base) + (DWORD)(Offset)))

Каталогу IMAGE_DIRECTORY_ENTRY_EXPORT соответствует структура IMAGE_EXPORT_DIRECTORY.

typedef struct _IMAGE_EXPORT_DIRECTORY
{
    DWORD   Characteristics;
    DWORD   TimeDateStamp;
    WORD    MajorVersion;
    WORD    MinorVersion;
    DWORD   Name;
    DWORD   Base;
    DWORD   NumberOfFunctions;
    DWORD   NumberOfNames;
    DWORD   AddressOfFunctions;
    DWORD   AddressOfNames;
    DWORD   AddressOfNameOrdinals;
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

Назначения этих полей такие:

  • Поле Characteristics является неиспользуемым и обычно 0.
  • TimeDateStamp хранит время создания таблицы.
  • MajorVersion и MinorVersion часто устанавливаются в 0.
  • Name имя DLL, как 0-законченная строка ASCII. Имя необходимо в случае, если DLL файл переименован.
  • NumberOfFunctions число экспортируемых функций.
  • NumberOfNames число экспортируемых названий.
  • AddressOfFunctions массив точек входа.

Давайте пока на этом остановимся. И попробуем получить ссылку на структуру IMAGE_EXPORT_DIRECTORY и посмотреть имя DLL дабы убедиться, что ссылку на эту структуру мы получили правильно.

......
IMAGE_OPTIONAL_HEADER32 OptionHeader;
OptionHeader = (IMAGE_OPTIONAL_HEADER32) pPEHeader->OptionalHeader;

PIMAGE_EXPORT_DIRECTORY pImportDesc=NULL;
pImportDesc = MakePtr(PIMAGE_EXPORT_DIRECTORY,hUser32,
    pPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);

char *p;
p=MakePtr(char*,hUser32,pImportDesc->Name);
MessageBox(NULL,p,"Info",MB_OK);
return TRUE;

На экран должно быть выведено USER32.DLL. Это имя DLL, которое находится внутри. И оно совпадает с именем в файловой системе. Microsoft нас не обманула.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 28 - Список функций из DLL AddressOfNames

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

В структуре IMAGE_DIRECTORY_ENTRY_EXPORT есть ссылки на три массива. Один из этих массивов ссылается на данные с именами функций:

typedef struct _IMAGE_EXPORT_DIRECTORY
{
    ......
    DWORD   AddressOfFunctions;
    DWORD   AddressOfNames;	// массив указателей на имена функций
    DWORD   AddressOfNameOrdinals;
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

Итак, сейчас давайте создадим программу, которая будет выводить в файл список всех функций из модуля user32.dll. Сначала создадим ссылку на библиотеку работы с потоками:

// TestAPI.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "fstream.h"
.......

А теперь новый код:

    ......
    PIMAGE_EXPORT_DIRECTORY pImportDesc=NULL;
    pImportDesc = MakePtr(PIMAGE_EXPORT_DIRECTORY,hUser32,
    pPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);

    PCSTR *l_ppszName = MakePtr(PCSTR*,pImportDesc->AddressOfNames, hUser32);
    DWORD x=pImportDesc->NumberOfNames;

    ofstream ofs("rez.txt");

    for (DWORD i=0;i<x;i++)
    {
        char *p=MakePtr(char*,*l_ppszName,hUser32);
        ofs << p << endl;
        l_ppszName++;
    }

    ofs.close();

    return TRUE;
}

Кстати эта программа тестировалась как на Windows 98, так и на Windows 2000. Были получены интересные выводы, которые я расскажу в следующем шаге. Ниже я приведу полный код программы, так как долго дописывал кусочки и Вы могли запутаться. Если Вы начали смотреть с этого шага, то прочитайте все предыдущие для лучшего понимания. Результат работы будет в файле rez.txt:

ActivateKeyboardLayout
AdjustWindowRect
AdjustWindowRectEx
AlignRects
AnimateWindow
AnyPopup
AppendMenuA
AppendMenuW
ArrangeIconicWindows
AttachThreadInput
......

Ну и полный код

// TestAPI.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "fstream.h"

#define NTSIGNATURE(a) ((LPVOID)((BYTE *)a + ((PIMAGE_DOS_HEADER)a)->e_lfanew))
#define MakePtr(Type, Base, Offset) ((Type)(DWORD(Base) + (DWORD)(Offset)))

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    HMODULE hUser32=NULL;
    hUser32=GetModuleHandle("user32");
    if (hUser32==NULL)
    {
        MessageBox(NULL,"Error Load User32","Error",MB_OK);
        return FALSE;
    }

    PIMAGE_DOS_HEADER pDOSHead;
    pDOSHead = (PIMAGE_DOS_HEADER)hUser32;

    if ( pDOSHead->e_magic != IMAGE_DOS_SIGNATURE )
    {
        MessageBox(NULL,"Error Dos Header signature MZ","Error",MB_OK);
        return FALSE;
    }

    PIMAGE_NT_HEADERS pPEHeader;
    pPEHeader=(PIMAGE_NT_HEADERS) NTSIGNATURE(pDOSHead);

    if ( pPEHeader->Signature != IMAGE_NT_SIGNATURE )
    {
        MessageBox(NULL,"Error PE Header signature PE","Error",MB_OK);
        return FALSE;
    }

    IMAGE_FILE_HEADER FileHeader;
    FileHeader=(IMAGE_FILE_HEADER) pPEHeader->FileHeader;

    if (FileHeader.Machine!=IMAGE_FILE_MACHINE_I386)
    {
        MessageBox(NULL,"Error Not 386 Proccesor","Error",MB_OK);
        return FALSE;
    }

    IMAGE_OPTIONAL_HEADER32 OptionHeader;
    OptionHeader=(IMAGE_OPTIONAL_HEADER32) pPEHeader->OptionalHeader;

    PIMAGE_EXPORT_DIRECTORY pImportDesc=NULL;
    pImportDesc = MakePtr(PIMAGE_EXPORT_DIRECTORY,hUser32,
        pPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);

    PCSTR *l_ppszName = MakePtr(PCSTR*,pImportDesc->AddressOfNames, hUser32);
    DWORD x=pImportDesc->NumberOfNames;

    ofstream ofs("rez.txt");
    for (DWORD i=0;i<x;i++)
    {
        char *p=MakePtr(char*,*l_ppszName,hUser32);
        ofs << p << endl;
        l_ppszName++;
    }
    ofs.close();
    return TRUE;
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 29 - Сравнение USER32 для Windows 98 и Windows 2000

На основе созданной нами программы в прошлом шаге я сравнил набор функций USER32 для Win98 и Win2000. Выводы такие.

Часть недокументированных функций в Windows 2000 больше не живет. Вот один из примеров.

Win 98			Win2000
......
CharNextA			CharNextA
CharNextExA		CharNextExA
CharNextExW
CharNextW			CharNextW
CharPrevA			CharPrevA
CharPrevExA		CharPrevExA
CharPrevExW
......

Функция CharNextExW в MSDN для Visual Studio 6.0 не описана и исчезла в Win 2000. Это случай не единственный. Ряд функций изчез.

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

Win 98				Win2000
......
CreateDesktopW			CreateDesktopW
CreateDialogIndirectParamA		CreateDialogIndirectParamA
                CreateDialogIndirectParamAorW
CreateDialogIndirectParamW		CreateDialogIndirectParamW
CreateDialogParamA			CreateDialogParamA
......

Так вот в Win98 функций 648, а в Win2000 695. С учетом того, что из API функции были удалены. Вывод не пользуйтесь недокументированными функциями ради бога.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 30 - VirtualProtect

Эта функция устанавливает атрибуты на блоки памяти.

BOOL VirtualProtect
(
    LPVOID lpAddress,		// адрес региона для установки флага
    DWORD dwSize,		// размер региона
    DWORD flNewProtect,	// флаг
    PDWORD lpflOldProtect	// адрес для сохранения старых флагов
);

Какие бывают флаги ???

#define PAGE_NOACCESS          0x01
#define PAGE_READONLY          0x02
#define PAGE_READWRITE         0x04
#define PAGE_WRITECOPY         0x08
#define PAGE_EXECUTE           0x10
#define PAGE_EXECUTE_READ      0x20
#define PAGE_EXECUTE_READWRITE 0x40
#define PAGE_EXECUTE_WRITECOPY 0x80
#define PAGE_GUARD            0x100
#define PAGE_NOCACHE          0x200

Я думаю, что имена их более менее понятны. Нет доступа или только для чтения. Давайте попробуем.

// TestPrivate.cpp : Defines the entry point for the application.
//
#include "stdafx.h"

int APIENTRY WinMain(HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        LPSTR lpCmdLine,
        int nCmdShow)
{
    DWORD* dwPointer;
    DWORD old;
    dwPointer =new DWORD;
    *dwPointer=2;

    if (VirtualProtect(dwPointer, sizeof(DWORD), PAGE_READONLY, &old))
    {
        MessageBox(NULL,"Protected","Info",MB_OK);
    }

    //*dwPointer=10; // Error Protected

    DWORD test;
    test=*dwPointer;

    if (VirtualProtect(dwPointer, sizeof(DWORD), old, &old))
    {
        MessageBox(NULL,"Not Protected","Info",MB_OK);
    }

    *dwPointer=*dwPointer+10;
    delete dwPointer;
    return 0;
}

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

//*dwPointer=10; // Error Protected.

Что будет догадываетесь ? Windows вам про незаконные операции расскажет.

Пользоваться этой функцией нельзя в диапазоне:

0xBFFFFFFF
0x80000000

Кстати она BOOL и если Вам не удастся поменять атрибуты памяти, то можно будет это обработать. Этот пример хорошо работает под Windows9x для NT я не смотрел и не проверял.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 31 - Программа, которая не удаляется из списка задач

Программа довольно простая. Вот ее код:

// TestProccess.cpp : Defines the entry point for the application.
//

#include "stdafx.h"

int APIENTRY WinMain(HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        LPSTR lpCmdLine,
        int nCmdShow)
{
    while (true)
    {
        MessageBox(NULL,"dfd","dsgs",MB_OK);
    }
}

При всей ее простоте Вы не сможете удалить ее из списка, так как программы под таким именем не будет. Будет только имя диалогового окна. Снимать это окно бесполезно, так как сразу же появится новое. Вот так это выглядит в списке задач.

31.gif (4029 b)

Вывод то простой, мы не можем видеть список всех задач стандартными средствами Windows 98.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 32 - Сканируем список процессов

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

Итак, давайте создадим приложение на базе MFC AppWizard и как Dialog Based. Поместим на диалог кнопку и элемент управления ListBox, который свяжем с помощью ClassWizard с переменной m_List1 типа Control и напишем код реакции на нажатие кнопки:

// ScanProcessDlg.cpp : implementation file
//

#include "stdafx.h"
#include "ScanProcess.h"
#include "ScanProcessDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#include "tlhelp32.h"

......

void CScanProcessDlg::OnScan()
{
    m_List1.ResetContent();
    HANDLE hSnap;
     hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnap == NULL)
    {
        AfxMessageBox("Error Load ToolHelp");
    }
    PROCESSENTRY32 proc;
    if (Process32First(hSnap, &proc))
    {
        m_List1.AddString(proc.szExeFile);
        while (Process32Next(hSnap, &proc))
        {
        m_List1.AddString(proc.szExeFile);
        }
    }
}

В заголовочном файле tlhelp32.h находятся описания функций.

Если вы посмотрите результат работы этой программы, то увидите, что процессов намного больше. В том числе и сможете увидеть процессы, которые не видели в прошлом шаге.

32.gif (4993 b)

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 33 - Win98 как NT. Убиваем процесс

Итак, мы с Вами получили список процессов. Теперь на диалоговую панель добавим новую кнопку Terminate Process. Если в списке выделен процесс, то по нажатию на эту кнопку процесс будет удален. Вот код:

void CScanProcessDlg::OnTernimate()
{
    int inIndex;
    inIndex=m_List1.GetCurSel();
    if (inIndex!=LB_ERR)
    {
        CString csExName;
        m_List1.GetText(inIndex,csExName);
        HANDLE hSnap;
         hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if (hSnap == NULL)
        {
            AfxMessageBox("Error Load ToolHelp");
        } else {
            PROCESSENTRY32 proc;
            if (Process32First(hSnap, &proc))
            {
                if (csExName==proc.szExeFile)
                    TerminateProcess(hSnap,0);
                while (Process32Next(hSnap, &proc))
                {
                    if (csExName==proc.szExeFile)
                    {
                        HANDLE ProcessHandle=NULL;
                        ProcessHandle = OpenProcess(SYNCHRONIZE,
                            TRUE, proc.th32ProcessID);
                        if (ProcessHandle!=NULL)
                        {
                            TerminateProcess(ProcessHandle,0);
                            CloseHandle(ProcessHandle);
                            Sleep(5000);
                            OnScan();
                        }
                        else
                            AfxMessageBox("Not Open Process");
                    }
                }
                CloseHandle(hSnap);
            }
        }
    } else AfxMessageBox("Select Process");
}

Сначала проверяем выбран ли элемент списка if (inIndex!=LB_ERR). Если выбран пробегаем по процессам. Код повторяется как при сканировании процесса. Конечно можно было создать массив при сканировании. Но процесс дело тонкое, то он есть, а то его нет. Лучше на мой взгляд просканировать еще раз. Если его находим, то открываем с помощью функции OpenProcess(). Дальше спокойно вызываем TerminateProcess.

HANDLE OpenProcess
(
    DWORD dwDesiredAccess,	// флаг доступа
    BOOL bInheritHandle,	// флаг наследования
    DWORD dwProcessId		// идентификатор процесса
);

Идентификатор процесса мы берем из структуры PROCESSENTRY32 - это переменная, которая заполняется при запуске.

BOOL TerminateProcess(
    HANDLE hProcess,	// Указатель процесса
    UINT uExitCode	// Код возврата процесса
);

Задержку я сделал для того, чтобы обновить список через некоторое время, так как удаление процесса не моментальное дело. Программу я испытывал на Windows 98. Удаляет все процессы кроме Kernel :) Оно и понятно, сам себя удалять не будешь. При этом помните шаг "Шаг 31 - Программа, которая не удаляется из списка задач". Отсюда удалить ее можно и это получается. Кроме того удалить можно и процесс оболочки. Все работает как в NT. Отсюда рождается много интересных вещей. Например, можно выяснить почему тормозит Windows. Многие процессы просто не нужны для работы. Попробуйте поудаляйте.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 34 - Сканируем модули

Продолжаем изучать возможности ToolHelp.Dll. Мы так же работаем с проектом, который создавали ранее. Наша задача теперь просмотреть модули загруженные в память. Создаем ScanModule кнопку на форме. Вот как это будет выглядеть:

34.gif (6086 b)

А вот и код функции:

void CScanProcessDlg::OnScanModule()
{
    m_List1.ResetContent();
    HANDLE hSnap;
    hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0);
    if (hSnap == NULL)
    {
        AfxMessageBox("Error Load ToolHelp");
    }
    else
    {
    MODULEENTRY32 mod;
    if (Module32First(hSnap, &mod))
    {
        m_List1.AddString(mod.szExePath);
        while (Module32Next(hSnap, &mod))
        {
        m_List1.AddString(mod.szExePath);
        }
    }
    CloseHandle(hSnap);
    }
}

Как видите существенных изменений в логике нет. Поменяли флаг TH32CS_SNAPMODULE и стали использовать новые функции Module32First() и Module32Next() связанные со структурой MODULEENTRY32. Вообще-то модули привязаны к процессам. Но пока мы просто их поискали. Давайте изменим код для того, чтобы найти модули связанные с определенным процессом. ВНИМАНИЕ код написан для демонстрации идеи на данный момент. То есть многие вещи надо было бы выделить в отдельные процедуры, например, SearсhProcess. Идея такая. Как зная процесс найти связанные с ним DLL ?

void CScanProcessDlg::OnScanModule()
{
    int inIndex;
    inIndex=m_List1.GetCurSel();
    if (inIndex!=LB_ERR)
    {
        CString csExName;
        m_List1.GetText(inIndex,csExName);
        HANDLE hSnap1;
         hSnap1 = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if (hSnap1 == NULL)
        {
            AfxMessageBox("Error Load ToolHelp");
        }
        else
        {
            PROCESSENTRY32 proc;
            if (Process32First(hSnap1, &proc))
            {
                while (Process32Next(hSnap1, &proc))
                {
                    if (csExName==proc.szExeFile)
                    {
                        m_List1.ResetContent();
                        HANDLE hSnap;
                         hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,
                        proc.th32ProcessID);
                        if (hSnap == NULL)
                        {
                            AfxMessageBox("Error Load ToolHelp");
                        }
                        else
                        {
                            MODULEENTRY32 mod;
                            if (Module32First(hSnap, &mod))
                            {
                                m_List1.AddString(mod.szExePath);
                                while (Module32Next(hSnap, &mod))
                                {
                                    m_List1.AddString(mod.szExePath );
                                }
                            }
                            CloseHandle(hSnap);
                        }
                    }
                }
            }
            CloseHandle(hSnap1);
        }
    }
    else AfxMessageBox("Select Process");
}

Можно передать ID процесса и найти связанные с ним модули hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, proc.th32ProcessID);.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 35 - Список процессов

Продолжаем изучать возможности ToolHelp.Dll. Давайте создадим консольное приложение и сразу код:

// TestThread.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"
#include "tlhelp32.h"

int main(int argc, char* argv[])
{
    HANDLE hSnap = NULL;
    THREADENTRY32 te32;
    hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    if (hSnap!=NULL)
    {
        if (Thread32First(hSnap, &te32))
        {
            cout <<  te32.th32ThreadID << " " << te32.th32OwnerProcessID << endl;
            while (Thread32Next(hSnap, &te32))
                cout <<  te32.th32ThreadID << " " << te32.th32OwnerProcessID << endl;
        }
    }
    CloseHandle(hSnap);
    return 0;
}

Методика таже самая. Соединяемся с ToolHelp, только теперь смотрим Thread32First() и Thread32Next(), которые возвращают результат в структуру THREADENTRY32, из которой я пока извлек два параметра. Это идентификатор потока th32ThreadID и процесса, который этот поток породил th32OwnerProcessID и Вы увидите, что у процесса много потоков.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 36 - GetVersion()

С Новым годом и веком !!!!!
31 декабля 2000 года 19.45 (+10 по Гринвичу +7 по Москве).

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

DWORD GetVersion(VOID);

Реализована эта функция в Kernel32, а описана в Winbase.h. Код версии может принимать следующие значения.

VER_PLATFORM_WIN32s  		Win32s для Windows 3.1
VER_PLATFORM_WIN32_WINDOWS  	Windows 95/98
VER_PLATFORM_WIN32_NT  		Windows NT/2000

В младшем слове находится версия релиза. Извлекать их надо с помощью функций LOBYTE, HIBYTE, HIWORD. Давайте посмотрим пример.

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main() {
    DWORD dwVersion;
    DWORD dwWindowsMajorVersion;
    DWORD dwWindowsMinorVersion;
    DWORD dwBuild;
    dwVersion = GetVersion();
    dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
    dwWindowsMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
    if (dwVersion < 0x80000000)
    {
        dwBuild = (DWORD)(HIWORD(dwVersion));
        cout << "NT Build" << dwBuild << endl;
    }
    else
    if (dwWindowsMajorVersion < 4){
        dwBuild = (DWORD)(HIWORD(dwVersion) & ~0x8000);
        cout << "WIN32s Build " << dwBuild << endl;
    } else {
        dwBuild=0;
        cout << "Win95/Win98 Build " << dwBuild << endl;
    }
}

На данный момент существует новая версия этой функции GetVersionEx().

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 37 - GetVersionEx().

Новая реализация функции получения версии системы GetVersionEx():

BOOL GetVersionEx
(
    LPOSVERSIONINFO lpVersionInfo // указатель на структуру,
                //в которую будет получена информация.
);

А вот и структура :-)

typedef struct _OSVERSIONINFO
{
    DWORD dwOSVersionInfoSize; 	// размер структуры
    DWORD dwMajorVersion;	// идентификатор операционной системы
    DWORD dwMinorVersion;	// идентификатор версии
    DWORD dwBuildNumber;	// идентификатор сборки
    DWORD dwPlatformId;	// платформа
    TCHAR szCSDVersion[128];	// дополнительная информация об операционной системе
} OSVERSIONINFO;

Перед использованием этой функции надо указать размер структуры в параметре dwOSVersionInfoSize используя sizeof(OSVERSIONINFO).

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    OSVERSIONINFO osvi;
    ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    GetVersionEx((OSVERSIONINFO*)&osvi);
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 38 - GetComputerName()

Возвращает NetBios имя компьютера:

BOOL GetComputerName
(
    LPTSTR lpBuffer,	// указатель на буфер
    LPDWORD lpnSize	// указатель на размер буфера
);

Если функция выполнится успешно, то она возвратит ненулевое значение. Давайте посмотрим пример:

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    char buffer[MAX_COMPUTERNAME_LENGTH+1];
    DWORD size;
    size=sizeof(buffer);
    GetComputerName(buffer,&size);
    cout << buffer << endl;
}

Я размер буфера указал через константу, которая описана в файле WinBase.h:

#ifndef _MAC
    #define MAX_COMPUTERNAME_LENGTH 15
#else
    #define MAX_COMPUTERNAME_LENGTH 31
#endif

У меня результат работы этой функции такой:

MYCOMP
Press any key to continue

А вот, что у меня в настройке сети:

38.gif (3752 b)

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 39 - RegisterClass()

В Windows прежде чем создавать окно его нужно зарегистрировать. Именно регистрацию класса окна и производит функция RegisterClass():

ATOM RegisterClass
(
    CONST WNDCLASS *lpWndClass // указатель на структуру с данными класса
);

lpWndClass - это ссылка на структуру WNDCLASS смотри "Подробности - Структура WNDCLASS". Эта структура описывает основные характеристики окна. После регистрации класса можно вызывать функцию CreateWindow(). При успешной регистрации возвращается ненулевое значение, иначе возвращается ноль. Стандарный пример кода можно привести такой:

WNDCLASS wcx;
wcx.cbSize = sizeof(wcx);
wcx.style = CS_HREDRAW | CS_VREDRAW;
wcx.lpfnWndProc = MainWndProc;
......
RegisterClass(&wcx);

В этом коде создается и заполняется структура окна, которая потом передается в функцию регистрации.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 40 - Управление питанием монитора с помощью WM_SYSCOMMAND

Блуждая по закоулкам MSDN-а, наткнулся я, совершенно случайно, на сообщение WM_SYSCOMMAND, которое поразило меня богатством свойх возможностей. Оказывается, если послать WM_SYSCOMMAND главному окну, передав в качестве wParam один из нижеописанных параметров можно получить довольно интерестные эффекты.

Начну с параметра SC_MONITORPOWER, который позволяет управлять питанием монитора. В этом случае lParam при вызове функции SendMessage может принимать одно из значений приведенных в таблице:

lParam | Описание
-1 | Переводит монитор в нормальный, рабочий режим
0 | Переводит монитор в режим "легкого" засыпания
1 | Переводит монитор в спящий режим
2 | Монитор выключается

Несмотря на то, что Microsoft описала только последние два значения, на практике (во всяком случае, в Win98) срабатывают все. Т.о. для выключения монитора в Вашей программе достаточно написать:

::SendMessage(AfxGetMainWnd()->m_hWnd, WM_SYSCOMMAND,
        SC_MONITORPOWER, 2);

И не забудьте в обработчик сообщений от клавиатуры или мыши добавить:

::SendMessage(AfxGetMainWnd()->m_hWnd, WM_SYSCOMMAND,
            SC_MONITORPOWER, -1);

как сделано в проекте-примере, иначе Вы не сможете вернуть монитор в прежнее состояние иначе как перезагрузкой!!!

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

lParam | Описание
0 | Активизирует скринсейвер
1 | Позволяет перейти в ждущий режим

Соответственно запустить хранитель экрана можно вызвав функцию:

::SendMessage(AfxGetMainWnd()->m_hWnd, WM_SYSCOMMAND,
            SC_SCREENSAVE, 0);

Ну и совсем уж неожиданный эффект - иммитация нажатия на кнопку "Пуск", которую выполняет SC_TASKLIST, причем lParam - любое число :

::SendMessage(AfxGetMainWnd()->m_hWnd, WM_SYSCOMMAND,
            SC_TASKLIST, 1);

Прислал Антон Рыбаков(anton_ryb@chat.ru)

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 41 - Явный вызов функций DLL

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

HMODULE LoadLibrary
(
    LPCTSTR lpLibFileName	// имя модуля
);

Она может завершиться как успешно, так и нет. Если успешно, то вернет указатель на DLL. Что она сделает ? Она поищет DLL. Еcли найдет, то загрузит ее в память и вернет Вам указатель. Так как DLL загружается в память Вы не можете просто так ее бросить, Вам надо ее выгрузить, а для этого есть функция FreeLibrary(), которая как раз сообщит Windows, что данная программа DLL больше не использует. Вообще за загрузку и выгрузку DLL отвечает Windows, так как DLL может использоваться несколькими программами. Вы просто говорите, что программа начинает использовать DLL (LoadLibrary) и заканчивает (FreeLibrary), а OC сама разбирается надо грузить ее в память или наоборот убирать, так как никто не использует ее. Вот пример:

// TestDLL.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    HINSTANCE hModule=NULL;
    hModule=::LoadLibrary("user32.dll");
    if (hModule!=NULL)
    {
        ::FreeLibrary(hModule);
    }
    else cout << "error load Dll" << endl;
}

Как только мы получили указатель на DLL мы можем получить адрес функции по имени функции. Естественно нам имя нужно знать. Сначала надо объявить прототип функции typedef BOOL (WINAPI MESS)(UINT);. Обратите внимание, что я явно указал тип вызова WINAPI, что означает _stdcall так как С++ использует _cdecl, который не совместим с WIN32 API. Объявив прототип я могу создать указатель на функцию, а потом воспользовавшись GetProcAddress() получить функцию и уже ее вызывать.

// TestDLL.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    HINSTANCE hModule=NULL;
    typedef  BOOL (WINAPI MESS)(UINT);
    MESS* me=NULL;
    hModule=::LoadLibrary("user32.dll");
    if (hModule!=NULL)
    {
        me=(MESS*)::GetProcAddress((HMODULE)hModule,"MessageBeep");
        if (me!=NULL)
        {
            UINT type=1;
            BOOL result;
            result=(*me)(type);
        }
        else cout << "Error Load function" << endl;
        ::FreeLibrary(hModule);
    }
    else cout << "error load Dll" << endl;

Внимание !!! Тщательно следите на типом вызова функций. Win32 пользуется методом вызова функций PASCAL - _stdcall, а VC методом вызова C, а в Windows стандарт вызова функций PASCAL. Разница этих методов в помещении параметров в стек. Будет время напишу подробнее. Просто помните об этом. Свои DLL Вы можете вызывать без WINAPI, а вот чужие надо знать, если стандартный API, то WINAPI, иначе надо выяснять. Как ?? Просто получаете ошибку вызова, если ошибетесь :-)

41.gif (3900 b)

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 42 - Функция WinMain()

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

int WINAPI WinMain
(
    HINSTANCE hInstance,	// указатель на текущий экземпляр
    HINSTANCE hPrevInstance,	// указатель на предыдущйи запушенный экземпляр
    LPSTR lpCmdLine,		// командная строка
    int nCmdShow		// тип отображения окна программы
);

Определена она в windows.h. Давайте посмотрим параметры. Первый параметр - это указатель на саму программу, каждая программа при запуске получает уникальный идентификатор, Windows просто передает его Вам. Второй - должен указывать на экземпляр программы, который был запущен ранее. В WIN32 - этот параметр всегда равен NULL, в WIN31 было иначе. То есть он не нужен. Что делать, если нужно определять все-таки запущен другой экземпляр или нет ? Использовать семафоры CreateMutex(). Чтобы получить представление о том, как это делается смотрите "Шаг 9 - Синхронизация файловых операций Mutex". Следующий параметр - это командная строка, как указатель на последовательность символов оканчивающихся нулем. Ее извлекать лучше с помощью GetCommandLine(). Последний параметр - это тип отображения окна, то есть совет Windows как окну надо отобразиться. Как известно советы бывают всякие черные, белые, красные и так далее. Дело в том, что у пользователя есть возможность указать как он хочет запустить программу, допустим, если он удерживает клавишу SHIFT, то программа должна запускаться в минимизированном виде. Проверьте на блокноте (notepad.exe), если не верите. У значков программ через ПУСК есть таже возможность указатель, как запускать.

42.gif (2638 b)

Вернуть WinMain должна результат своей работы. Но на самом деле Windows никогда не проверяет это значение. В DOS - это значение можно было проверять в BAT файлах, анализируя результат выполнения. Я писал диплом в Институте как раз примерно про это. То есть как в DOS организовать автоматические цепочки обработки информации. Сложность реальная была одна, как узнать результат работы другой программы. Вот и было два выхода - это стандартный файл с отчетом о работе и кода завершения. Используя и то и другое вроде как-то получалось. Вообще программа для Windows должна завершаться когда получит сообщение WM_QUIT. Это сообщение может послать как пользователь, зарыв главное окно, так и операционная система, например, при снятии задачи или завершении работы. Обратите внимание на то, что в WINAPI именно такое правило передачи параметров через стек.

Примеры применения ее для программирования на С смотрите в шагах:

  • "1.27.1.56 Функция WinMain"
  • "Подробности - #pragma message"
  • "Шаг 17 - Абстрактные классы"
  • "Шаг 4 - Окно Windows на С"
  • "Шаг 18 - Как узнать имя EXE файла программы"
  • "Шаг 31 - Программа, которая не удаляется из списка задач"
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 43 - CreateWindow()

Данная функция используется для создания окна приложения:

HWND CreateWindow
(
    LPCTSTR lpClassName,	// имя класса окна
    LPCTSTR lpWindowName,	// заголовок окна
    DWORD dwStyle,		// стиль окна
    int x,			// горизонтальная позиция окна
    int y,			// вертикальная позиция окна
    int nWidth,		// ширина окна
    int nHeight,		// высота окна
    HWND hWndParent,		// указатель на родительское окно
    HMENU hMenu,		// указатель на меню
    HINSTANCE hInstance,	// указатель на приложение создающее окно
    LPVOID lpParam		// дополнительные параметры
);

Для того, чтобы создать окно, класс окна необходимо сначала зарегистрировать. Это делается функцией RegisterClass(). О этой функции смотрите "Шаг 39 - RegisterClass()". Вторая строка - это просто заголовок окна. Он может быть в последствии изменен. Следующий параметр - это стиль окна. Смотрите "Подробности - Стили окна". Дальше идут координаты окна относительно монитора, высота и ширина окна, эти параметры можно не указывать используя CW_USEDEFAULT, полагаясь на Windows. В нем есть некоторый алгоритм расположения окон. Указатель на родительское окно в случае, если у окна есть родитель. Дело в том, что одной и той же функцией создаются как главные окна, так и подчиненные, такие как диалоговые окна. Вообщем все окна windows создаются одной и той же функцией, различие только в стилях окон. Дальше нужен указатель на меню связанное с окном. Создавая окно, нужно указать идентификатор приложения его создавшего. Этот идентификатор идет как параметр WinMain(). Смотрите "Шаг 42 - Функция WinMain()". Перед тем, как завершить создание окна посылается сообщение WM_CREATE в процедуру обработки окна.

После завершения работы эта функция вернет идентификатор окна HWND. Этот идентификатор является уникальным и он теперь будет характеризовать наше окно.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 44 - Извлечение ресурсов из модуля EnumResourceTypes()

Как известно, в программах хранятся их ресурсы. Как извлечь ресурсы из файла EXE или DLL программным путем ??? Очень просто. В WIN32 API предусмотрены специальные функции по этому поводу. Давайте посмотрим EnumResourceTypes(), которая позволяет узнать все типы ресурсов, которые есть в модуле:

BOOL EnumResourceTypes
(
    HMODULE hModule,		// указатель на модуль
    ENUMRESTYPEPROC lpEnumFunc,	// функция перечисления
    LONG_PTR lParam		// параметры определенные программистом
);

Как ее применить. Ну, во-первых нужно получить указатель на модуль, потом вызвать эту функцию, передав в параметрах и модуль и функцию, которая будет вызываться. Вот так:

// ResTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

BOOL WINAPI EnumTypesFunc(HMODULE hModule,LPTSTR lpType, LONG lParam);

void main()
{
HMODULE hMod=NULL;
hMod = LoadLibrary("notepad.exe");
if (hMod != NULL)
{
    EnumResourceTypes(hMod,(ENUMRESTYPEPROC)EnumTypesFunc,0);
    FreeLibrary(hMod);
}
else cout << "Not Load Module";
}

BOOL WINAPI EnumTypesFunc(HMODULE hModule,LPTSTR lpType, LONG lParam)
{
    char buffer[100];
    if ((ULONG)lpType & 0xFFFF0000)
    {
        sprintf(buffer, "%s\n", lpType);
    }
    else
        {
        sprintf(buffer, "%u\n", (USHORT)lpType);
    }
    cout << "Type " << buffer << endl;
    return true;
}

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

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 45 - Извлечение имен ресурсов EnumResourceNames()

Типы ресурсов мы получили, но для доступа к самим ресурсам нам нужно получить их имена. Вот для этого и существует функция EnumResourceNames():

BOOL EnumResourceNames
(
    HMODULE hModule,		// модуль
    LPCTSTR lpszType,		// тип ресурса
    ENUMRESNAMEPROC lpEnumFunc,	// вызываемая функция
    LONG_PTR lParam		// параметры определенные программистом
);

Ну и применим к нашей программе:

// ResTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

BOOL WINAPI EnumTypesFunc(HMODULE hModule,LPTSTR lpType, LONG lParam);
BOOL WINAPI EnumNamesFunc(HMODULE hModule,
        LPCTSTR lpType,LPTSTR lpName,LONG lParam);

void main()
{
    HMODULE hMod=NULL;
    hMod = LoadLibrary("notepad.exe");
    if (hMod != NULL)
    {
        EnumResourceTypes(hMod,(ENUMRESTYPEPROC)EnumTypesFunc,0);
        FreeLibrary(hMod);
    }
    else cout << "Not Load Module";
}

BOOL WINAPI EnumTypesFunc(HMODULE hModule,LPTSTR lpType, LONG lParam)
{
    char buffer[100];
    if ((ULONG)lpType & 0xFFFF0000)
    {
        sprintf(buffer, "%s\n", lpType);
    }
    else
    {
        sprintf(buffer, "%u\n", (USHORT)lpType);
    }
    cout << "Type " << buffer << endl;
    EnumResourceNames(hModule,lpType,(ENUMRESNAMEPROC)EnumNamesFunc,0);
    return true;
}

BOOL WINAPI EnumNamesFunc(HMODULE hModule, LPCTSTR lpType,LPTSTR lpName,LONG lParam)
{
    char buffer[100];
    if ((ULONG)lpName & 0xFFFF0000)
    {
        sprintf(buffer,"%s\n", lpName);
    }
    else
        {
        sprintf(buffer, "%u\n",(USHORT)lpName);
    }
    cout << "Name Res " << buffer << endl;
    return true;
}

Пример результата ее работы:

........
Type 9
Name Res1
Name Res2
Type 14
Name Res1
Name Res2
Type 16
Name Res1

Кстати к ресурсам можно обращаться как по именам, так и по идентификаторам. Вот теперь мы получили имена ресурсов и их типы. Можно извлекать их из модуля. По этому поводу есть функции, например, LoadImage(), LoadIcon(), LoadMenu(), LoadCursor() ну и так далее.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 46 - О функциях Enum

Мы уже несколько раз сталкивались с функциями начинающимися с префикса Enum. Это в принципе отдельный класс функций. Где мы их встречали ??? К примеру в шаге "Шаг 14 - Перечисление сервисов NT EnumServicesStatus".

Встретим мы их еще ??? Точно, вот примеры EnumCalendarInfoEx, EnumChildProc, EnumClipboardFormats. И так далее.

Вообщем есть такой класс функций. Название этих функций идет от английского Enumeration, то есть перечисление. Используются они, если нужно получить доступ к списку чего-либо, например соединений, устройств и так далее. По этому поводу есть два пути. Первый передавать адрес массива и количество элементов в нем. Но тут нам нужно самим организовывать циклы доступа и так далее. Другой подход реализованный в этих функциях: можно вызывать одну и туже функцию, которая будет возвращать нам значения. Это скрывает от нас многие тонкости реализации. Общая идея такая.

Пока (EnumGet());

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

EnumGet(*MyFunction)

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

Вариант 1

// TestEnum.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "iostream.h"

bool EnumGet();
int x;

void main()
{
    x=0;
    cout << "test1" << endl;
    while(EnumGet());
    cout << "test2" << endl;
    while(EnumGet());
}

bool EnumGet()
{
    x=x+1;
    if (x==3)
    {
        x=0;
        return false;
    }
    else
    {
        cout << "Iter - " << x << endl;
        return true;
    }
}

Вариант 2

// TestEnum.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "iostream.h"

void MyFunct(int x);
void EnumGet();

void main()
{
    cout << "test1" << endl;
    EnumGet();
    cout << "test2" << endl;
    EnumGet();
}

void EnumGet()
{
    int x;
    x=3;
    for (int y=1; y<x ;y++) MyFunct(y);
}

void MyFunct(int x)
{
    cout << "Iter - " << x << endl;
}

Конечно эти примеры очень упрощенные, но главное показана идея как это вообще работает и как реализовывается.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 47 - Поиск ресурсов FindResource

Эту функцию мы использовали раньше, смотрите "Шаг 148 - WAV файлы в ресурсах". Есть у нее и другие применения. Что делает эта функция ??? Она производит поиск ресурсов в модуле.

HRSRC FindResource
(
    HMODULE hModule,	// указатель на модуль
    LPCTSTR lpName,	// имя ресурса
    LPCTSTR lpType	// тип ресурса
);

Если в качестве модуля указать NULL, то поиск будет производиться в текущем процессе. Давайте посмотрим как это происходит на примере. При неудачном поиске функция вернет NULL. Типы ресурсов смотрите в "Шаг 51 - Константы типов ресурсов".

У нас приложение WIN32 (без MFC), в котором есть ресурс диалогового окна.

47.gif (5122 b)

А вот и приложение для проверки:

// TestRes.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "resource.h"

int APIENTRY WinMain(HINSTANCE hInstance,
            HINSTANCE hPrevInstance,
            LPSTR lpCmdLine,
            int nCmdShow)
{
    HRSRC rc=NULL;
    rc=::FindResource(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),RT_DIALOG);
    if (rc!=NULL)
    {

    } else
        MessageBox(NULL,"Not resource","error",MB_OK);
    return 0;
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 48 - LoadIcon()

Этa функция позволяет загрузить икону из ресурсов.

HICON LoadIcon
(
    HINSTANCE hInstance,	// указатель на приложение
    LPCTSTR lpIconName		// идентификатор
);

Если функция завершится неудачно, то вернется значение NULL. Эта функция вернет указатель на икону в том случае, если ее параметры совпадают с параметрами установленными в SM_CXICON и SM_CYICON, которые можно получить функцией GetSystemMetric. Если Вы хотите икону другого типа, то используйте LoadImage().

#include "stdafx.h"
#include "resource.h"

int APIENTRY WinMain(HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        LPSTR lpCmdLine,
        int nCmdShow)
{

    HICON hi=NULL;
    hi=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));
    if (hi!=NULL)
    {

    }
    else MessageBox(NULL,"Not resource","error",MB_OK);
    return 0;
};

При указателе равном NULL появляется возможность использовать одну из системных икон.

// TestRes.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "resource.h"

int APIENTRY WinMain(HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        LPSTR lpCmdLine,
        int nCmdShow)
{

    HICON hi=NULL;
    hi=::LoadIcon(NULL,MAKEINTRESOURCE(IDI_ERROR));
    if (hi!=NULL)
    {

    }
    else MessageBox(NULL,"Not resource","error",MB_OK);
    return 0;
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 49 - Макросы для ресурсов

Их всего два:

  • IS_INTRESOURCE - этот макрос проверяет является ли данный идентификатор идентификатором ресурсов. Если это идентификатор ресурса вернется значение TRUE.
    BOOL IS_INTRESOURCE
(
    WORD wInteger	// идентификатор ресурсов
);
  • MAKEINTRESOURCE - конвертирует идентификатор в строковый параметр.
    LPTSTR MAKEINTRESOURCE
(
    WORD wInteger
);
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 50 - LoadResource()

Функция читает ресурс из модуля. Для получения указателя на ресурс используйте функцию FindResource() или FindResourceEx(). Если функция удачна, то вернется указатель на ресурс.

HGLOBAL LoadResource
(
    HMODULE hModule,	// указатель модуля
    HRSRC hResInfo	// указатель на ресурс
);

Смотрим пример. Тот же проект, что и в FindResource():

// TestRes.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "resource.h"

int APIENTRY WinMain(HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        LPSTR lpCmdLine,
        int nCmdShow)
{
    HRSRC rc=NULL;
    rc=FindResource(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),RT_DIALOG);
    if (rc!=NULL)
    {
        HGLOBAL hgl=NULL;
        hgl=LoadResource(hInstance,rc);
        if (hgl!=NULL)
        {
            FreeResource(hgl);
        }
        else MessageBox(NULL,"Not resource","error",MB_OK);

    }
    else MessageBox(NULL,"Not resource","error",MB_OK);
    return 0;
}

Внимание HGLOBAL на самом деле не возвращает указатель именно к глобальной памяти. Этот тип использован для совместимости. Нельзя к нему применять функции типа GlobalLock() или GlobalFree().

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 51 - GetMessage()

Эта функция извлекает сообщение из очереди.

BOOL GetMessage
(
    LPMSG lpMsg, // указатель на структуру
    HWND hWnd, // указатель окна чьи сообщения нужно обрабатывать
    UINT wMsgFilterMin, // номер мимимального сообщения для выборки
    UINT wMsgFilterMax // номер максимального сообщения для выборки
);

С помощью переменной hWnd есть возможность указать конкретное окно, от которого будет принято сообщение. Если установить это значение в NULL, то будут приниматься все сообщения. Возврат этой функции будет отличен от нуля пока не будет получено сообщение WM_QUIT. Это дает возможность вроде как организовать цикл в программе типа:

while(GetMessage(:)
{
    //...
}

Эта функция кстати может завершиться ошибкой, то есть вернуть -1. А вот тут-то мы сразу и видим, что вышеуказанный код неверен и может привести к ошибке в приложении. Правда во всех книгах он описан, так как и у меня. Странно однако. Ну ладно. Хотя пренебрежение этим как пишет Microsoft может привести к фатальной ошибке "синий экран" и все такое. Эта функция блокирующая, то есть она блокирует приложение до того момента пока не будет получено сообщение, но в этот момент передается управление Windows для выполнения других приложений. Последние параметры устанавливают фильтр на сообщения. Если оба их поставить в 0б то будут приниматься все сообщения. Откуда же в Windows вообще берутся сообщения ??? Вот примерно такая схема.

51_1.gif (3761 b)

Итак, Windows получает сообщения от устройств типа клавиатуры, мыши, таймера и так далее. Естественно, что у каждого этого устройства есть драйвер, который и умеет сам работать с оборудованием. Сообщение попадает в очередь Windows, из которой уже сообщение передается в очередь сообщений приложения. Само приложение уже выбирает сообщения, используя GetMessage(). Как Windows узнает кому надо оправить сообщение, то есть в чью очередь??? Для клавиатуры и мыши просто. У кого фокус ввода, тот и получит сообщение. На картинке ниже сообщения от клавиатуры будет получать блокнот. Он сверху и у него фокус.

51_2.gif (3511 b)

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 52 - PeekMessage()

Помните, что функция GetMessage() является блокирующей. То есть она ожидает пока не будет получено сообщение из очереди. До этого момента программа стоит. Что делать, если надо просто проверить есть ли сообщение в очереди. Зачем ??? Например, чтобы занять программу в этот момент другими действиями, например, упаковкой базы данных. Для этого и есть функция PeekMessage(). Она проверяет есть ли в очереди сообщение и программа выполняется дальше.

BOOL PeekMessage
(
    LPMSG lpMsg,		// Указатель на структуру MSG
    HWND hWnd,		// Указатель на окно (кому сообщение)
    UINT wMsgFilterMin,	// для маски минимум
    UINT wMsgFilterMax,	// для маски максимум
    INT wRemoveMsg		// Что делать с сообщением
);

Единственный последний параметр нам не знаком. Вот какой он может быть:

PM_NOREMOVE		Не удалять сообщение из очереди
PM_REMOVE			Удалять сообщения из очереди

Эта функция вернет ненулевое значение, если в очереди есть сообщения. Если фильтра нет, то будут получены все сообщения, при наличии фильтра только по фильтру. Обратите внимание, что GetMessage() вернет WM_QUIT даже при фильтре. Пример использования ее может быть такой.

while (true)
{
    while (!::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE))
    {
        // функция для работы пока нет сообщений
    }
    if (!::GetMessage(&m_msgCur, NULL, NULL, NULL)) break;
    ::TranslateMessage(&m_msgCur);
    ::DispatchMessage(&m_msgCur);
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 53 - TranslateMessage()

Эта функция переводит сообщения формата виртуальных клавиш в сообщения символы.

BOOL TranslateMessage
(
    CONST MSG *lpMsg   // структура с информацией о сообщении
);

lpMsg - это структура полученная в результате вызова функций GetMessage() или PeekMessage(). Функция вернет значение отличное от нуля в случае, если перевод произведен. Если сообщение типа WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, или WM_SYSKEYUP, то возвращаемое значение всегда отличное от нуля. Эта функция не изменяет структуру MSG, а добавляет новые сообщения. Вот так:

WM_KEYDOWN + WM_KEYUP ->  WM_CHAR или WM_DEADCHAR
WM_SYSKEYDOWN + WM_SYSKEYUP -> WM_SYSCHAR или WM_SYSDEADCHAR

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

while (GetMessage(&msg, (HWND) NULL, 0, 0))
{
    if (TranslateAccelerator(hwndMain, haccl, &msg) == 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

Этот пример хоть и классический, но уже устаревший. Новая интерпретация его такая:

while (ret)
{
    ret = GetMessage(&msg, NULL, 0, 0);
    if( (int) ret != -1 )
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
     }
     return( ret );
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 54 - DispatchMessage()

Эта функция пересылает сообщение оконной процедуре.

LRESULT DispatchMessage
(
    CONST MSG *lpmsg	// указатель на структуру с сообщением
);

Возвращаемое значение является тем, которое вернет оконная процедура. Но обычно это значение игнорируется. Откуда берется оконная процедура ??? Она есть в параметрах, то есть не сама процедура, а указатель на окно (HWND). Если указатель HWND_TOPMOST, то сообщение будет переслано всем окнам верхнего уровня. А если NULL, то вообще ничего не будет делаться. Эта функция нужна только один раз, даже если у вас в приложении много окон, она будет рассылать сообщения по окнам в соответствии со структурой MSG. Теперь мы можем нарисовать общую схему прохождения сообщений:

54.gif (6816 b)

Итак, мы получаем сообщение. Проверяем не конец ли это работы, т.е. WM_QUIT. Если нет, то отдаем сообщение в TranslateMessage(), чтобы получить сообщения от клавиатуры более высокого уровня. После этого перенаправляем сообщение в оконную процедуру на основе HWND указанного в самом сообщении DispatchMessage. Цикл должен быть один для одного потока.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 55 - Понятие CALLBACK функции

Что это за тип функции такой CALLBACK? Обычно такие функции называются функциями обратного вызова. Это просто. Если Вашу функцию должен вызывать Windows, то вы должны указать ей тип передачи параметров как CALLBACK. Этот тип вызова описан в WinDef.H как:

#define CALLBACK    __stdcall

То есть тип передачи параметров PASCAL. Обычный вызов функций осуществляется в стиле WIN32 API. Как же Windows узнает, что эту функцию можно выполнить ? Вы сами, зная то или нет, передаете ее в параметрах. Если вы создаете окно в Win 32, то и передаете функцию окна. Windows эту функцию вызывает когда управляет окном. Все просто. Сказали системе, что если нужно обратиться к окну вот тебе функция. После этого Windows знает, что если нужно перерисовать окно, то он хвать эту функцию и передает ей в параметры WM_PAINT. Идея довольно простая. Операционная система должна уметь вызывать некоторые функции в приложении, чтобы освободить вас как программиста от слежения за программой. Кто писал для ДОС знает как это не удобно думать о том, какое окно видно на экране, а какое нет. Пусть операционная система заботится. Итак, в любой программе для Windows (кстати и не только в понимании графического интерфейса) есть функции, которые вызовет операционная система. Как пример главная функция окна. Эта функция должна быть в программе правильно оформлена, а именно CALLBACK. Обычно мы ее передаем в виде параметров при вызове фнукций WIN32 API.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 56 - Основная функция окна

Эта функция производит обработку сообщений для окна. Мы ее связываем с окном при заполнении структуры класса окна WNDCLASS в поле lpfnWndProc:

WNDCLASS WC;
......
WC.lpfnWndProc = WndProc;

Вот эта функция WndProc и будет получать сообщения, которые Windows будет отсылать окну. Соответственно эта функция должна быть объявлена ранее. Прототип у этой функции такой:

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,LPARAM);

Общий вид для реализации:

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wparam,LPARAM lparam)
{
    if (Message == WM_DESTROY )
    {
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd,Message,wparam,lparam);
}

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

LRESULT DefWindowProc
(
    HWND hWnd,	// указатель окна
    UINT Msg,		// идентификатор сообщения
    WPARAM wParam,	// первый параметр сообщения
    LPARAM lParam	// второй параметр сообщения
);

Возврашает результат обработки сообщения. Обычно в функции WndProc организуется огромный switch для обработки сообщений.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 57 - Функции ShowWindow() и UpdateWindow()

Функция ShowWindow() устанавливает режим отображения окна:

BOOL ShowWindow
(
    HWND hWnd,	// указатель на окно
    int nCmdShow	// режим
);

Функция UpdateWindow() обновляет клиентскую область указанного окна, посылая WM_PAINT сообщение к окну. Функция посылает WM_PAINT сообщение непосредственно процедуре указанного окна, обходя прикладную очередь.

BOOL UpdateWindow
(
    HWND hWnd 	// указатель на окно
);

57.gif (2191 b)

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 58 - Понятие дескриптора

Дескриптор - это уникальное число, которое Windows использует для идентификации. В Windows есть большое количество типов дескрипторов, например:

  • окна
  • меню
  • устройства вывода
  • файлы
  • перья
  • и многие другие.

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

58.gif (1509 b)

Программируя под Windows мы очень часто используем эти дескрипторы. Существуют ограничения по количеству дескрипторов. Например, количество окон в Windows ограничено, хотя может очень большим. Хуже с другими объектам типа перьев, их намного меньше и если Ваша программа ведет себя не корректно по отношению к дескрипторам, то очень быстро они могут закончиться. В связи с этим общая идеология такая:

Получить дескриптор
Использование
Освободить

Вы можете подобную последовательность наблюдать практически при каждом этапе программирования.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 59 - Сообщение WM_CLOSE

Это сообщение посылается когда окно должно быть закрыто. Это сообщение не имеет параметров. Использование этого сообщения:

case WM_CLOSE:
    DestroyWindow(hwndMain);
    break;

Функция DestroyWindow() разрушает указанное окно. Функция посылает сообщения WM_DESTROY и WM_NCDESTROY окну. DestroyWindow() автоматически разрушает связанные или находящиеся в собственности окна. DestroyWindow() также разрушает немодальные диалоговые окна, созданные функцией CreateDialog().

BOOL DestroyWindow
(
    HWND hWnd // указатель на окно
);

Если функция заканчивается удачно, то будет возвращено ненулевое значение.

59.gif (1829 b)

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 60 - Сообщение WM_DESTROY

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

case WM_DESTROY:
    PostQuitMessage( 0 );
    break;
В ответ на это сообщение мы должны поместить в очередь сообщение WM_QUIT. Это и делает функция PostQuitMessage() посылая в очередь это сообщение и говоря, что процесс должен быть завершен.
VOID PostQuitMessage
(
    int nExitCode		// код возврата
);

60.gif (1434 b)

Смотрите на рисунок. Сообщение WM_DESTROY поступает сразу в оконную процедуру. Теперь оконная процедура вызывает PostQuitMessage(), которая и помещает сообщение WM_QUIT в очередь сообщений. В последствии его отловит GetMessage() и программа прекратит работу. WM_QUIT может посылать только WinMain() и должна это делать. И Windows и Вы сами не должны посылать сообщение WM_QUIT. Это сделано для того, чтобы окно могло освободить все использованные им ресурсы.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 61 - Функция LoadMenu()

Эта функция получает указатель на меню из файла ресурсов:

HMENU LoadMenu
(
    HINSTANCE hInstance,	// модуль
    LPCTSTR lpMenuName		// имя ресурса меню
);

Если результат работы функции неудачный, то вернется NULL. Давайте добавим поддержку меню к обычной программе на C, которую мы создавали в "Шаг 4 - Окно Windows на С". Для этого нам нужно добавить файл ресурсов и поместить в него меню.

61_1.gif (3868 b)

Добавить ссылку на файл с идентификаторами ресурсов.

#include "stdafx.h"
#include "windows.h"
#include "windowsx.h"
#include "resource.h"

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,LPARAM);
............

И описать меню в структуре окна.

w.lpfnWndProc = WndProc;
w.hInstance = hInstance;
w.hbrBackground = GetStockBrush(WHITE_BRUSH);
w.lpszClassName = "C Windows";
w.lpszMenuName = MAKEINTRESOURCE (IDR_MENU1);
RegisterClass(&w);

После запуска мы увидим, что меню у нас появилось:

61_2.gif (960 b)

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 62 - Сообщение WM_COMMAND

Сообщение WM_COMMAND посылается когда:

  • производится выбор пункта меню
  • элемент управления посылает уведомительное сообщение родительскому окну
  • происходит нажатие клавиши акселератора.

Обработка этого сообщения производится в главной функции окна.

Wparam - определяет источник сообщения: элемент управления или акселератор.

Lparam - идентификатор элемента, если это не акселератор.

После обработки этого сообщения необходимо вернуть 0. Пример обработки этого сообщения мы сделаем на основе "Шаг 61 - Функция LoadMenu()".

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wparam,LPARAM lparam)
{
    switch (Message)
    {
        case WM_COMMAND:
        {
            switch(wparam)
            {
                case ID_ABOUT:
                {
                    MessageBox(hwnd,"Menu Click","Info",MB_OK);
                    return 0;
                }
            }
        }
        case WM_DESTROY:
        {
            PostQuitMessage(0);
            return 0;
        }
    }
    return DefWindowProc(hwnd,Message,wparam,lparam);
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 63 - DialogBox

Макро DialogBox создает модальное диалоговое окно из шаблона в ресурсах. Диалоговое окно не вернет управление пока не будет вызвана функция EndDialog. Эта функция использует функцию CreateWindowEx для создания окна.

INT_PTR DialogBox
{
    HINSTANCE hInstance,	// указатель на модуль
    LPCTSTR lpTemplate,	// шаблон диалога
    HWND hWndParent,		// окно владелец
    DLGPROC lpDialogFunc	// процедура диалогового окна
);

Если функция не выполняется по причине отсутствия окна владельца, то ворачивается 0, если по другой причине, то -1. Пример применения:

case ID_ABOUT:
{
    DialogBox(hInst,MAKEINTRESOURCE (IDD_DIALOG1), hwnd, DlgProc);
    return 0;
}

Работа диалогового окна заканчивается функцией EndDialog.

BOOL EndDialog
(
    HWND hDlg,	// указатель на диалоговое окно
    INT_PTR nResult	// код возврата
);

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

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 64 - Функция диалогового окна

Как у окна есть функция обработки, так и у диалогового окна есть своя функция обработки команд, таких как нажатие на кнопку или перемещение диалогового окна. Отличаются они тем, что функция диалогового окна не вызывает DefWindowProc, а возвращает TRUE если сообщение обработано или FALSE если не обработано.

Общий вид процедуры:

BOOL CALLBACK DlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        default:
            return FALSE;
    }
}

Эта функция будет указываться при создании диалогового окна. Используя, например, CreateDialog() вы в параметрах указываете ссылку на эту функцию. Давайте сделаем ее к нашему предыдущему примеру.

Описание:

#include "resource.h"

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,LPARAM);
BOOL CALLBACK DlgProc(HWND,UINT,WPARAM,LPARAM);

int APIENTRY WinMain(HINSTANCE hInstance

И реализация пока в виде макета:

BOOL CALLBACK DlgProc(HWND hwndDlg, UINT message,
        WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        default:
            return FALSE;
    }
}

Для того, чтобы диалоговое окно закрывалось нам надо сделать реакцию на нажатие кнопок OK и CANCEL. То есть описать это в процедуре диалогового окна:

BOOL CALLBACK DlgProc(HWND hwndDlg, UINT message,
        WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_COMMAND:
        {
            if (wParam == IDOK||wParam == IDCANCEL)
            {
                EndDialog(hwndDlg, NULL);
                return TRUE;
            }
            else return FALSE;
        }
        default: return FALSE;
    }
}

Напишите эту функцию. Добавьте в ресурсы диалог:

64.gif (1112 b)

Измените реакцию на WM_COMMAND в функции окна программы. По выбору пункта меню About запускать диалоговое окно.

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wparam,LPARAM lparam)
{
    switch (Message)
    {
        case WM_COMMAND:
        {
            switch(wparam)
            {
                case ID_ABOUT:
                {
                    DialogBox(hInst,MAKEINTRESOURCE (IDD_DIALOG1),
                        hwnd, DlgProc);
                    return 0;
                }
            }
        }
        case WM_DESTROY:
        {
            PostQuitMessage(0);
            return 0;
        }
}
return DefWindowProc(hwnd,Message,wparam,lparam);
}

Да, я объявил дескриптор экземпляра программы глобально:

......
BOOL CALLBACK DlgProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE hInst;
int APIENTRY WinMain(HINSTANCE hInstance
......

И инициализировал его:

WNDCLASS w;
hInst=hInstance;
memset(&w,0,sizeof(WNDCLASS));

Этот дискриптор используется часто и лучше его иметь при себе.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 65 - Единицы диалогового окна

При создании диалогового окна и при размещении на нем элементов управления используются единицы диалогового окна. Это не пикселы. Что такое единица диалогового окна? Одна горизонтальная единица окна равна четвертой части средней ширины цифры(знака) для шрифта. Одна вертикальная единица окна равна восьмой части средней высоты цифры(знака) для шрифта. Это в том случае если используется системный шрифт. При создании шаблона диалога указывается ширина и высота в единицах диалогового окна.

AboutBox DIALOG 22, 17, 144, 75
........

65.gif (3090 b)

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

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

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 66 - Функция GetDialogBaseUnits()

У диалога свои единицы измерения. Эти единицы зависят от шрифта используемого в диалоге. С помощью функции GetDialogBaseUnits у нас есть возможность получить единицы диалогового окна в пикселах.

LONG GetDialogBaseUnits
(
    VOID
);

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

Для конвертирования единиц измерения диалоговых окон к пикселям нужно применять следующие формулы:

pixelX = MulDiv( templateunitX, baseunitX, 4 );
pixelY = MulDiv( templateunitY, baseunitY, 8 );

И наоборот:

templateunitX = MulDiv( pixelX, 4, baseunitX );
templateunitY = MulDiv( pixelY, 8, baseunitY );

Единицы измерения окна зависят от стиля Style, который был установлен при создании окна в шаблоне. Для дочерних панелей диалога координаты связаны с начальными координатами родительского окна, в противном случае панель диалога имеет тип DS_ABSALIGN, тогда координаты связаны с начальными координатами экрана дисплея.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 67 - Откуда окно получает сообщения

Окно обычно получает сообщения из двух источников: от устройств ввода и от диспетчера управления окнами.

67.gif (2922 b)

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

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 68 - Функции UpdateWindow() и InvalidateRect()

Функия UpdateWindow() обновляет содержимое окна, посылая сообщение WM_PAINT непосредственно в оконную процедуру.

BOOL UpdateWindow
(
    HWND hWnd		// окно
);

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

68.gif (3749 b)

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 69 - Функция InvalidateRect()

Указывает прямоугольник для перерисовки окна:

BOOL InvalidateRect
(
    HWND hWnd,		// указатель на окно
    CONST RECT *lpRect,	// прямоугольник перерисовки
    BOOL bErase		// режим перерисовки
);

Если первый параметр NULL, то будут перерисованы все окна. Если второй параметр NULL, то будет перерисована вся область окна. Последний параметр указывает на действия с фоном, если TRUE, то фон будет стерт, иначе оставлен. При удачном выполнении этой функции результат отличен от нуля.

Указанные области перерисовки накапливаются, пока не будет получено сообщение WM_PAINT или пока эта функция не будет отменена противоположной функцией ValidateRect(). Само сообщение WM_PAINT посылается при необходимости изменить область, но только когда нет в очереди других сообщений. При установке нескольких областей производится их объединение и обработка одним WM_PAINT.

69.gif (3205 b)

Типичная обработка сообщения в главной функции окна:

case WM_PAINT:
    hDC=BeginPaint(hWnd, &ps);
    /* операции вывода */
    EndPaint(hWnd, &ps);
break;
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 70 - Функция InvalidateRgn()

Аналогична функции InvalidateRect() по своей работе и функциональности:

BOOL InvalidateRgn
(
    HWND hWnd,		// окно
    HRGN hRgn,		// регион
    BOOL bErase		// тип перерисовке
);

Единственное отличие в том, что отменяется она функцией ValidateRgn(). Немного про регион. Регион - это любая область окна и не обязательно прямоугольная. Дополнительную информацию о регионах можно найти в следуюших шагах:

  • "Шаг 155 - Борьба с однообразием, круглое окно"
  • "Шаг 156 - О регионах (CRgn)"
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 71 - Z порядок окон

В Windows используется z порядок окон. Окна распологаются одно над другим по вертикали. Окно на верху лежит поверх всех. Нижнее окно в самом низу, остальные в промежутке. Для этого в Windows существует специальный список, в котором эти окна расположены. Важность окна зависит от стиля окна. Самую высокую важность имеет стиль WS_EX_TOPMOST.

Когда система создает окно она помещает это окно на самом верху относительно окон того же самого типа. Вы можете использовать функцию BringWindowToTop(), чтобы вывести окно наверх относительно окон того же самого типа. Вы можете реорганизовать порядок, используя функции DeferWindowPos() и SetWindowPos().

Функция GetNextWindow() возвращает указатель к следующему или предыдущему окну в Z-порядке. Для поиска подчиненных окон используется функция GetTopWindow().

Смотри также - "1.6 Z-последовательность (Z Order)".

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 72 - Функции GetWindowRect() и GetClientRect()

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

72.gif (2906 b)

Для получение прямоугольника приложения используется функция:

BOOL GetWindowRect
(
    HWND hWnd, 	// указатель на окно
    LPRECT lpRect 	// указатель на структуру с координатами
);

Результат возвращается в единицах экрана(т.е. пикселах) относительно левого верхнего угла экрана. Если функция выполнена удачно, то она вернет ненулевое значение.

Для получения области клиента используется функция:

BOOL GetClientRect
(
    HWND hWnd, 		// указатель на окно
    LPRECT lpRect   		// указатель на структуру с координатами
);

Координаты левого верхнего угла 0,0 так как результат возвращается относительно клиентской области. При удачном выполненинии вернется ненулевое значение.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 73 - Функция AdjustWindowRect()

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

BOOL AdjustWindowRect
(
    LPRECT lpRect,	// структура с данными о клиентской области
    DWORD dwStyle,	// стиль окна
    BOOL bMenu	// есть или нет меню
);

Результат вычислений вернется через туже структуру. При удачном выполнении результат возврата ненулевое значение. Правда эта функция не учитывает, что меню может быть в два ряда, если окно маленькое. Так же она не учитывает стили WS_VSCROLL или WS_HSCROLL. Для этого нужно вызывать GetSystemMetrics().

73.gif (2878 b)

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 74 - Функции GetCurrentDirectory() и SetCurrentDirectory()

Первая функция получает текущий каталог:

DWORD GetCurrentDirectory
(
    DWORD nBufferLength,	// размер буфера
    LPTSTR lpBuffer		// указатель на буфер
);

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

Вторая функция устанавливает текущий каталог:

BOOL SetCurrentDirectory
(
    LPCTSTR lpPathName		// имя каталога
);

Если все нормально, то функция вернет ненулевое значение, в противном случае нуль. Ну и пример что ли.

// TestDir.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    TCHAR buffer[MAX_PATH];
    GetCurrentDirectory(sizeof(buffer),buffer);
    cout << buffer << endl;
    SetCurrentDirectory("C:\\");
    GetCurrentDirectory(sizeof(buffer),buffer);
    cout << buffer << endl;
}

А вот результат у меня:

C:\VC\TestDir
C:\
Press any key to continue
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 75 - Rect - CopyRect()

Копирует один прямоугольник в другой:

BOOL CopyRect
{
    LPRECT lprcDst,		// сюда копируется
    CONST RECT *lprcSrc	// отсюда берется
);

Вернет ненулевое значение, если выполнена удачно. Пример:

// TestAPI.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    RECT r1;
    RECT r2;
    r1.bottom = 1;
    r1.left = 1;
    r1.right =1;
    r1.top = 100;
    CopyRect(&r2,&r1);
    cout << r2.top << endl;
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 76 - Rect - EqualRect()

Позволяет узнать являются ли два прямоугольника равными.

BOOL EqualRect
(
    CONST RECT *lprc1,	// указатель на первый прямоугольник
    CONST RECT *lprc2	// указатель на второй прямоугольник
);

Равные - это те прямоугольники, у которых точно совпадают вершины. Именно вершины, а не ширина и высота. Функция вернет ненулевое значение, если прямоугольники равные.

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    RECT r1;
    RECT r2;
    r1.bottom = 1;
    r1.left = 1;
    r1.right =1;
    r1.top = 100;
    r2.bottom = 1;
    r2.left = 1;
    r2.right =1;
    r2.top = 100;
    if (EqualRect(&r2,&r1)) cout << "==" << endl;
    else cout << "!=" << endl;
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 77 - Rect - InflateRect()

Изменяет размеры прямоугольника.

BOOL InflateRect
(
    LPRECT lprc,	// указатель на прямоугольник
    int dx,		// приращение ширины
    int dy		// приращение высоты
);

На самом деле ширина меняется в две стороны. Если внести отрицательные значения, то прямоугольник будет уменьшен.

77.gif (904 b)

При удачном выполнении функция вернет ненулевое значение.

// TestAPI.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    RECT r1;
    r1.bottom = 1;
    r1.left = 1;
    r1.right =1;
    r1.top = 100;
    InflateRect(&r1,10,0);
    cout << r1.left << " " << r1.right << endl;
}

Как вы думаете какой будет результат ???? Смотрите:

-9 11
Press any key to continue
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 78 - Rect - IntersectRect()

Выполняет пересечение прямоугольников.

BOOL IntersectRect
(
    LPRECT lprcDst,		// сюда будет выведен результат
    CONST RECT *lprcSrc1,	// первый прямоугольник
    CONST RECT *lprcSrc2	// второй прямоугольник
);

Если прямоугольники пересекаются, то возвращаемое значение ненулевое.

78.gif (956 b)

// TestAPI.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    RECT r1;
    RECT r2;
    RECT r3;
    r1.bottom = 100;
    r1.left = 1;
    r1.right =100;
    r1.top = 1;
    r2.bottom = 150;
    r2.left = 50;
    r2.right = 150;
    r2.top = 50;
    if (IntersectRect(&r3,&r2,&r1))
        cout << r3.left << " " << r3.right << endl;
    else
        cout << "Not intersect" << endl;
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 79 - Rect - IsRectEmpty()

Проверяет прямоугольник на пустоту (правильность).

BOOL IsRectEmpty
(
    CONST RECT *lprc	// прямоугольник
);

Проверка на пустоту - это проверка на правильность данных, которые находятся в структуре. Левая точка должна быть левее, а нижняя ниже. Это конечно тривиально, но такая проверка может понадобиться, например, при чтении прямоугольника с диска или операциях над ним. Функция ворачивает ненулевое значение, если прямоугольник пуст.

// TestAPI.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    RECT r1;

    r1.left = 100;
    r1.right = 1;
    r1.top = 1;
    r1.bottom = 10;

    if (IsRectEmpty(&r1))
        cout << "Empty" << endl;
    else
        cout << "Not Empty" << endl;
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 80 - Rect - OffsetRect()

OffsetRect меняет позицию прямоугольника без изменения его размера:

BOOL OffsetRect
(
    LPRECT lprc,	// прямоугольник
    int dx,		// горизонтальное смещение
    int dy		// вертикальное смещение
);

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

// TestAPI.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    RECT r1;

    r1.left = 1;
    r1.right = 100;
    r1.top = 1;
    r1.bottom = 10;
    OffsetRect(&r1,10,10);
    cout << r1.left << endl;
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 81 - Rect - PtInRect()

Определяет находится функция внутри прямоугольника или нет:

BOOL PtInRect
(
    CONST RECT *lprc,	// прямоугольник
    POINT pt		// точка
);

Одна тонкость. Эта Windows почему-то считает, что левая и верхняя грань внутри, а вот нижняя и правая нет. Если точка внутри, то вернется ненулевое значение.

// TestAPI.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    RECT r1;
    POINT p1;

    r1.left = 1;
    r1.right = 100;
    r1.top = 1;
    r1.bottom = 100;
    p1.x = 50;
    p1.y = 50;

    if (PtInRect(&r1,p1))
        cout << "Point in rect" << endl;
    else
        cout << "Point not in Rect" << endl;
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 82 - Rect - SetRect()

Устанавливает координаты прямоугольника. Очень удобно.

BOOL SetRect
(
    LPRECT lprc,	// прямоугольник
    int xLeft,	// левая
    int yTop,		// верхняя
    int xRight,	// правая
    int yBottom	// нижняя
);

В случае успешного выполнения вернется ненулевое значение:

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    RECT r1;
    SetRect(&r1,10,10,100,100);
    cout << r1.left << endl;
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 83 - Rect - SetRectEmpty()

Устанавливает пустой прямоугольник. Все значения устанавливаются в нуль.

BOOL SetRectEmpty
{
    LPRECT lprc		// указатель на прямоугольник
);

В случае успешного выполнения возвращается ненулевое значение.

// TestAPI.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    RECT r1;
    SetRectEmpty(&r1);
    cout << r1.left << " " << r1.top << " " << r1.bottom << " " << r1.top << endl;
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 84 - Rect - SubtractRect()

Вычитает один прямоугольник из другого.

BOOL SubtractRect
(
    LPRECT lprcDst,		// результирующий прямоугольник
    CONST RECT *lprcSrc1,	// первый прямоугольник
    CONST RECT *lprcSrc2	// второй прямоугольник
);

Чтобы эта функция правильно сработала два прямоугольник должны полностью пересекаться по одной стороне.

84.gif (1024 b)

При успешном выполнении функция возвращает ненулевое значение.

// TestAPI.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    RECT r1;
    RECT r2;
    RECT r3;

    SetRect(&r1,50,50,150,150);
    SetRect(&r2,100,70,120,100);
    SetRectEmpty(&r3);

    if (SubtractRect(&r3,&r2,&r1))
        cout << "OK Subtract" << endl;
    else
        cout << "Bad Subtract" << endl;

    SetRect(&r2,100,70,120,300);
    SetRectEmpty(&r3);

    if (SubtractRect(&r3,&r2,&r1))
        cout << "OK Subtract" << endl;
    else
        cout << "Bad Subtract" << endl;
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 85 - Rect - UnionRect()

Объединяет два прямоугольника в один.

BOOL UnionRect
(
    LPRECT lprcDst,		// прямоугольник с результатом
    CONST RECT *lprcSrc1,	// первый прямоугольник
    CONST RECT *lprcSrc2	// второй прямоугольник
);

Если прямоугольники объеденены, то вернется ненулевое значение.

85.gif (1631 b)

// TestAPI.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{

    RECT r1;
    RECT r2;
    RECT r3;

    SetRect(&r1,10,10,100,100);
    SetRect(&r2,90,10,150,100);
    SetRectEmpty(&r3);

    if (UnionRect(&r3,&r2,&r1))
        cout << r3.left << " " << r3.top << " " << r3.right
            << " " << r3.bottom << endl;
    else
        cout << "error union" << endl;
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 86 - Rect - Структура RECT

Эта структура определяет прямоугольник.

typedef struct _RECT
{
    LONG left;
    LONG top;
    LONG right;
    LONG bottom;
} RECT, *PRECT;

Внутри этой структуры координаты углов. Верхний левый угол определяется двумя координатами left и top. Нижний правый соответственно определяется вдумя оставшимися координатами right и bottom. Смотрите на рисунке:

86.gif (1346 b)

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 87 - Структуры POINT и POINTS

Эти две стуктуры определяют координаты x и y точки.

typedef struct tagPOINT
{
    LONG x;
    LONG y;
} POINT, *PPOINT;

typedef struct tagPOINTS
{
    SHORT x;
    SHORT y;
} POINTS, *PPOINTS;

Можно сказать, что структура POINTS это маленькая версия стуктуры POINT, так как значения координат X и Y можно задать в маленьком диапазоне, но при этом и памяти тратится на много меньше.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 88 - ClipCursor() и GetClipCursor()

Функция ClipCursor() устанавливает область передвижения курсора:

BOOL ClipCursor
(
    CONST RECT *lpRect	// ограничивающий прямоугольник
);

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

Вторая функция GetClipCursor() получает область передвижения курсора:

BOOL GetClipCursor
(
    LPRECT lpRect   // область ограничения курсора
);

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

// TestAPI.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    RECT r1;
    RECT r2;
    if (GetClipCursor(&r1))
    {
        SetRect(&r2,1,1,50,50);
        if (ClipCursor(&r2))
        {
            cout << "Clip Cursor" << endl;
            Sleep(10000);
            ClipCursor(&r1);
        }
        else cout << "Error Clip Cursor" << endl;
    }
    else cout << "Error GetClipCursor " << endl;
}

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

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 89 - SetCursorPos() и GetCursorPos()

Устанавливает курсор в определенную позицию на экране:

BOOL SetCursorPos
(
    int X,	// горизонтальная позиция
    int Y	// вертикальная позиция
);

При успешном выполнении функция вернет ненулевое значение.

Вторая функция получает позицию курсора на экране:

BOOL GetCursorPos
(
    LPPOINT lpPoint	// позиция курсора
);

При успешном выполнении функция вернет ненулевое значение.

Запустите пример ниже. Курсор убежит в левый верхний угол, после истечения времени вернется на место.

// TestAPI.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    POINT cp;
    GetCursorPos(&cp);
    SetCursorPos(0,0);
    Sleep(10000);
    SetCursorPos(cp.x,cp.y);
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 90 - CommConfigDialog настройка COM порта

Эта функция позволяет Вам вызвать стандартный диалог настройки портов. Этот диалог Вы можете увидеть из панели управления - система - порты - COM1.

Если Вам нужно дать пользователю возможность настроить порты. То не надо отправлять его в панель управления. Вызовите диалог. Для этого есть специальная функция CommConfigDialog():

BOOL CommConfigDialog
(
    LPCTSTR lpszName,		// имя устройства
    HWND hWnd,		// указатель на вызываемое окно
    LPCOMMCONFIG lpCC		// указатель на структуру дял информации
);

lpszName - это строка, которая указывает о каком порте мы говорим. В LpCC вернется информация, которая будет выбрана. Эта информация будет применена к порту и возвращена Вам. Вы можете ее анализировать и заставлять поменять что-то еще.

90_1.gif (4180 b)

Пример:

// TestComm.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    COMMCONFIG comm;
    CommConfigDialog("COM1",NULL,&comm);
}

А это результат:

90_2.gif (9433 b)

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 91 - Структура COMMPROP

Она большая:

typedef struct _COMMPROP
{
    WORD  wPacketLength;
    WORD  wPacketVersion;
    DWORD dwServiceMask;
    DWORD dwReserved1;
    DWORD dwMaxTxQueue;
    DWORD dwMaxRxQueue;
    DWORD dwMaxBaud;
    DWORD dwProvSubType;
    DWORD dwProvCapabilities;
    DWORD dwSettableParams;
    DWORD dwSettableBaud;
    WORD  wSettableData;
    WORD  wSettableStopParity;
    DWORD dwCurrentTxQueue;
    DWORD dwCurrentRxQueue;
    DWORD dwProvSpec1;
    DWORD dwProvSpec2;
    WCHAR wcProvChar[1];
} COMMPROP;

wPacketLength - Размер структуры в байтах.

wPacketVersion - Версия структуры.

dwServiceMask - Маска для коммуникационных портов SP_SERIALCOMM.

dwReserved1 - Не используется.

dwMaxTxQueue - Максимальный размер внутреннего буфера передачи, если равен нулю, то без ограничений.

DwMaxRxQueue - Максимальный размер внутреннего буфера приема.

DwMaxBaud - Максимальная скорость обмена принимает следующие значения:

BAUD_075 	75
BAUD_110 	110
BAUD_134_5 	134.5
BAUD_150 	150
BAUD_300 	300
BAUD_600 	600
BAUD_1200 	1200
BAUD_1800 	1800
BAUD_2400 	2400
BAUD_4800 	4800
BAUD_7200 	7200
BAUD_9600 	9600
BAUD_14400 	14400
BAUD_19200 	19200
BAUD_38400 	38400
BAUD_56K 	56K
BAUD_57600 	57600
BAUD_115200 	115200
BAUD_128K 	128K
BAUD_USER 	Пользовательская

DwProvSubType - Тип порта:

PST_FAX 		Факс
PST_LAT LAT 		протокол
PST_MODEM 		Модем
PST_NETWORK_BRIDGE 	Сетевой мост
PST_PARALLELPORT 	Параллельный порт
PST_RS232 		порт RS-232
PST_RS422 		Порт RS-422
PST_RS423 		Порт RS-423
PST_RS449 		Порт RS-449
PST_SCANNER 		Сканнер
PST_TCPIP_TELNET 	Протокол TCP/IP TelnetR
PST_UNSPECIFIED 	Неизвестное устройство
PST_X25 		Устройство стандарта X.25

DwProvCapabilities - Маска с возможностями устройства:

PCF_16BITMODE 		специальный 16-битный режим.
PCF_DTRDSR  		сигналы DTR\DSR.
PCF_INTTIMEOUTS 	межсимвольный тайм-аут.
PCF_PARITY_CHECK  	контроль четности.
PCF_RLSD  		определение наличия сигнала в приемной линии.
PCF_RTSCTS  		сигналы RTS\CTS.
PCF_SETXCHAR 		Поддерживаются задаваемые символы XON\XOFF.
PCF_SPECIALCHARS 	Поддерживаются спецсимволы.
PCF_TOTALTIMEOUTS 	Поддерживаются общие тайм-ауты (ожидаемое время).
PCF_XONXOFF 		Поддерживается XON/XOFF управление потоком.

DwSettableParams - Параметры, которые можно менять:

SP_BAUD 		Скорость обмена.
SP_DATABITS 		Бит в символе.
SP_HANDSHAKING 		Рукопожатие (управление потоком).
SP_PARITY 		Четность.
SP_PARITY_CHECK 	Контроль четности.
SP_RLSD 		Детектирование наличия сигнала в приемной линии.
SP_STOPBITS 		Количество стоповых бит.

DwSettableBaud - Допустимая скорость обмена.

WSettableData - Допустимые длины символов:

DATABITS_5 	5 бит
DATABITS_6 	6 бит
DATABITS_7 	7 бит
DATABITS_8 	8 бит
DATABITS_16 	16 бит
DATABITS_16Х 	Специальный широкий канал через аппаратную
            последовательную линию.

WSettableStopParity - Допустимые стоповые биты и режимы четности:

STOPBITS_10 	Один стоповый бит
STOPBITS_15 	Полтора стоповыx бита
STOPBITS_20 	Два стоповых бита
PARITY_NONE 	Без четности
PARITY_ODD 	Доплнение до нечетности
PARITY_EVEN 	Дополнение до четности
PARITY_MARK 	Бит четности всегда "1"
PARITY_SPACE 	Бит четности всегда "0"

DwCurrentTxQueue - Размер внутренней очереди передачи драйвера в байтах.

DwCurrentRxQueue - Размер внутренней очереди приема драйвера в байтах.

dwProvSpec1 - Данные зависящие от устройства.

dwProvSpec2 - Данные зависят от устройства.

wcProvChar - Данные зависят от устройства.

Размер wPacketLength играет немного непривычную роль. С помощью него можно узнать есть ли дополнительная информация. То есть, если Вы помощью GetCommProperties() получили данные и wPacketLength > sizeof(COMMPROP), то нужно выделять дополнительную память.

Эта дополнительная информация может быть структурой MODEMDEVCAPS, если тип устройства модем и находиться она будет на месте wcProvChar.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 92 - Структура DCB

Вот она какая большая и длинная:

typedef struct _DCB
{
    DWORD DCBlength;
    DWORD BaudRate;
    DWORD fBinary:1;
    DWORD fParity:1;
    DWORD fOutxCtsFlow:1;
    DWORD fOutxDsrFlow:1;
    DWORD fDtrControl:2;
    DWORD fDsrSensitivity:1;
    DWORD fTXContinueOnXoff:1;
    DWORD fOutX:1;
    DWORD fInX:1;
    DWORD fErrorChar:1;
    DWORD fNull:1;
    DWORD fRtsControl:2;
    DWORD fAbortOnError:1;
    DWORD fDummy2:17;
    WORD wReserved;
    WORD XonLim;
    WORD XoffLim;
    BYTE ByteSize;
    BYTE Parity;
    BYTE StopBits;
    char XonChar;
    char XoffChar;
    char ErrorChar;
    char EofChar;
    char EvtChar;
    WORD wReserved1;
} DCB;

DCBlength - длина структуры. Она необходима, так как мы передаем эту структуру в разные функции, кроме того можно контролировать ее корректность. Длина в байтах.

BaudRate - это поле отражает скорость передачи данных. Поле числовое. Скорости передачи могут быть разные. Можно указывать просто число. Но лучше использовать константу. Вот они:

CBR_110
CBR_300
CBR_600
CBR_1200
CBR_2400
CBR_19200
CBR_4800
CBR_9600
CBR_38400
CBR_56000
CBR_57600
CBR_14400
CBR_128000
CBR_115200
CBR_256000

FBinary - Режим двоичного обмена. Win32 не поддерживает недвоичный режим, поэтому данное поле всегда должно быть равно TRUE.

FParity - Режим проверки четности. Если указать TRUE, то четность будет проверяться.

FOutxCtsFlow - Режим слежения за сигналом CTS. Если это поле равно TRUE и сигнал CTS сброшен, передача данных приостанавливается до установки сигнала CTS. Используется для того, чтобы посылая данные можно было определить успевают ли их принимать.

FOutxDsrFlow - Включает режим слежения за сигналом DSR. Если это поле равно TRUE, то передача будет происходить только при наличии сигнала DSR:

FDtrControl - Режимы обмена DTR бывают следующие:

DTR_CONTROL_DISABLE 		Запрещает использование линии
DTR DTR_CONTROL_ENABLE 		Разрешает использование линии
DTR DTR_CONTROL_HANDSHAKE 	Включает специальный механизм восстановления связи,
                 который называется рукопожатие.

FDsrSensitivity - устанавливает влияние линии DSR. Если TRUE, то данные принимаются, если есть DSR.

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

FOutX - Реакция на переполнения буфера (XON/XOFF) при передаче. Есть следующие сигналы:

XoffChar приостановить поток
XonChar возобновить поток.
Если значение TRUE, то эти сигналы будут учтены.

fInX - Реакция на переполнения буфера (XON/XOFF) при приеме. Если TRUE, то мы будет принимать сигналы о том, когда в буфере мало места и когда достаточно.

FErrorChar - Устанавливает необходимость замены символов с ошибкой четности. Если TRUE, то будет произведена замена.

FNull - Что делать с нулевым байтом. Когда равна TRUE нулевой байт отбрасывается.

FRtsControl - Устанавливает режим управления потоком для сигнала RTS.

RTS_CONTROL_DISABLE Запрещает использование линии
RTS RTS_CONTROL_ENABLE Разрешает использование линии
RTS RTS_CONTROL_HANDSHAKE Устанавливается сигнал RTS когда приемный
                буфер заполнен менее, чем на половину, и сбрасывает,
                когда буфер заполняется более чем на три четверти.
RTS_CONTROL_TOGGLE Задает, что сигнал RTS установлен, когда есть
                данные для передачи, иначе сбрасывается.

FAbortOnError - Реакция на ошибки. Если это поле равно TRUE, драйвер прекращает все операции чтения/записи для порта при возникновении ошибки.

fDummy2 - Не используется.

wReserved - Не используется.

XonLim - Задает минимальное число символов в приемном буфере перед посылкой символа XON.

XoffLim - Определяет максимальное количество байт в приемном буфере перед посылкой символа XOFF. Максимально допустимое количество байт в буфере вычисляется вычитанием данного значения из размера приемного буфера в байтах.

ByteSize - Число бит в передаваемом байте.

Parity - Схема контроля четности:

EVENPARITY 	Дополнение до четности
MARKPARITY 	Бит четности всегда 1
NOPARITY 	Бит четности отсутствует
ODDPARITY 	Дополнение до нечетности
SPACEPARITY 	Бит четности всегда 0

StopBits - Количество стоповых бит.

ONESTOPBIT 	Один стоповый бит
ONE5STOPBIT 	Полтора стоповых бита
TWOSTOPBIT 	Два стоповых бита

XonChar - Задает символ XON используемый как для приема, так и для передачи.

XoffChar - Задает символ XOFF используемый как для приема, так и для передачи.

ErrorChar - Задает символ, использующийся для замены символов с ошибочной четностью.

EofChar - Задает символ, использующийся для сигнализации о конце данных.

EvtChar - Задает символ, использующийся для сигнализации о событии.

wReserved1 - Зарезервировано и не используется.

Часть этой структуры представлено в окне настроке портов.

92.gif (7820 b)

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 93 - Зачем нужна структура DCB ?

С помощью этой структуры у Вас есть возможность получать информацию из порта и передавать ее в порт. Посмотрите на схему ниже.

93.gif (7492 b)

Красным цветом отмечено получение информации, зеленым ее передача. Есть два варианта - это передача информации напрямую в порт или через HANDLE, который ассоциирован с портом. О том как это делается поговорим позднее. Структура DСB является сложенной для структуры COMMCONFIG, в которой есть дополнительная информация. Если Вы смотрели ее параметры, то их много и они пересекаются друг с другом. То есть, если с нуля устанавливать параметры, то это сложно, а мы бы хотели просто поменять скорость или проверку четности. Вот для этого структура и нужна. Общая идея такая:

  1. Получить текущую информацию в структуру DCB (функции GET)
  2. Изменить нужные нам параметры в структуре DCB.
  3. Установить параметры порта (функции SET)
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 94 - Функция BuildCommDCB()

Функция:

BOOL BuildCommDCB
(
    LPCTSTR lpDef,	// строка инициализации
    LPDCB lpDCB	// структура инициализации
);

Эта функция очень удобна вот в каком плане. Она устанавливает параметры структуры DCB, которую потом можно передать в порт практически также как команда mode. Если кто помнит MS DOS и Нуль модемный кабель и связь между двумя компьютерами. Так вот подаем строку, в ответ получаем структуру DCB. Пример строки.

baud=1200 parity=N data=8 stop=1

Пробуем ???

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    DCB dcb;
    ZeroMemory(&dcb,sizeof(DCB));
    char buffer[100];
    strcpy(buffer,"baud=1200 parity=N data=8 stop=1");
    if (BuildCommDCB((char*)&buffer,&dcb))
    {
        if (dcb.BaudRate == CBR_1200) cout << "Yes " << endl;
    }
    else cout << " error config DCB";
}

В случае успешного завершения функция BuildCommDCB() возвращает не нулевое значение, иначе ноль. Эта функция заменяет только явные поля. За некоторыми исключениями.

Для строк вида 9600,n,8,1 (не заканчивающихся символами x или p):

· fInX, fOutX,fOutXDsrFlow, fOutXCtsFlow устанавливаются в FALSE
· fDtrControl устанавливается в DTR_CONTROL_ENABLE
· fRtsControl устанавливается в RTS_CONTROL_ENABLE

Для строк вида 9600,n,8,1,x (заканчивающихся символом х):

· fInX, fOutX устанавливаются в TRUE
· fOutXDsrFlow,fOutXCtsFlow устанавливаются в FALSE
· fDtrControl устанавливается в DTR_CONTROL_ENABLE
· fRtsControl устанавливается в RTS_CONTROL_ENABLE

Для строк вида 9600,n,8,1,p (заканчивающихся символом p):

· fInX, fOutX устанавливаются в FALSE
· fOutXDsrFlow,fOutXCtsFlow устанавливаются TRUE
· fDtrControl устанавливается в DTR_CONTROL_HANDSHAKE
· fRtsControl устанавливается в RTS_CONTROL_HANDSHAKE
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 95 - А вы уверены, что это RS-232 ? GetCommProperties()

Функции рассмотренные ранее хороши, но они подразумевают, что вы знаете тип порта. Вы совершенно уверены, что все порты у Вас RS-232 ? Уверены ? А у пользователя ??? Тут может быть что угодно. Для получения более подробной информации используется функция GetCommProperties().

BOOL GetCommProperties
(
    HANDLE     hFile,		// указатель на порт
    LPCOMMPROP lpCommProp	// указатель на структуру COMMPROP
);

При удачном выполнении вернет ненулевое значение и заполненную структуру. Смотрим.

#include "windows.h"
#include "iostream.h"

void main()
{

COMMCONFIG  comm;
if (GetDefaultCommConfig("COM1",&comm,&comm.dwSize))
{
    switch  (comm.dwProviderSubType)
    {
    case  PST_FAX :
        cout << "FAX device " << endl;
        break;
    case  PST_LAT :
        cout << "LAT protocol" << endl;
           break;
    case  PST_MODEM :
        cout << "Modem device " << endl;
        break;
    case  PST_NETWORK_BRIDGE :
        cout << "Unspecified network bridge " << endl;
        break;
    case  PST_PARALLELPORT :
        cout << "Parallel port " << endl;
        break;
    case  PST_RS232 :
        cout << "RS-232 serial port " << endl;
        break;
    case  PST_RS422 :
        cout << "RS-422 port " << endl;
        break;
    case  PST_RS423 :
        cout << "RS-423 port " << endl;
        break;
    case  PST_RS449 :
        cout << "RS-449 port " << endl;
        break;
    case  PST_SCANNER :
        cout << "Scanner device " << endl;
        break;
    case  PST_TCPIP_TELNET :
        cout << "TCP/IP TelnetR protocol " << endl;
        break;
    case  PST_UNSPECIFIED :
        cout << "Unspecified " << endl;
        break;
    case  PST_X25 :
        cout << "X.25 standards " << endl;
        break;
    default :
        cout << "?????? Microsft mail please  ...." << endl;
        break;
    }
}
else cout << "Error access" << endl;
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 96 - Функции GetCommState() и SetCommSate()

Получаем информацию о порте, заполняя структуру DCB:

BOOL GetCommState
(
    HANDLE hFile,	// указатель  на устройство
    LPDCB lpDCB	// указатель на блок DCB
);

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

Вторая функция передает информацию порт:

BOOL SetCommState
(
    HANDLE hFile,	// указатель на порт
    LPDCB lpDCB	// указатель на DBC
);

Она точна такая же. Но тут надо быть внимательным. Ее можно вызывать и в ходе приема передачи, только она сработает даже если в буфере есть данные. И еще она завершится ошибкой, если в структуре DCB поля XonChar и XoffChar одинаковые.

Эти две функции удобно применять вместе при настройке порта. Получил информацию из порта (Get) внес изменения и установил новые значения (Set).

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 97 - CreateFile и HANDLE порта

Итак, функции для работы с портом используют указатель на порт. То есть Вы создаете этот указатель, и если он создан (не NULL), то используя его можно управлять устройством. Как раз CreateFile() и умеет создавать указатель для порта.

97.gif (7423 b)

Посмотрите на рисунок. Мы используем CreateFile() для получения HANDLE, с помощью которого потом и производим операции ввода-вывода на устройство. После работы его нужно закрыть CloseHandle(). Сама эта функция CreateFile() такая:

HANDLE CreateFile
(
    LPCTSTR lpFileName,
    DWORD dwDesiredAccess,
    DWORD dwShareMode,
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    DWORD dwCreationDistribution,
    DWORD dwFlagsAndAttributes,
    HANDLE hTemplateFile
);

В нашем случае lpFileName - это имя порта:

LPT1 , LPT2 и так далее
COM1, COM2, и так далее.

Переменная dwDesiredAccess - это атрибут доступа файлу. Он может принимать такие значения:

0 получить атрибут
GENERIC_READ чтение
GENERIC_WRITE запись
GENERIC_READ|GENERIC_WRITE чтение и запись

DwShareMode - совместный доступ, для данного случая доступа к портам всегда равен 0.

LpSecurityAttributes - атрибут защиты. Нужен для NT, в нашем случае всегда равен OPEN_EXISTING.

DwFlagsAndAttributes - атрибут создаваемого файла, в нашем случае должен быть 0.

HTemplateFile - файл шаблона, для нас всегда NULL.

Итак, для работы с портами нужно уставить только lpFileName, dwDesiredAccess, LpSecurityAttributes. При нормальном выполнении мы получим HANDLE, в противном случае NULL.

// TestComm.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    HANDLE Com2Port;
    Com2Port=CreateFile("COM2",GENERIC_READ|GENERIC_WRITE,0,
        NULL,OPEN_EXISTING,0,NULL);
    if(Com2Port!=INVALID_HANDLE_VALUE)
    {
        cout << "Open COM 2 " << endl;
        CloseHandle(Com2Port);
    } else
        cout << "Error Open COM2" << endl;
}

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

Занят.
Отсутствует.
Выведен из строя.
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 98 - Функция DLLMain()

Функция входа в DLL:

BOOL WINAPI DllMain
(
    HINSTANCE hinstDLL,	// указатель на модуль DLL
    DWORD fdwReason,		// флаг причины вызова функции
    LPVOID lpvReserved		// зарезервировано
);

Эта функция вызывается в нескольких случаях, причина вызова описана в fdwReason:

DLL_PROCESS_ATTACH	новый процесс имеет доступ к DLL
DLL_THREAD_ATTACH	новый поток получает доступ к DLL
DLL_THREAD_DETACH	последний поток отсоединяется от DLL
DLL_PROCESS_DETACH	один из потоков процесса отсоединяется от DLL

Если Вы хотите сами обрабатывать эти вызовы, то код должен быть примерно таким:

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
    switch( fdwReason ){
        case DLL_PROCESS_ATTACH:

            break;
        case DLL_THREAD_ATTACH:

            break;
        case DLL_THREAD_DETACH:

            break;
        case DLL_PROCESS_DETACH:

            break;
    }
    return TRUE;
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 99 - Функция Beep()

Эта функция воспроизводит звук.

BOOL Beep
(
    DWORD dwFreq,		// звуковая частота
    DWORD dwDuration		// длительность звучания
);

Воспроизводится по разному. В случае Win 98 воспроизводится системный звук SystemDefault, то есть эти параметры игнорируются. В Windows NT действительно воспроизводится указанный звук.

В случае успеха возвращает ненулевое значение.

// TestAPI.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    if (Beep(0,0))
        cout << "beep" << endl;
    else
        cout << "error beep" << endl;
}

У меня есть звуковая карта и ошибок воспроизведения не было. Может попробуете у кого нет ее ???

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 100 - Функция CharLower()

Конвертирует все символы из верхнего регистра к нижнему.

LPTSTR CharLower
(
    LPTSTR lpsz		// указатель на строку
);

Не возвращает информации об ошибках. Пример:

// TestAPI.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    char buffer[5];
    char *rez;
    strcpy(buffer,"HELLO");
    rez=CharLower(buffer);
    cout << rez << endl;
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 101 - Функция CharUpper()

Переводит символы в верхний регистр:

LPTSTR CharUpper
(
    LPTSTR lpsz   // указатель на строку
);

Не возвращает информации об ошибках. Пример:

// TestAPI.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    char buffer[5];
    char *rez;
    strcpy(buffer,"hello");
    rez=CharUpper(buffer);
    cout << rez << endl;
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 102 - Функции SysAllocString() и SysFreeString()

Функция SysAllocString() выделяет память и копирует туда строку:

BSTR SysAllocString
(
    const OLECHAR * sz		// строка
);

Предназначена для создания строк BSTR применяющихся в COM - OLE. Пример:

InitProperties[1].vValue.bstrVal = SysAllocString(OLESTR("C:\\test.mdb"));

После использования такая строка должна быть освобождена в помощью функции SysFreeString():

VOID SysFreeString
(
    BSTR  bstr
);
Пример:
// выделяем
InitProperties[1].vValue.bstrVal = SysAllocString(OLESTR("C:\\test.mdb"));
.......
// освобождаем
SysFreeString(InitProperties[1].vValue.bstrVal);
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 103 - Функция GetOEMCP()

Эта функция возвращает кодовую страницу OEM установленную на компьютере.

UINT GetOEMCP(void);

Коды возврата могут быть такими:

437 MS-DOS United States
708 Arabic (ASMO 708)
709 Arabic (ASMO 449+, BCON V4)
710 Arabic (Transparent Arabic)
720 Arabic (Transparent ASMO)
737 Greek (formerly 437G)
775 Baltic
850 MS-DOS Multilingual (Latin I)
852 MS-DOS Slavic (Latin II)
855 IBM Cyrillic (primarily Russian)
857 IBM Turkish
860 MS-DOS Portuguese
861 MS-DOS Icelandic
862 Hebrew
863 MS-DOS Canadian-French
864 Arabic
865 MS-DOS Nordic
866 MS-DOS Russian (former USSR)
869 IBM Modern Greek
874 Thai
932 Japan
936 Chinese (PRC, Singapore)
949 Korean
950 Chinese (Taiwan; Hong Kong SAR, PRC)
1361 Korean (Johab)

Пример:

// TestAPI.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    cout << GetOEMCP() << endl;
}

У меня оказалось 866. Почитав выше оказалось, что это прежняя CCCP. Мне то казалось, что про СССР уже забыли, а нет - Microsoft помнит.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 104 - Функция MessageBeep()

Проигрывает WAV файлы связанные с конкретной ситуацией.

BOOL MessageBeep
(
    UINT uType		// тип звука
);

Могут быть использованы следующие типы:

-1 стандартный динамик
MB_ICONASTERISK
MB_ICONEXCLAMATION
MB_ICONHAND
MB_ICONQUESTION
MB_OK

Пример:

// TestAPI.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#include "iostream.h"
void main()
{
    if (MessageBeep(-1 ))
        cout << "beep" << endl;
    else
        cout << "error beep" << endl;
}

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

104.gif (7123 b)

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 105 - Функция GetACP()

Получает кодовую страницу установленную на компьютере (ANSI).

UINT GetACP(VOID);

Возвращенное значений содержит код страницы. Они бывают следующими:

874 Thai
932 Japan
936 Chinese (PRC, Singapore)
949 Korean
950 Chinese (Taiwan; Hong Kong SAR, PRC)
1200 Unicode (BMP of ISO 10646)
1250 Windows 3.1 Eastern European
1251 Windows 3.1 Cyrillic
1252 Windows 3.1 Latin 1 (US, Western Europe)
1253 Windows 3.1 Greek
1254 Windows 3.1 Turkish
1255 Hebrew
1256 Arabic
1257 Baltic

Пример:

// TestAPI.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    cout << GetACP() << endl;
}

У меня 1251 как ни странно :-)

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 106 - Функция GetKeyboardState()

Копирует состояние 256 виртуальных клавиш в массив.

BOOL GetKeyboardState
(
    PBYTE lpKeyState	// указатель на массив
);

При успешном выполнении вернет ненулевое значение. Помимо обычных клавиш эта функция умеет различать и левые - правые Shift, Alt, Ctrl:

VK_LSHIFT
VK_RSHIFT
VK_LCONTROL
VK_RCONTROL
VK_LMENU
VK_RMENU

После получения массива можно пробежаться по нему и посмотреть какие клавиши включены.

// TestAPI.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    BYTE mass[256];
    if (GetKeyboardState((BYTE*)&mass))
        cout << "Get " << endl;
    else
        cout << "Error Get" << endl;
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 107 - Функция CreateDirectory()

Эта функция создает новую папку.

BOOL CreateDirectory
(
    LPCTSTR lpPathName,			// имя каталога
    LPSECURITY_ATTRIBUTES lpSecurityAttributes	// атрибуты безопасности
);

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

// TestAPI.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    if (CreateDirectory("c:\\new",NULL))
        cout << "directory create" << endl;
    else
        cout << "error create directory" << endl;
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 108 - Функция CreateDirectoryEx()

Расширенная функция создания каталога. Она создает каталог беря все атрибуты от каталога указанного как шаблон в том числе и атрибуты секретности.

BOOL CreateDirectoryEx
(
    LPCTSTR lpTemplateDirectory,		// каталог шаблон
    LPCTSTR lpNewDirectory,			// имя нового каталога
    LPSECURITY_ATTRIBUTES lpSecurityAttributes	// атрибут безопасности
);

В случае успешного выполнения вернет ненулевое значение. Посмотреть как это работает можно так, вот код:

// TestAPI.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    if (CreateDirectoryEx("c:\\temp","c:\\new",NULL))
        cout << "directory create" << endl;
    else
        cout << "error create directory" << endl;
}

Устанавливаем у каталога temp атрибут только чтение. Запускаем программу и смотрим атрибуты у вновь созданной папки.

Атрибут сохранился. Только не забудьте с temp снять атрибут "только для чтения", а то могут быть неприятности.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 109 - Функция RemoveDirectory()

Функция RemoveDirectory() удаляет каталог. Но каталог должен быть обязательно пустым.

BOOL RemoveDirectory
(
    LPCTSTR lpPathName		// имя каталога
);

В случае успеха функция ворачивает ненулевое значение.

// TestAPI.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    if (RemoveDirectory("c:\\new"))
        cout << "directory remove" << endl;
    else
        cout << "error remove directory" << endl;
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 110 - Аудит каталогов FindFirstChangeNotification()

Windows 98 как и Windows NT позволяет Вам установить аудит каталога с помощью функции FindFirstChangeNotification. Вот она:

HANDLE FindFirstChangeNotification
(
    LPCTSTR lpPathName, 	// путь к каталогу
    BOOL bWatchSubtree, 	// флаг управления
    DWORD dwNotifyFilter	// флаги событий
);

С первым параметром понятно. Флагом управления может быть значение TRUE или FALSE. От него зависит будут ли события генерироваться только для каталога FALSE или для каталога и всех подкаталогов - TRUE. Второй параметр это флаги, с помощью которых можно установить типы событий, на которых будет генерироваться событие.

FILE_NOTIFY_CHANGE_FILE_NAME | Изменение имен файлов, расположенных в указанном каталоге и его подкаталогах, создание и удаление файлов
FILE_NOTIFY_CHANGE_DIR_NAME | Изменение имен каталогов, создание и удаление каталогов
FILE_NOTIFY_CHANGE_ATTRIBUTES | Изменение атрибутов
FILE_NOTIFY_CHANGE_SIZE | Изменение размеров файлов (после записи содержимого внутренних буферов на диск)
FILE_NOTIFY_CHANGE_LAST_WRITE | Изменение времени записи для файлов (после записи содержимого внутренних буферов на диск)
FILE_NOTIFY_CHANGE_SECURITY | Изменение дескриптора защиты

Давате попробуем. Делайте приложение на основе MFC AppWizard на базе диалогового окна с одной кнопкой. При нажатии на эту кнопку будет устанавливаться аудит.

void CTestNotDlg::OnButton1()
{
    HANDLE hDir;
    hDir=FindFirstChangeNotification("c:\\Test1\\",
        TRUE,FILE_NOTIFY_CHANGE_FILE_NAME);
    if (hDir==INVALID_HANDLE_VALUE)
        AfxMessageBox("Не могу следить за каталогом");

    while (WaitForSingleObject(hDir,10000)!=WAIT_OBJECT_0)
    {
    }

    AfxMessageBox("с каталогом работают");
    FindCloseChangeNotification(hDir);
}

Мы создали указатель на объект каталога, аудит которого будем проводить FindFirstChangeNotification(), а потом ждем сообщения от каталога WaitForSingleObject при его получении выводим сообщение на экран и закрываем указатель FindCloseChangeNotification().

BOOL FindCloseChangeNotification
(
    HANDLE hChangeHandle	// указатель на объект
);

Если нужно следить постоянно, например, чтобы вести LOG файл, то нужно вызывать функцию:

BOOL FindNextChangeNotification
{
    HANDLE hChangeHandle	// указатель на объект
);

Для получения информации о следующем событии. Эта функция переводит объект в первоначальное состояние и им можно пользоваться в дальнейшем для обнаружения сообщений. Если Вы внимательно посмотрели код, то увидели, что функция FindFirstChangeNotification() не получает сообщение, а только создает объект, которому эти сообщения будут посланы.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 111 - Отображение файлов в память

Самый главный вопрос - это зачем нужно отображать файлы на память ? Ведь есть виртуальная память до 2 ГБ. Одна из причин это обеспечение работы с файлами большего размера. Второе преимущество при работе с большими файлами, что память не выделяется, а резервируется и при обращении к ней происходит подгрузка из файла. Этот механизм используется операционной системой, например, при работе с DLL. Общий набор функций по работе с отображаемыми файлами представлен на диаграмме.

111.gif (2091 b)

Сначала файл открывается с помощью CreateFile(), и если открытие прошло успешно, то идентификатором файла можно воспользоваться для создания отображенного файла CreateFileMapping(), после которой мы получим идентификатор отраженного файла, на основе которого мы можем проецировать файл в память с помощью функции MapViewOfFile(). Эта функция даст нам указатель LPVOID, который используется для последующих операций, в том числе и по отмене проецированного файла UnmapViewOfFile() или принудительной записи на диск FlushViewOfFile(). В том случае, если с отображенным файлом будут работать несколько приложений одно приложение создает файл проецированный на память CreateFileMaping(), а остальные открывают эту проекцию OpenFileMapping().

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 112 - SuspendThread() и ResumeThread()

Эти две функции позволяют приостанавливать и возобновлять выполнение задач(потоков). Для приостановке потока используется следующая функция:

DWORD SuspendThread
(
    HANDLE hThread		// указатель на поток
);

При успешном выполнении вернется предыдущая задержка. А для возобновления:

DWORD ResumeThread
(
    HANDLE hThread		// указатель на поток
);

При успешном выполнении вернется предыдущая задержка. Обе эти функции в случае неудачи вернут -1.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 113 - VirtualAlloc() и VirtualFree()

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

LPVOID VirtualAlloc
(
    LPVOID lpAddress,		// базовые адрес
    SIZE_T dwSize,		// размер
    DWORD flAllocationType,	// способ получения
    DWORD flProtect		// тип доступа
);

lpAddress - задает начальный адрес. При этом адрес округляется до ближайшей границы блока размером 64 Кбайт. Это значение можно задать NULL и тогда операционная система сама выберет этот адрес.

DwSize - размер памяти. Но эта величина очень специфичная. Память выделяется блоками по 4096 байт и соответственно указанный размер будет округляться до этого числа. Выделяете память например 10 байт, а получите 4096, а если выделяете например 5000, то будет выделено памяти в 8192 байта. Округление естественно идет в сторону увеличения.

FlAllocationType - способ получения, он может быть следующим:

  • MEM_COMMIT - Выполняется выделение страниц памяти для непосредственной работы с ними. Выделенные страницы заполняются нулями.
  • MEM_TOP_DOWN - Память выделяется в области верхних адресов адресного пространства приложения.

Как видите мы можем получить память, зарезервировать.

FlProtect - устанавливает тип доступа:

  • PAGE_READWRITE - Чтение и запись.
  • PAGE_READONLY - Только чтение.
  • PAGE_EXECUTE - Только исполнение программного кода.
  • PAGE_EXECUTE_READ - Исполнение и чтение.
  • PAGE_EXECUTE_READWRITE - Исполнение, чтение и запись.
  • PAGE_NOACCESS - Запрещен любой вид доступа.
  • PAGE_GUARD - Сигнализация доступа к странице. Это значение можно использовать вместе с любыми другими, кроме PAGE_NOACCESS.
  • PAGE_NOCACHE - Отмена кэширования для страницы памяти. Используется драйверами устройств. Это значение можно использовать вместе с любыми другими, кроме PAGE_NOACCESS.

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

Функция VirtualFree освобождает выделенную память.

BOOL VirtualFree
(
    LPVOID lpAddress,	// адресс памяти
    SIZE_T dwSize,	// рамер памяти
    DWORD dwFreeType	// операция
);

dwSize - размер, если мы будем использовать тип освобождения, как MEM_RELEASE, то размер должен быть установлен в 0.

dwFreeType - будет определять какая операция произойдет с памятью:

  • MEM_RELEASE - освобождена
  • MEM_DECOMMIT - зарезервированные, но не используемые.

При успешном выполнении функция вернет ненулевое значение.

Давайте посмотрим пример.

// testAlloc.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

#define MEMSIZE 4000

void main()
{
    void *p=NULL;
    p=VirtualAlloc(NULL,MEMSIZE,MEM_RESERVE,PAGE_READWRITE);
    if (p!=NULL)
    {
        cout << "OK Alloc " << endl;
        if (VirtualFree(p,0,MEM_RELEASE))
            cout << "Ok Free";
        else
            cout << "Not Free" << endl;
    }
    else
        cout << "Error Alloc " << endl;
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 114 - VirtualLock() и VirtualUnlock()

Виртуальная память сама по себе не очень быстрая, так как она может находиться на диске. Есть ряд задач, для которых необходимо иметь участок памяти с максимально быстрым доступом. Функция VirtualLock() позволят предотвратить запись памяти на диск.

BOOL VirtualLock
(
    LPVOID lpAddress,	// адрес начала памяти
    SIZE_T dwSize	// количество байтов
);

Если фиксация больше не нужна, то ее можно убрать функцией VirtualUnlock().

BOOL VirtualUnlock
(
    LPVOID lpAddress,	// адрес начала памяти
    SIZE_T dwSize	// количество байтов
);

При успешном выполнении обе функции возвращают ненулевое значение.

Смотрим пример:

// testAlloc.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

#define MEMSIZE 4000

void main()
{
    void *p=NULL;
    p=VirtualAlloc(NULL,MEMSIZE,MEM_RESERVE,PAGE_READWRITE);
    if (p!=NULL)
    {
        if (VirtualLock(p,MEMSIZE))
            cout << "Lock" << endl;
        else
            cout << "Error Lock" << endl;
        cout << "Press key and Enter- ";
        char i;
        cin >> i;

        if (VirtualUnlock(p,MEMSIZE))
            cout << "Unlock" << endl;
        else
            cout << "Error Unlock" << endl;
        cout << "OK Alloc " << endl;

        if (VirtualFree(p,0,MEM_RELEASE))
            cout << "Ok Free" << endl;
        else
            cout << "Not Free" << endl;
    }
    else
        cout << "Error Alloc " << endl;
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 115 - Состояние виртуальной памяти

Виртуальная память может находиться в следующих состояниях:

Free - свободная
Reserved - зарезервированная
Committed - выделенная

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

Управление типом памяти обеспечивает функция VirtualAlloc() с параметрами:

MEM_RESERVE - резервировать
MEM_COMMIT - выделить

Удалять страницы и переводить их в резервное состояние позволяет VirtualFree():

MEM_RELEASE - освободить
MEM_DECOMMIT - зарезервировать

Общая схема изменения памяти.

115.gif (3288 b)

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 116 - EnterCriticalSection, LeaveCriticalSection и InitializeCriticalSection

Очень полезно сначала прочитать "Шаг 80 - Что такое критическая секция (Critical Section)", так как именно эти функции относятся к критической секции. Давайте посмотрим пример. Следующий код выполянет ряд действий над массивом.

// TestCritical.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

#define MAX_ARRAY 5

int array[MAX_ARRAY];

void EmptyArray();
void PrintArray();
void FullArray();

void main()
{
    EmptyArray();
    PrintArray();
    FullArray();
    PrintArray();
    EmptyArray();
    PrintArray();
}

void EmptyArray()
{
    for (int x=0;x<(MAX_ARRAY+1); x++) array[x]=0;
    Sleep(1000);
}

void PrintArray()
{
    for (int x=0;x<(MAX_ARRAY+1); x++)
        cout << array[x] << " ";
    cout << endl;
    Sleep(1000);
}

void FullArray()
{
    for (int x=0;x<(MAX_ARRAY+1); x++) array[x]=x;
    Sleep(1000);
}

В данном примере все нормально. У нас всего один поток. Этот поток последовательно выполнит все действия над распределенным объектом array. Почему он распределенный ? Потому, что он определен глобально и к нему можно обратиться в любой момент. Так вот, если у нас будет несколько потоков все станет сложнее. Одна фунция не успеет очистить массив, а вторая может уже начать писать или печатать не до конца очищенный массив. Вот для решения этих проблем и используются критические секции. В тот код, который правит распределенный ресурс и является критической секцией. Для объявления начала критической секции используется функция.

VOID EnterCriticalSection
(
    LPCRITICAL_SECTION lpCriticalSection
        // указатель на переменную критическая секция
);

А для выхода из критической секции.

VOID LeaveCriticalSection
(
    LPCRITICAL_SECTION lpCriticalSection
        // указатель на переменную критическая секция
);

Для работы с критической секцией нам нужна переменная типа - критическай секция. Вот она:

CRITICAL_SECTION

Перед тем как использовать критическую секцию ее надо проинициализировать.

VOID InitializeCriticalSection
(
    LPCRITICAL_SECTION lpCriticalSection
        // указатель на переменную критическая секция
);

Давайте переделаем наш пример в многопоточное приложение с критическими секциями.

// TestCritical.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"
#include "process.h"

#define MAX_ARRAY 5

CRITICAL_SECTION critsect;

int array[MAX_ARRAY];

void EmptyArray(void *);
void PrintArray(void *);
void FullArray(void *);

void main()
{

    InitializeCriticalSection(&critsect);
    if (_beginthread(EmptyArray,1024,NULL)==-1)
        cout << "Error begin thread " << endl;
    if (_beginthread(PrintArray,1024,NULL)==-1)
        cout << "Error begin thread " << endl;
    if (_beginthread(FullArray,1024,NULL)==-1)
        cout << "Error begin thread " << endl;
    if (_beginthread(PrintArray,1024,NULL)==-1)
        cout << "Error begin thread " << endl;
    if (_beginthread(EmptyArray,1024,NULL)==-1)
        cout << "Error begin thread " << endl;
    if (_beginthread(PrintArray,1024,NULL)==-1)
        cout << "Error begin thread " << endl;
    Sleep(10000);
}

void EmptyArray(void *)
{
    cout << "EmptyArray" << endl;
    EnterCriticalSection(&critsect);
    for (int x=0;x<(MAX_ARRAY+1); x++) array[x]=0;
    Sleep(1000);
    LeaveCriticalSection(&critsect);
    _endthread();
}

void PrintArray(void *)
{
    cout << "PrintArray" << endl;
    EnterCriticalSection(&critsect);
    for (int x=0;x<(MAX_ARRAY+1); x++) cout << array[x] << " ";
    cout << endl;
    Sleep(1000);
    LeaveCriticalSection(&critsect);
    _endthread();
}

void FullArray(void *)
{
    cout << "FullArray" <<
 endl;
    EnterCriticalSection(&critsect);
    for (int x=0;x<(MAX_ARRAY+1); x++) array[x]=x;
    Sleep(1000);
    LeaveCriticalSection(&critsect);
    _endthread();
}

Результат работы будет вот такой:

EmptyArray
PrintArray
FullArray
PrintArray
EmptyArray
PrintArray
0 0 0 0 0 0
0 1 2 3 4 5
0 0 0 0 0 0

Потоки запускаются, начинается доступ к критичекой секции. Дожидаются своей очереди и выполняют необходимые действия. Не забудьте установиь опции многопоточного проекта, как в шаге ActiveX: "Шаг 78 - Что понимается под условиями гонки (rase condition) ?".

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 117 - CreateSemaphore, ReleaseSemaphore

Очень полезно сначало прочитать MSDN: "Шаг 81 - Что такое семафоры (Semaphore)". Создается семафор функцией CreateSemaphore():

HANDLE CreateSemaphore
(
    LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,	// атрибут доступа
    LONG lInitialCount,			// инициализированное начальное состояние счетчика
    LONG lMaximumCount,			// максимальное количество обращений
    LPCTSTR lpName				// имя объекта
);

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

BOOL ReleaseSemaphore
(
    HANDLE hSemaphore,		// хенд семафора
    LONG lReleaseCount, 	// на сколько изменять счетчик
    LPLONG lpPreviousCount	// предыдущее значение
);

При успешном выполнении возвращаемое значение ненулевое. Для уничтожения семафора нужно вызвать CloseHandle(). Давайте рассмотрим пример. Вот он:

// TestSemaphore.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#include "iostream.h"
#include "process.h"

HANDLE hSemaphore;
LONG cMax = 2;

void Test1(void *);
void Test2(void *);
void Test3(void *);

void main()
{
    hSemaphore = CreateSemaphore(
        NULL,	// нет атрибута
        cMax,	// начальное состояние
        cMax,	// максимальное состояние
        NULL	// без имени
    );

    if (!hSemaphore == NULL)
    {
        if (_beginthread(Test1,1024,NULL)==-1)
            cout << "Error begin thread " << endl;
        if (_beginthread(Test2,1024,NULL)==-1)
            cout << "Error begin thread " << endl;
        if (_beginthread(Test3,1024,NULL)==-1)
        cout << "Error begin thread " << endl;
        Sleep(10000);
        CloseHandle(hSemaphore);
    }
    else
        cout << "error create semaphore" << endl;
}

void Test1(void *)
{
    cout << "Test1 Running" << endl;
    DWORD dwWaitResult;
    while(dwWaitResult!=WAIT_OBJECT_0)
    {
        dwWaitResult = WaitForSingleObject(
            hSemaphore,	// указатель на семафор
            1		// интерфал ожидания
        );
        cout << "Test 1 TIMEOUT" << endl;
    }
    Sleep(1000);
    if (ReleaseSemaphore(
            hSemaphore,	// указатель на светофор
            1,		// изменяет счетчик на 1
            NULL)
    )
    cout << " ReleaseSemaphore Ok Test1" << endl;
    _endthread();
}

void Test2(void *)
{
    cout << "Test2 Running" << endl;
    DWORD dwWaitResult;
    while(dwWaitResult!=WAIT_OBJECT_0)
    {
        dwWaitResult = WaitForSingleObject(hSemaphore,1);
        cout << "Test 2 TIMEOUT" << endl;
    }
    Sleep(1000);
    if (ReleaseSemaphore(hSemaphore,1,NULL))
        cout << " ReleaseSemaphore Ok Test2" << endl;
    _endthread();
}

void Test3(void *)
{
    cout << "Test2 Running" << endl;
    DWORD dwWaitResult;
    while(dwWaitResult!=WAIT_OBJECT_0)
    {
        dwWaitResult = WaitForSingleObject(hSemaphore,1);
        cout << "Test 3 TIMEOUT" << endl;
    }
    if (ReleaseSemaphore(hSemaphore,1,NULL))
        cout << " ReleaseSemaphore Ok Test3" << endl;
    _endthread();
}

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

.......
Test 3 TIMEOUT
Test 3 TIMEOUT
Test 3 TIMEOUT
Test 3 TIMEOUT
 ReleaseSemaphore Ok Test1
Test 3 TIMEOUT
 ReleaseSemaphore Ok Test2
 ReleaseSemaphore Ok Test3
Press any key to continue

Как видите третий поток ждет. И как только освободился семафор он может дальше что-то делать.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 118 - Функции CreateMutex() и ReleaseMutex()

Очень полезно сначала прочитать MSDN: "Шаг 82 - Что такое взаимоисключение (Mutex)". Создается Mutex функцией CreateMutex():

HANDLE CreateMutex
(
    LPSECURITY_ATTRIBUTES lpMutexAttributes,	// атрибут безопастности
    BOOL bInitialOwner,			// флаг начального владельца
    LPCTSTR lpName				// имя объекта
);

Результатом будет дескриптор объекта mutex, если такое имя есть, то дескпритор существующего. Функция GetLastError() при вызове будет выдавать ERROR_ALREADY_EXISTS.

Для освобождения объекта нужно вызвать функцию ReleaseMutex():

BOOL ReleaseMutex
(
    HANDLE hMutex	// дескриптор mutex
);

При успешном выполнении вернет ненулевое значение.

По окончанию дескриптор нужно закрыть вызвав CloseHandle(). Давайте посмотрим пример использования Mutex для запрета запуска двух приложений. Я упоминал об этом в API: "Шаг 42 - Функция WinMain()".

// CreateMutex.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    HANDLE mut;
    mut = CreateMutex(NULL, FALSE, "FirstStep");
    DWORD result;
    result = WaitForSingleObject(mut,0);
    if (result == WAIT_OBJECT_0)
    {
        cout << "programm running" << endl;
        int i;
        cin >> i;
        ReleaseMutex(mut);
    }
    else
        cout << "fail programm running" << endl;
    CloseHandle(mut);
}

При запуске программы она создает объект с именем "FirstStep", если захватить его удается WaitForSingleObject(), то программа выполняется якобы, ждет пока Вы введете число и нажмете Enter. Если захватить его не удается, то выходит с надписью fail. Если Вы попробуете, то Вы сможете запустить только одну копию.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 119 - Функции CreateEvent(), SetEvent(), ResetEvent()

Очень полезно сначало прочитать "Шаг 83 - Что такое События (Event) синхронизации". Создается объект событие функцией CreateEvent():

HANDLE CreateEvent
(
    LPSECURITY_ATTRIBUTES lpEventAttributes,	// атрибут защиты
    BOOL bManualReset,				// тип сброса TRUE - ручной
    BOOL bInitialState,			// начальное состояние TRUE - сигнальное
    LPCTSTR lpName				// имя обьекта
);

Если функция успешна, то вернется дескриптор события. В том случае, если с таким именем событие уже создано, то вернется дескриптор уже созданного события, а GetLastError() вернет код ERROR_ALREADY_EXISTS. Но функция может вернуть и NULL, если объект события создать не удалось совсем. Функция SetEvent() меняет состояние на сигнальное (есть событие).

BOOL SetEvent
(
    HANDLE hEvent		// дескриптор события
);

В случае успеха вернет ненулевое значение. А функция ResetEvent() меняет состояние на невыделенное (нет события):

BOOL ResetEvent
(
    HANDLE hEvent		// дескриптор события
);

Пример смотрим.

// TestEvent.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"
#include "process.h"

HANDLE event;

void Test1(void *);
void Test2(void *);
void Test3(void *);

void main()
{
    event=CreateEvent(NULL,TRUE,FALSE,"FirstStep");
    if (_beginthread(Test1,1024,NULL)==-1)
        cout << "Error begin thread " << endl;
    if (_beginthread(Test2,1024,NULL)==-1)
        cout << "Error begin thread " << endl;
    if (_beginthread(Test3,1024,NULL)==-1)
        cout << "Error begin thread " << endl;
    if (event!=NULL){
        Sleep(1000);
        SetEvent(event);
        Sleep(1000);
        ResetEvent(event);
        CloseHandle(event);
    } else {
        cout << "error create event" << endl;
    }

}

void Test1(void *)
{
    DWORD dwWaitResult;
    while(dwWaitResult!=WAIT_OBJECT_0) {
        dwWaitResult = WaitForSingleObject(event,1);
        cout << "Test 1 TIMEOUT" << endl;
    }
    cout << "Event Test 1 " << endl;
    _endthread();
}

void Test2(void *)
{
    DWORD dwWaitResult;
    while(dwWaitResult!=WAIT_OBJECT_0){
        dwWaitResult = WaitForSingleObject(event,1);
        cout << "Test 2 TIMEOUT" << endl;
    }
    cout << "Event Test 2 " << endl;
    _endthread();
}

void Test3(void *)
{
    DWORD dwWaitResult;
    while(dwWaitResult!=WAIT_OBJECT_0){
        dwWaitResult = WaitForSingleObject(event,1);
        cout << "Test 3 TIMEOUT" << endl;
    }
    cout << "Event Test 3 " << endl;
    _endthread();
}

Создает объект Event, запускает три потока. Каждый поток ждет когда объект синхронизации перейдет в сигнальное состояние. После некоторой задержки устанавливаем его в сигнальное состояние SetEvent(), выжидаем некоторое время, чтобы потоки среагировали и сбрасываем ResetEvent(). Обратите внимание, что в данном случае в отличии от всех других объектов синхронизации потоков может быть любое количество.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 120 - HeapCreate и HeapDestroy

Эти две функции позволяют создавать и разрушать частную кучу. Смотрим функцию создания кучи.

HANDLE HeapCreate
(
    DWORD flOptions,		// атрибуты
    SIZE_T dwInitialSize,	// начальный размер
    SIZE_T dwMaximumSize	// конечный размер
);

Атрибутов всего два:

  • HEAP_GENERATE_EXCEPTIONS - Говорит о том, что в случае ошибки нужно генерировать структурную исключительную ситуацию вместо возврата NULL.
  • HEAP_NO_SERIALIZE - указатель на то, что куча не должна синхронизировать доступ.

При указании максимального размера можно указать 0 что будет говорить о том что максимальный размер будет ограничен только размером виртуальной памяти.

Результат зависит от флага либо исключение, либо NULL.

А вот функция удаления кучи.

BOOL HeapDestroy
(
    HANDLE hHeap	// указатель на кучу
);

Если выполнение удачно, то будет возвращено ненулевое значение. Смотрим пример создания и удаления кучи.

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    HANDLE hHeap;			// указатель на кучу
    hHeap=HeapCreate(0,0x01000,0);	// создать
    if (hHeap!=NULL)			// если создана удачно
    {
        // Разрушить и сообщить в случае ошибки
        if (HeapDestroy(hHeap)==0)
            cout << "Error delete Heap" << endl;
    }
    else
        cout << "Error Create Heap" << endl;
}
Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 121 - HeapAlloc и HeapFree

Создав кучу, есть возможность выделить в ней память.

LPVOID HeapAlloc
(
    HANDLE hHeap,	// указатель на кучу где можно выделить память
    DWORD dwFlags,	// флаги
    SIZE_T dwBytes	// обьем выделяемой памяти
);

Флаги могут быть следующие:

  • HEAP_GENERATE_ EXCEPTIONS - при ошибке будет исключение вместо NULL
  • HEAP_NO_SERIALIZE - доступ доложен быть не синхронизированный
  • HEAP_ZERO_MEMORY - установить содержимое выделяемой памяти в 0

При успешном выполнении возвращается указатель на память, а при ошибке либо NULL, либо исключение.

Для освобождения памяти используется функция HeapFree:

BOOL HeapFree
(
    HANDLE hHeap,	// указатель на кучу
    DWORD dwFlags,	// флаги
    LPVOID lpMem	// указатель на память
);

Флаг может быть HEAP_NO_SERIALIZE что бы отключить механизмы синхронизации. При успешном выполнении возвращаемое значение ненулевое.

Смотрим пример:

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{

    HANDLE hHeap;			// указатель на кучу
    hHeap=HeapCreate(0,0x01000,0);	// создать
    if (hHeap!=NULL)			// если создана удачно
    {
        char *strName=NULL;			// указатель на память
        strName=(char*)HeapAlloc(hHeap,0,100);	// выделить в нашей памяти место
        if (strName!=NULL)				// если удачно
        {
            // Разрушить и сообщить в случае ошибки
            if (HeapFree(hHeap,0,strName)==0)
                cout << "Error Free" << endl;
        }

        // Разрушить и сообщить в случае ошибки
        if (HeapDestroy(hHeap)==0)
            cout << "Error delete Heap" << endl;
    }
    else
        cout << "Error Create Heap" << endl;
}
Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 122 - __declspec

Спецификация Microsoft

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

allocate("segname")		// определяет сегмент данных для распределения
dllimport				// экспортируемое из DLL
dllexport				// импортируемое в DLL
naked				// генерация кода без оболочки функций
noreturn				// функция не имеет возврата
nothrow				// в функции не будет исключений
novtable				// у класса не будет виртуальной таблицы
property({get=get_func_name|, put=put_func_name})	// для виртуальных членов в классах т структурах.
selectany				// для оптимизации переменных
thread				// для локальных переменных потока
uuid("ComObjectGUID")		//Компилятор прилагает GUID к классу или структуре

Применение этого ключевого слова требует опыта. Если с импортом, экспортом более менее понятно, то зачем говорить, например что у функции не будет исключений nothrow? Тут надо знать, что если функция может вызвать исключение, то к ней дописывается определенный код. А вот применение этого ключевого слова этот код удаляет. Вроде как функция будет меньше. Или когда виртуальной таблицы нет novtable, то же будет меньше.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 123 - Использование dllimport и dllexport для создания и использования DLL

Как Win32 Dynamic Link Library. Дальше выбрать Simple DLL project c именем DllNew. Используя спецификацию Microsoft __declspec и эти два ключевые слова у нас есть возможность создавать DLL без DEF файлов.

Итак, для того, что бы из DLL экспортировать функцию ее нужно определить как.

//
//  DLLdefine.h
//
void __declspec(dllexport) Test();

Ну и реализовать, конечно:

// DllNew.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "DLLdefine.h"
BOOL APIENTRY DllMain( HANDLE hModule,
        DWORD ul_reason_for_call,
        LPVOID lpReserved)
{
    return TRUE;
}

void __declspec(dllexport) Test()
{
    MessageBox(NULL,"TestDLL","First Step",MB_OK);
}

После сборки проекта у нас будет lib файл и заголовочный файл DLLdefine.h. Для того, что бы использовать этот заголовочный файл в проекте для работы с DLL нам нужно его поменять. Ведь там стоит dllexport а нужно dllimport. Как быть ? Выход в применении условной компиляции. Заведем в DLL проекте объявление которое будет говорить нам где проводиться компиляция.

// DllNew.cpp : Defines the entry point for the DLL application.
//
#define COMPILE_DLL_XHTYE102474
#include "stdafx.h"

И вот теперь изменим заголовочный файл.

//
//   DLLdefine.h
//
#ifdef COMPILE_DLL_XHTYE102474
    void __declspec(dllexport) Test();
#else
    void __declspec(dllimport) Test();
#endif

Смысл этого всего в том, что если компиляции производиться из проекта с DLL то выбирается dllexport. А если из программы которая использует DLL то dllimport. Ну вот а теперь можно создать простое консольное приложение, пусть оно будет GetDll. И использовать этот заголовочный файл. Не забудете про LIB и доступ к DLL.

// GetDll.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "DLLdefine.h"

int main(int argc, char* argv[])
{
    Test();
    return 1;
}
Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 124 - Раздел с общими данными в DLL

Так как DLL находиться в адресном пространстве процесса который ее использует возникает проблеме с общими данными которые могут быть нужны всех процессов. Например в самой DLL подсчитывать количество к ней обращений. К счастью это легко решается. Нужно просто определить данные в общем модуле. Но использовать можно только инициализированные данные. Мы с Вами использует этот механизм, применив его к ограничению на использование DLL несколькими программами. То есть практически создадим DLL защиты, которая будет ограничивать число программ, которые будут обращаться к DLL. Очень похоже на лицензионную политику. Итак, создаем DLL. Дадим имя Users.dll:

#include "stdafx.h"
#include "windows.h"

#pragma data_seg(".shared")
 int Countelem=0;
#pragma data_seg()

BOOL APIENTRY DllMain( HANDLE hModule,
            DWORD  ul_reason_for_call,
            LPVOID lpReserved)
{
    switch(ul_reason_for_call)	// проверка подключения
    {
    case DLL_PROCESS_ATTACH:	// новый процесс
        Countelem++;
        if (Countelem>3)	// больше трех подключились
        {
            MessageBox(NULL,"Not Limit Access","error",MB_OK);	// прогнать
            return FALSE;
        }
        break;
    }
    return TRUE;
}

Надо добавить файл описания модуля - UsersDll.def:

LIBRARY "UsersDll"
SECTIONS
 .shared READ WRITE SHARED

Вот, а теперь создадим программу, которая будет эту DLL загружать.

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

int main(int argc, char* argv[])
{
    HINSTANCE hi=NULL;
    hi=LoadLibrary("test.dll");
    if (hi!=NULL)
    {
        int i;
        cin >> i;
    }
    else
        cout << "Error Load" << endl;
    return 0;
}

Вот теперь мы сможет запустить три копии программы, а при запуске четвертой копии получим сообщение.

124_1.gif (5623 b)

Но при реализации данного механизма нужно не забывать про синхронизацию так как много процессов будут иметь доступ к одним и тем же данным.

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 125 - Статическая память потоков

Эта память, которая доступна только одному потоку, она помещается в адресном пространстве потока. Естественно, что в ней будут содержаться переменные, которые доступны только потоку. Это удобно. Нет необходимости синхронизировать доступ к ней и так далее. А ведет себя она точно также как обычная переменная. Смотрим код:

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"
#include "process.h"		// специально для потока

void  fThredFunct1(void* pv);	// декларация функции потока
void  fThredFunct2(void* pv);	// декларация функции потока

int i=10;				// тестировочная переменная

void main()
{
    ULONG hThread1 = 0;	// Идентификатор потока 1
    ULONG hThread2 = 0;	// Идентификатор потока 2
    //unsigned long _beginthread( void( __cdecl *start_address )( void * ),
    //		unsigned stack_size, void *arglist );
    hThread1 = _beginthread(fThredFunct1,0,NULL);	// создали первый поток
    if (hThread1==-1)
        cout << "Error create thread" << endl;
    hThread2 = _beginthread(fThredFunct2,0,NULL);	// создали второй поток
    if (hThread1==-2)
        cout << "Error create thread" << endl;
    Sleep(1000);			// ждем потоки
    cout << "main " << i << endl;
}

void fThredFunct1(void* pv)	// реализация функции потока
{
    cout << "Thread1 Runnig" << endl;
    i=i+30;
    cout << "Thread1 " << i << endl;
}

void fThredFunct2(void* pv)	// реализация функции потока
{
    cout << "Thread2 Runnig" << endl;
    i=i+50;
    cout << "Thread2 " << i << endl;
}

Результат его работы будет такой.

Thread1 Runnig
Thread1 40
Thread2 Runnig
Thread2 90
main 90
Press any key to continue

То есть с переменной int могут работать все потоки. Это требует синхронизации как минимум. Давайте объявим ее как локальную статическую для потока.

__declspec(thread) int i=10;		// тестировочная переменная

И опять запустим пример на выполнение.

Thread1 Runnig
Thread1 40
Thread2 Runnig
Thread2 60
main 10
Press any key to continue

Результат будет уже другой. Для каждого потока эта переменная будет своя. Изменения в одном потоке не влияет на нее в другом потоке.

125_1.gif (4673 b)

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 126 - Динамическая локальная память потоков TlsAlloc - TlsFree

Здесь все сложнее. Эта память будет создана во время работы приложения, как и обычная динамическая память. Идея та же. Используя этот тип памяти у нас отпадает необходимость заботиться о синхронизации памяти между потоками. Первое это надо запросить у системы индекс динамической локальной памяти потоков это делает TlsAlloc.

DWORD TlsAlloc(VOID);

Если функция успешна она вернет индекс памяти, иначе вернет -1;

DWORD dwTlsIndex;
dwTlsIndex=TlsAlloc();
if (dwTlsIndex==-1)
{
    cout << "Error TlsAlloc " << endl;
    return;
}

В конце завершения работы потока индекс надо освободить. Это реализует функция -

BOOL TlsFree(
    DWORD dwTlsIndex	//TLS index
);

При успехе возвращаемое значение ненулевое.

if ( TlsFree( dwTlsIndex)==0 )
{
    cout << "Error TlsFree" << endl;
    return;
}

К чему все это? Я понимаю, что на примере просто одной программы это не совсем понятно. А вот представьте себе, что Вы организуете DLL. К которой будут обращаться много программ. Ведь код DLL в памяти храниться в одном экземпляре. Соответственно надо гарантировать что каждый процесс, который обратиться к DLL будет иметь свою локальную динамическую память. Что бы один процесс не испортил данные другого процесса. Вот к чему все это. Хоть статическая локальная память процесса, хоть динамическая локальная память процесса нужна если к одной и той же функции будут обращаться много потоков. Обе эти памяти только по своему гарантируют локальность данных. К примеру, о DLL. В момент подключения процесса он должен создать свою динамическую локальную память, а в момент отключения освободить. То есть не процесс должен это делать в DLL должна уметь это делать. Вот примерно так. Это совсем простой пример так как в процессе может быть много потоков.

BOOL APIENTRY DllMain(HANDLE hInst, ULONG uCall, LPVOID
    lpReserved)
{
    ......
    switch(uCall)
    {
        case DLL_PROCESS_ATTACH:
        {
            dwTlsIndex = TlsAlloc();
            ......
        }

        case DLL_PROCESS_DETACH:
        {
            TlsFree(dwTlsIndex);
            ......
        }
        ......
    }
    ......
}

Ну и полный пример:

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"
#include "process.h"			// специально для потока

void  fThredFunct1(void* pv);		// декларация функции потока
__declspec(thread) DWORD dwTlsIndex;		// локальная статическая функция для потока

void main()
{

    ULONG hThread1 = 0;		// Идентификатор потока 1
    ULONG hThread2 = 0;		// Идентификатор потока 2
    //unsigned long _beginthread( void( __cdecl *start_address )( void * ),
    //			unsigned stack_size, void *arglist );
    hThread1 = _beginthread(fThredFunct1,0,NULL);	// создали первый поток
    if (hThread1==-1)
        cout << "Error create thread" << endl;
    hThread2 = _beginthread(fThredFunct1,0,NULL);	// создали второй поток
    if (hThread1==-2)
        cout << "Error create thread" << endl;
    Sleep(2000);				// ждем
}

void fThredFunct1(void* pv)			// реализация функции потока
{
    dwTlsIndex=TlsAlloc();		// Запросить индекс
    if (dwTlsIndex==-1)		// проверить на ошибку
    {
        cout << "Error TlsAlloc " << endl;
        return;
    }
    cout << dwTlsIndex << endl;
    Sleep(1000);

    if ( TlsFree( dwTlsIndex)==0 )	// освободить индекс
    {
        cout << "Error TlsFree" << endl;
        return;
    }
}

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

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 127 - Использование исключений для выделения страниц виртуальной памяти

Идея использования исключений для выделения страниц виртуальной памяти простая. Сначала резервируются страницы. По мере обращения эти страницы заполнятся и к ним есть доступ. Смотрим пример:

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

struct MemItem
{
    int a;
};

// указатель на резервируемую память
int* m_pVirtualAlloc;
// размер структуры
const sizestruct=sizeof(MemItem);

void Access(int index,int data);
void Printdata(int index);

void main()
{
    // выделение памяти
    m_pVirtualAlloc=(int*)VirtualAlloc(
        NULL,		//ОС выберет начало
        sizestruct*2500,	//для структур
        MEM_RESERVE,	//резервирование
        PAGE_NOACCESS	//без доступа
    );
    // проверка инициализации
    if (m_pVirtualAlloc!=NULL)
    {
        // доступ
        Access(1,10);
        Printdata(1);
        Access(1,20);
        Printdata(1);
        Access(2000,12);
        cout << "finish" << endl;
        Printdata(1);
        Printdata(2000);
        // освободить
        VirtualFree(m_pVirtualAlloc,0,MEM_RELEASE);
    }
    else
    cout << "Error Alloc" << endl;
}

void Access(int index,int data)
{
    __try
    {
        MemItem* mi=(MemItem*)m_pVirtualAlloc+index*sizestruct;
        mi->a=data;
    }
    __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
    {
        cout << "Not Access" << endl;
        VirtualAlloc(m_pVirtualAlloc+index*sizestruct,
            sizestruct,MEM_COMMIT,PAGE_READWRITE);
        MemItem* mi=(MemItem*)m_pVirtualAlloc+index*sizestruct;
        mi->a=data;
    }
}

void Printdata(int index)
{
__try
    {
        MemItem* mi=(MemItem*)m_pVirtualAlloc+index*sizestruct;
        cout << mi->a << endl;
    }
    __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
    {
        cout << "Not Print" << endl;

    }
}

Если при попытки обращения к странице получаем EXCEPTION_ACCESS_VIOLATION то ее нужно заполнить. Дальше обращения к ней будут нормальные. Данное исключение будет сгенерированно только один раз. Использовать данный пример можно было например для заполнения памяти из файла по мере обращения к данным или для заполнения массива.

Смотрим результат:

Not Access
10
20
Not Access
finish
20
12
Press any key to continue
Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 128 - Интегрирование исключений SEH и C++

Совместное использование этих двух исключений несколько усложнено. Но в реальных программах необходимо использовать обработку этих двух исключений так как само операционная система будет порождать исключения SEH а стандартный функции библиотеки по правилам ANSI будут порождать исключения С++. Используя функцию _set_se_translator у нас есть возможность интегрировать эти два типа исключений.

typedef void (*_se_translator_function)( unsigned int, struct _EXCEPTION_POINTERS* );
_se_translator_function _set_se_translator( _se_translator_function se_trans_func );

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

// Testexception.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#include "iostream.h"
#include "eh.h"

class CExcp		// класс перехватчик
{
    unsigned int m_nCode;
public:
    CExcp(unsigned int nCode) : m_nCode(nCode) {};
    unsigned int Code() const {return m_nCode;};
};

void SEH_TR(unsigned int nCode, EXCEPTION_POINTERS* pexp) // Получили SEH
{
    throw CExcp(nCode);		// Вернули C++
}

void ErrorSEH()
{
    int *p=0;
    *p=0;				// Ошибку хотим.
}

void main()
{

    _se_translator_function fnOld;	// указатель на функцию
    fnOld = _set_se_translator(SEH_TR);	// перехват
    try
    {
        ErrorSEH();		// вызывтать код с ошибкой
    }
    catch(CExcp& e)			// ловим ошибку
    {
        cout << "Error" << endl;
        if (e.Code() ==EXCEPTION_ACCESS_VIOLATION)
            cout << "EXCEPTION_ACCESS_VIOLATION" << endl;
    }
    _set_se_translator(fnOld);		// вернуть старую функцию

}

Результат выполнения этой программы будет такой.

Error
EXCEPTION_ACCESS_VIOLATION
Press any key to continue

Попробуйте закоментировать:

//_se_translator_function fnOld;
//fnOld = _set_se_translator(SEH_TR);
............
//_set_se_translator(fnOld);

И теперь результат будет уже такой.

128_1.gif (5396 b)

Будьте осторожны в версии Release. Установка оптимизации по скорости или по размеру может привести к тому, что этот код не сработает. То есть Вы не перехватите исключение SEH. Попробуйте становить оптимизацию по скорости.

128_2.gif (3824 b)

Код не будет работать. А вот отключите ее или поставьте Default то все станет нормально.

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 129 - Передача события синхронизации в другой процесс

Связанные темы:

  • "Шаг 119 - Функции CreateEvent(), SetEvent(), ResetEvent()"
  • "Шаг 83 - Что такое События (Event) синхронизации"

Итак, в прошлых шагах мы с Вами использовали сообщения для передачи события внутри одного процесса разным потокам. Теперь мы посмотрим, как это же самое сделать между разными процессами. Мы создадим два приложения в одной рабочей области. Оба они будут Win32 Console application. Одно приложение SetEvet будет посылать событие синхронизации, а второе его ждать.

129_1.gif (2067 b)

Код ожидающего приложения.

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    HANDLE hEv = CreateEvent(NULL,FALSE,FALSE,"Event");	// открыть указатель на сообщение
    WaitForSingleObject(hEv,INFINITE);			// ждать сообщения
    cout << " Event Event !!!" << endl;			// есть сообшение
    CloseHandle(hEv);					// закрыть указатель
}

Код посылающего приложения. Я имею ввиду сообщение.

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"
void main()
{
    HANDLE hEv = CreateEvent(NULL,FALSE,FALSE,"Event");	// открыть указатель на сообщение
    SetEvent(hEv);					// послать (сообщение)
    cout << " Event Setting !!!" << endl;
}

Запускайте сначала ожидающее приложение, оно замрет. После этого посылающее и все сработает.

129_2.gif (5417 b)

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 130 - InterlockedIncrement и InterlockedDecrement

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

LONG InterlockedIncrement
(
    LPLONG lpAddend   // переменная для увеличения
);

LONG InterlockedDecrement
(
    LPLONG lpAddend   // переменная для уменьшения
);

Очень часто эти функции применяются при создании COM объектов которые будут работать естественно в условии многопоточности.

130_1.gif (4719 b)

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 131 - CreateProcess

На данный момент это основная функция запуска процесса, все остальные функции такие как WinExec и LoadModule оставлены для совместимости и используют CreateProcess.

131_1.gif (5388 b)

Описание

BOOL CreateProcess
(
    LPCTSTR lpApplicationName,                 // имя исполняемого модуля
    LPTSTR lpCommandLine,                      // Командная строка
    LPSECURITY_ATTRIBUTES lpProcessAttributes, // Указатель на структуру SECURITY_ATTRIBUTES
    LPSECURITY_ATTRIBUTES lpThreadAttributes,  // Указатель на структуру SECURITY_ATTRIBUTES
    BOOL bInheritHandles,                      // Флаг наследования текущего процесса
    DWORD dwCreationFlags,                     // Флаги способов создания процесса
    LPVOID lpEnvironment,                      // Указатель на блок среды
    LPCTSTR lpCurrentDirectory,                // Текущий диск или каталог
    LPSTARTUPINFO lpStartupInfo,               // Указатель нас структуру STARTUPINFO
    LPPROCESS_INFORMATION lpProcessInformation // Указатель нас структуру PROCESS_INFORMATION
);

lpApplicationName. Указатель на строку которая заканчивается нулем и содержит имя выполняемого модуля. Этот параметр может быть NULL тогда имя модуля должно быть в lpCommandLine самым первым элементом. Если операционная система NT и модуль 16 разрядов этот параметр NULL обязательно. имя модуля может быть абсолютным или относительным. Если относительное то будет использована информация из lpCurrentDirectory или текущий каталог.

lpCommandLine.Командная строка. Здесь передаются параметры. Она может быть NULL. Здесь можно указать и путь и имя модуля.

lpProcessAttributes.Здесь определяются атрибуты защиты для нового приложения. Если указать NULL то система сделает это по умолчанию.

lpThreadAttributes. Здесь определяются атрибуты защиты для первого потока созданного приложением. NULL опять приводит к установке по умолчанию.

bInheritHandles. Флаг наследования от процесса производящего запуск. Здесь наследуются дескрипторы. Унаследованные дескрипторы имеют те же значения и права доступа, что и оригиналы.

dwCreationFlags. Флаг способа создание процесса и его приоритет.

CREATE_DEFAULT_ERROR_MODE	Новый процесс не наследует режим ошибок (error mode) вызывающего процесса.
CREATE_NEW_CONSOLE		Новый процесс получает новую консоль вместо того, чтобы унаследовать родительскую.
CREATE_NEW_PROCESS_GROUP	Создаваемый процесс - корневой процесс новой группы.
CREATE_SEPARATE_WOW_VDM	только Windows NT: Если этот флаг  установлен, новый процесс запускается
            в собственной Virtual DOS Machine (VDM).
CREATE_SHARED_WOW_VDM	только Windows NT: Этот флаг указывает функции CreateProcess запустит
            новый процесс в разделяемой Virtual DOS Machine.
CREATE_SUSPENDED		Первичная нить процесса создается в спящем (suspended) состоянии
            и не выполняется до вызова функции ResumeThread.
CREATE_UNICODE_ENVIRONMENT	Если этот флаг установлен, блок переменных окружения, указанный в
            параметре lpEnvironment, использует кодировку Unicode. Иначе - кодировку ANSI.
DEBUG_PROCESS		Если этот флаг установлен, вызывающий процесс считается отладчиком,
            а новый процесс - отлаживаемым.
DEBUG_ONLY_THIS_PROCESS	Если этот флаг не установлен и вызывающий процесс находится под отладкой,
            новый процесс так же становится отлаживаемым тем же отладчиком.
DETACHED_PROCESS		Создаваемый процесс не имеет доступа к родительской консоли.
            Этот флаг нельзя использовать с флагом CREATE_NEW_CONSOLE.
HIGH_PRIORITY_CLASS	Указывает на то, что процесс выполняет критичные по времени задачи
IDLE_PRIORITY_CLASS	Указывает процесс,  выполняются только когда система находится в состоянии ожидания
NORMAL_PRIORITY_CLASS	Указывает на процесс, без каких либо специальных требований к выполнению.
REALTIME_PRIORITY_CLASS	Указывает процесс имеющий наивысший возможный приоритет.

lpEnvironment. Указывает на блок среды. Если NULL, то будет использован блок среды родительского процесса. Блок среды это список переменных имя=значение в виде строк с нулевым окончанием.

lpCurrentDirectory.Указывает текущий диск и каталог. Если NULL то будет использован диск и каталог процесса родителя.

lpStartupInfo Используется для настройки свойств процесса, например расположения окон и заголовок. Структура должна быть правильно инициализирована

STARTUPINFO sti;				// структура
ZeroMemory(&sti,sizeof(STARTUPINFO));	// обнулить
sti.cb=sizeof(STARTUPINFO);			// указать размер

lpProcessInformation Структура PROCESS_INFORMATION с информацией о процессе. Будет заполнена Windows.

В результате выполнение функций вернет FALSE или TRUE. В случае успеха TRUE. Пример использования.

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    STARTUPINFO cif;
    ZeroMemory(&cif,sizeof(STARTUPINFO));
    PROCESS_INFORMATION pi;
    if (CreateProcess("c:\\windows\\notepad.exe",NULL,
        NULL,NULL,FALSE,NULL,NULL,NULL,&cif,&pi)==TRUE)
    {
        cout << "process" << endl;
        cout << "handle " << pi.hProcess << endl;
        Sleep(1000);				// подождать
        TerminateProcess(pi.hProcess,NO_ERROR);	// убрать процесс
    }
}
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 132 - ExitProcess

Есть две функций прекращения выполнения процесса - TerminateProcess и ExitProcess. Функция TerminateProcess прекращает процесс с стороны, а функция ExitProcess прекращает из нутри. Использовать TerminateProcess не являеться хорошим стилем так как при вызове и выполнении этой функции не освобождаться связанные DLL и ресурсы.

VOID ExitProcess
(
    UINT uExitCode	// код возврата
);

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

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 133 - Установка и удаление шрифтов (AddFontResource,RemoveFontResource)

Для установки шрифта в систему используется функция AddFontResource:

int AddFontResource
(
    LPCTSTR lpszFilename	// имя файла шрифта
);

При неудаче вернет ноль. После установки шрифта программа должна послать извещение с параметрами:

WM_FONTCHANGE
HWND_BROADCAST

Пробуем ? Win 32 Console Application.

// InstallFont.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "iostream.h"
#include "windows.h"

void main()
{
    int i=AddFontResource("D:\\VС\\InstallFont\\geomap.TTF");
    if (i!=0)
    {
        SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);  // сообщить о шрифте
        cout << "install" << endl;
    }
}

С этого момента шрифт станет, известен всем приложениям. Например, в блокноте его можно будет выбрать.

133_1.gif (9526 b)

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

BOOL RemoveFontResource
(
    LPCTSTR lpFileName	// имя шрифта
);

При успешном выполнении функция вернет ненулевое значение. Пробуем:

#include "stdafx.h"
#include "iostream.h"
#include "windows.h"

void main()
{
    if (RemoveFontResource("D:\\VС\\InstallFont\\geomap.TTF")!=0)
    {
        SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);  // сообщить о шрифте
        cout <<  "removed" << endl;
    }
}

Теперь этого шрифта не будет в списке:

133_2.gif (2743 b)

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 134 - Установка и удаление шрифта в системе

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

  1. Скопировать его в папочку Fonts.
  2. Зарегистрировать в реестре.
  3. Использовать функцию AddResourceFont для того, чтобы не перезагружать компьютер.

Давайте договоримся что будет использовать имя файла шрифта как имя шрифта. Вообще то это не одно и тоже. Имя файла шрифта например GeoMap.ttf, a имя шрифта у него вот такое:

134_1.gif (3338 b)

Именно это имя будет использоваться, если добавить шрифт стандартными средствами Windows. Мы с Вами пока будет оперировать именем файла. Это удобно в том плане, что не надо запоминать имя шрифта. Оно же не совпадает с именем файла. Для простоты будет регистрировать под именем файла. Создадим класс CFontInstall. Мы будет пользоваться классами MFC поэтому код будет работать только с поддержкой MFC.

#include "afx.h"
#include "atlbase.h"

#define PATH_FONT "Fonts\\"
#define REGKEY_FONT "Software\\Microsoft\\Windows\\CurrentVersion\\Fonts"

class CFontInstall
{
public:
    void RemoveFonts(CString csFile);			// удалить шрифт
    void InstallFonts(CString csFile, CString csPath);	// добавить шрифт
    CFontInstall();
    virtual ~CFontInstall();

private:
    CString GetName(CString csFile);		// отрезать расширение
    CString GetWinDir();				// папка Windows
    void RegisterFont(CString csFile);		// регистрировать в реестре
};

Пишем код. Первое это отрезание расширения, чтобы получить имя:

CString CFontInstall::GetName(CString csFile)
{
    CString csTemp=csFile;
    csTemp=csTemp.Left(csTemp.Find('.',0));	// найти точку взять все что с лева
    return csTemp;
}

Получение системной папки Windows. Кто сказал, что она должны быть только на диске С.

CString CFontInstall::GetWinDir()
{
    char buffer[MAX_PATH];
    if (GetWindowsDirectory(buffer,MAX_PATH)==0)
        throw CString("Error GetSystemDirectory");
    CString temp(buffer);
    temp+="\\";
    temp+=PATH_FONT;
    return temp;
}

Регистрация в реестре:

void CFontInstall::RegisterFont(CString csFile)
{
    CRegKey cKey;
    if (cKey.Open(HKEY_LOCAL_MACHINE,REGKEY_FONT)!=ERROR_SUCCESS)
        throw CString("Error Open Registry");
    if (cKey.SetValue(csFile,GetName(csFile))!=ERROR_SUCCESS)
        throw CString("Error Add Key");
    AddFontResource(csFile);
    SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
}

Непосредственная установка:

void CFontInstall::InstallFonts(CString csFile,CString csPath)
{
    CString in=csPath+csFile;
    CString out=GetWinDir()+csFile;
    if (CopyFile(in,out,FALSE)==0)
        throw CString("Error Copy");
    RegisterFont(csFile);
}

Удаление:

void CFontInstall::RemoveFonts(CString csFile)
{
    if (DeleteFile(GetWinDir()+csFile)==0)
        throw CString("Error Delete ");
    CRegKey cKey;
    if (cKey.Open(HKEY_LOCAL_MACHINE,REGKEY_FONT)!=ERROR_SUCCESS)
        throw CString("Error Open Registry");
    if (cKey.DeleteValue(GetName(csFile))!=ERROR_SUCCESS)
        throw CString("Error Delete");
    RemoveFontResource(csFile);
    SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
}

Попробуем ?

#include "stdafx.h"
#include "iostream.h"
#include "FontInstall.h"
#include "conio.h"

void main()
{
    CFontInstall cf;
    try
    {
        cf.InstallFonts("geomap.ttf","D:\\VС\\InstallFont\\");
        cout << "install" << endl;
        getch();
        cf.RemoveFonts("geomap.ttf");
        cout <<  "remove" <<  endl;
    }
    catch(CString s)
    {
        cout <<  s <<  endl;
    }
}

В проекте находится класс CFontInstall упaкованный для использования в Component Gallery, как ogx файл.

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 135 - GetUserName

Получает имя пользователя для текущего процесса. Обычно это имя пользователя зарегистрировавшегося в системе. Имя сеанса:

135_1.gif (2737 b)

Вот она.

BOOL GetUserName
(
    LPTSTR lpBuffer,	// указатель на буфер
    LPDWORD nSize	// получает размер возвращает количество символов
);

Размер буфера должен быть достаточный для того, чтобы вместить пользователя. Определение размера носит имя UNLEN и описана в Lmcons.h. При неудачном выполнении функция вернет 0:

#define UNLEN 256	// Maximum user name length

Давайте совместим "Шаг 38 - GetComputerName()" и этот шаг, создав универсальный класс, который нам поможет легко получать эти имена. Я применю технологию описанную в шаге "Шаг 108 - Универсальные классы". Ведь имя можно получить по разному, например, получить из реестра. Весь код и структуру классов можно посмотреть в проекте, а вот сам конкретный код получения функции имени пользователя.

CString CEasyGetUserName::Get()
{
    char buffer[UNLEN+1];		// буфер
    DWORD size;			// размер
    size=sizeof(buffer);		// размер буфера
    if (GetUserName(buffer,&size)==0)
        throw "Error GetUserName";	// при ошибке функция вернет 0
    return buffer;			// вернуть результат
}

Структура классов довольно сложная для такой простой задачи. Стоит создавать такое количество классов или нет, это вопрос. Мне просто нравиться так программировать. Можно в любой момент все изменить и это хорошо. Ну, например при переходе например на Windows 9000 beta 2 bild 199 :-) какой нибуть все что нужно только исправить одну функцию а все остальное будет работать.

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 136 - Удаленное подключение к реестру RegConnectRegistry и RegCloseKey

У нас есть все-таки способ работы с удаленным реестром. Это функция RegConnectRegistry:

LONG RegConnectRegistry
(
    LPCTSTR lpMachineName,	// имя компьютера
    HKEY hKey,		// ключ реестра
    PHKEY phkResult		// указатель на удаленный ключ
);

Естественно, чтобы подключение вообще можно было реализовать но компьютеры должны быть настроены, сервисы там и протоколы. Если Вы про это нечего не знаете читать здесь. Вот пример кода:

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    HKEY pKey;
    if (RegConnectRegistry("Panasonic",HKEY_CURRENT_CONFIG,&pKey)!=ERROR_SUCCESS)
    {
        cout << "Error connect";
        return;
    }
    cout << "Ok Connect" << endl;
    RegCloseKey(pKey);
}

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

LONG RegCloseKey
(
    HKEY hKey		// закрываемый ключ
);

В случаем успеха функция вернет ERROR_SUCCESS, иначе код ошибки.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 137 - Исследуем сеть (WNetOpenEnum, WNetCloseEnum)

При программировании данной задачи в Windows 98 можно использовать функции Windows Networking (WNet), что мы с Вами и сделаем. Все начинается с функции WNetOpenEnum. Эта функция отрывает указатель, с помощью которого можно изучать сеть. Давайте ее посмотрим.

DWORD WNetOpenEnum
(
    DWORD dwScope,			// определяет возможности перечисления
    DWORD dwType,			// тип ресурса для перечисления
    DWORD dwUsage,			// тип использования для перечисления
    LPNETRESOURCE lpNetResource,	// структура для информации о ресурсу
    LPHANDLE lphEnum			// указатель на перечислитель
);

Давайте посмотрим параметры dwScope:

  • RESOURCE_CONNECTED - перечисляются все подключенные ресурсы, dwUsage игнорируется
  • RESOURCE_CONTEXT - перечисляются все ресурсы в контексте сети, dwUsage игнорируется
  • RESOURCE_GLOBALNET - перечисляются все ресурсы сети
  • RESOURCE_REMEMBERED - перечисляются все постоянные связи, dwUsage игнорируется

Следующий флаг - это dwType:

  • RESOURCETYPE_ANY - все ресурсы
  • RESOURCETYPE_DISK - все диски
  • RESOURCETYPE_PRINT - все принтеры

Флаг dwUsage используется только при перечислении всех ресурсов:

  • 0 - все ресурсы
  • RESOURCEUSAGE_CONNECTABLE - все подключенные ресусры
  • RESOURCEUSAGE_CONTAINER - все ресурсы контейнеры
  • RESOURCEUSAGE_ATTACHED - запрещает перечислять без аутентификации
  • RESOURCEUSAGE_ALL - объединяет флаги RESOURCEUSAGE_CONNECTABLE, RESOURCEUSAGE_CONTAINER и RESOURCEUSAGE_ATTACHED.

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

После использования указатель на перечислитель lphEnum должен быть закрыт с помощью функции:

DWORD WNetCloseEnum
(
    HANDLE hEnum	// указатель на перечислитель
);

В случае успеха функция вернет NO_ERROR. Вот пример кода для начала перечисления.

void CEasyEnumNetResourceAbstract::OpenEnum()
{
    dwResult = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, NULL, &hEnum);
    if (dwResult != NO_ERROR)
        throw CString("Error OpenEnum");
    GetResource();
    dwResult = WNetCloseEnum(hEnum);
    if (dwResult != NO_ERROR)
        throw CString("Error OpenEnum");
}

Все, что нужно здесь - это указатель на перечислитель:

class CEasyEnumNetResourceAbstract
{
    ......
    DWORD 		dwResult;		// для результата
    HANDLE 		hEnum;		// указатель на ресурсы
    LPNETRESOURCE	netRc;
    ......
};

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

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 138 - Исследуем сеть - список клиентов

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

DWORD WNetEnumResource
(
    HANDLE hEnum,		// указатель на ресурсы
    LPDWORD lpcCount,		// сколько перечислят и результат перечисления
    LPVOID lpBuffer,		// указатель на буфер
    LPDWORD lpBufferSize	// размер буфера
);

Если в lpcCount указать -1, то будут перечисляться все возможные ресурсы. В буфер будут помещаться результаты. Размер нужно установить достаточный. Где-то читал, что 16 KB - это удачный выбор. При успешном выполнении может вернуть NO_ERROR или ERROR_NO_MORE_ITEMS, что значит нет вхождений. Функция получения списка клиентов будет выглядеть вот так:

void CEasyEnumProvider::GetResource()
{
    do
    {
        dwResult = WNetEnumResource(hEnum,&cEntries,netRc,&cbBuffer);
        if( dwResult == NO_ERROR )
        {
            LPNETRESOURCE temp;
            temp=&netRc[0];
            cArray.Add(temp->lpProvider);
        }
        else break;
    }while( dwResult != ERROR_NO_MORE_ITEMS );
}

Получаем ресурс и пока есть элементы dwResult != ERROR_NO_MORE_ITEMS берем имя провайдера и складываем в массив. Только сначала нужно инициализировать массив и переменные. Вот так:

CEasyEnumNetResourceAbstract ::CEasyEnumNetResourceAbstract ()
{
    cEntries = -1 ;		// для всех ресурсов
    cbBuffer = 16384;		// размер буфера
    netRc=0;
    netRc = (LPNETRESOURCE) GlobalAlloc(GPTR, cbBuffer);
}

CEasyEnumNetResourceAbstract ::~CEasyEnumNetResourceAbstract ()
{
    GlobalFree((HGLOBAL)netRc);
}

CEasyEnumProvider я породил от CEasyEnumNetResourceAbstract, в котором там производится иницализация переменных открытие перечислителя и все такое. В CEasyEnumProvider всего одна функция GetResource. А вот так это используется:

#include "stdafx.h"
#include "iostream.h"
#include "EasyEnumNetResource.h"

void main()
{
    try
    {
        CEasyEnumProvider ce;
        ce.OpenEnum();
        int x=ce.GetCount();
        for (int i=0;i<x;i++)
            cout << ce.GetString(i) << endl;
    }
    catch(CString s)
    {
        cout << s;
    }
}

Полный пример кодов в проекте. В результате работы программы на экране будет список доступных клиентов на компьютере, с которого запущена эта программа.

138_1.gif (6427 b)

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 139 - Перебор шрифтов

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

int EnumFontFamiliesEx
(
    HDC hdc,				//  указатель на DC
    LPLOGFONT lpLogfont,		// информация о шрифте
    FONTENUMPROC lpEnumFontFamExProc,	// функция обратного вызова
    LPARAM lParam,			// дополнительные данные
    DWORD dwFlags			// не используеться.
);

Функцию обратного вызова нужно правильно оформить. Вот ее прототип:

int CALLBACK EnumFontFamExProc
(
    ENUMLOGFONTEX *lpelfe,	// логические данные шрифта
    NEWTEXTMETRICEX *lpntme,	// физические данные шрифта
    DWORD FontType,		// тип шрифта
    LPARAM lParam		// данные приложения
);

Ну и теперь полный пример:

#include "stdafx.h"
#include "afxwin.h"
#include "afxdlgs.h"
#include "iostream.h"

int CALLBACK EnumFontFamExProc(
    ENUMLOGFONTEX *lpelfe,
    NEWTEXTMETRICEX *lpntme,
    DWORD FontType,
    LPARAM lParam
);

void main()
{
    HWND hwnd=GetDesktopWindow();	// получить окно
    HDC hdc=GetDC(hwnd);		// связанный DC
    LOGFONT  lf;
    lf.lfFaceName[0] = '\0';
    lf.lfCharSet = DEFAULT_CHARSET;	// все шрифты
    EnumFontFamiliesEx(hdc,&lf,(FONTENUMPROC)EnumFontFamExProc,
        (LPARAM) 0,(DWORD) 0);
    ReleaseDC(hwnd,hdc);
}

int CALLBACK EnumFontFamExProc(ENUMLOGFONTEX *lpelfe,
    NEWTEXTMETRICEX *lpntme,DWORD FontType,LPARAM lParam)
{
    cout <<  lpelfe->elfLogFont.lfFaceName << endl;
    return true;
}

Мы не стали специализировать какие нужны шрифты а просто запросили все.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 140 - Конвертация HEX - BIN и BIN - HEX

From: cYbErLoRd <evgenyh@peterlink.ru>
To: kaev@yandex.ru <kaev@yandex.ru>
Date: 26 августа 2001 г. 14:43
Subject: MFCByStep

Артём это ещё раз я.
Сейчас я попытаюсь объяснить тебе попонятнее зачем мне вообще это нужно:
Дело в том, что я хотел сам написать редактор сэйвов для
Diablo II LOD (ну там всякие деньги скилы и т.д.). Сначала всё шло
вроде неплохо,  но потом я понял, что не могу сделать так, чтобы
программа открывала сэйв и в EDIT BOX записывала не символы, а
именно HEX значения,  вот в чём весь прикол-то!

P.P.S Заранее благодарен!
Best regards,
 cYbErLoRd      mailto:evgenyh@peterlink.ru

Проблемы как таковой нет. Надо просто найти кто умеет это делать. А делать это умеет MAPI с помощью двух функций HexFromBin и ScBinFromHexBounded смотрим пример:

#include "stdafx.h"
#include "afxwin.h"
#include "mapiutil.H"
#include "iostream.h"

#pragma comment(lib,"Mapi32.lib")

void main()
{
    CString s="Hello Hex & Bin";
    for (int x=0;x<s.GetLength();x++)
    {
        char c;
        c=s[x];
        BYTE b=c;
        char buffer[10];
        HexFromBin( &b,sizeof(b),(char*)&buffer);
        cout << buffer;
    }
    cout << endl;
    CString csnext("48656C6C6F2048657820262042696E");
    for (x=0;x<csnext.GetLength();x=x+2)
    {
        BYTE bb;
        char buffer[2];
        buffer[0]=csnext[x];
        buffer[1]=csnext[x+1];
        ScBinFromHexBounded((char*)&buffer,&bb,sizeof(bb));
        char cc=bb;
        cout << cc;
    }
    cout << endl;
}

А вот результат конвертации туда сюда:

140.gif (3295 b)

Если использовать MFC, то можно создать пользовательскую DDX на основе этого кода подробнее написано в "Шаг 37 - Пользовательская функция DDX". В ней нужно описать эти действий по переводу в окно и из окна.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 141 - WINAPI и время

WIN 32 API поддерживает пять форматов времени, и функции для получения времени и преобразования форматов с учетом часовых поясов. Вот эти типы.

System	SYSTEMTIME  		Года, месяц, день, час, секунда, и миллисекунды,
                взятые с внутренних аппаратных часов.
File	FILETIME			100-наносекунд интервалов 1 Января, 1601.
Local	SYSTEMTIME ИЛИ FILETIME	Системное время или файловое время преобразованное
                в локальное время с учетом  часовых поясов.
MS-DOS	WORD			Упакованное 16-битовое слово для даты другое для времени.
Windows	DWORD 			Количество миллисекунд с тех пор как загруженная система;
                повторяется каждые 49.7 дней.

Как видите у нас время храниться в WORD, DWROD и еще есть две струтуры. Структура SYSTEMTIME хранит дату и время используя отдельные поля для месяца, дня, года, дня недели, часа, минут, секунд и миллисекунд.

typedef struct _SYSTEMTIME
{
    WORD wYear;		// Указывает текущий год
    WORD wMonth;		// Текущий месяц; Январь = 1, Февраль = 2, и так далее
    WORD wDayOfWeek;		// Текущий день недели; Воскресенье = 0, Понедельник = 1, и так далее.
    WORD wDay;		// Текущий день месяца.
    WORD wHour;		// Час.
    WORD wMinute;		// Минуты.
    WORD wSecond;		// Секунды.
    WORD wMilliseconds;	// Миллисекунды.
} SYSTEMTIME;

Структура FILETIME - это 64-х разрядное значение, представляющее число сто-наносекундных интервалов, прошедших с первого Января 1601 года:

typedef struct _FILETIME
{
    DWORD dwLowDateTime; 	// Младшие 32 бита времени файла
    DWORD dwHighDateTime;	// Старшие 32 бита времени файла
} FILETIME;
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 142 - GetSystemTime

Функция возвращает системное время. Системное время выражается в UTC:

VOID GetSystemTime
(
    LPSYSTEMTIME lpSystemTime
);

В lpSystemTime нужно передать указатель на структуру SYSTEMTIME ее описание есть в шаге "Шаг 141 - WINAPI и время". Давайте попробуем. Win 32 Console Application как всегда.

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    SYSTEMTIME sm;
    GetSystemTime(&sm);
    cout << sm.wHour <<  endl;
}

Результат работы этой функции немного непривычен. Смотрите на рисунок. Это не есть локальное время. Это есть универсальное время UTC.

142_1.gif (2475 b)

И результат возврата зависит от часового пояса. При установке другого часового пояса будет получен другой результат. Ставим другой часовой пояс.

142_2.gif (2561 b)

Получаем другой результат.

142_3.gif (2994 b)

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

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 143 - GetLocalTime

Функция возвращает локальное время:

VOID GetLocalTime
(
    LPSYSTEMTIME lpSystemTime
);

В lpSystemTime нужно передать указатель на структуру SYSTEMTIME, ее описание есть в шаге "Шаг 141 - WINAPI и время". Давайте попробуем. Win 32 Console Application как всегда:

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    SYSTEMTIME sm;
    GetLocalTime(&sm);
    cout << sm.wHour <<  endl;
}

В результате мы получим время, которое установлено на нашем компьютере. Оно должно быть высчитано как UTC+Time Zone. Но Все равно вы то можете установить любое время.

143_1.gif (2501 b)

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 144 - GetFileTime

GetFileTime - извлекает дату и время, когда файл создавался, последнего доступа, и последней модификации.

BOOL GetFileTime
(
    HANDLE hFile,			// указатель на открытый файл
    LPFILETIME lpCreationTime,		// время создания
    LPFILETIME lpLastAccessTime,	// время доступа
    LPFILETIME lpLastWriteTime		// время модификации
);

При удачном выполнении вернется ненулевое значение. Смотрим пример:

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    HANDLE hFile=NULL;
    hFile=CreateFile("c:\\config.sys",GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL);
    if (hFile!=NULL)
    {
        FILETIME fc;
        FILETIME fa;
        FILETIME fw;
        if (GetFileTime(hFile,&fc,&fa,&fw)!=0)
        {
            //.....
        }
        else
            cout << "error gettime" << endl;
    }
    else
        cout << "error open" << endl;
}

Структура FILETIME описана в шаге . На данный момент просматривать ее нет смылса в связи с тем что там два значения DWORD и из нужно приводить к формату системного времени.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 145 - FileTimeToSystemTime

Преобразует структуру FILETIME к структуре SYSTEMTIME.

BOOL FileTimeToSystemTime
(
    CONST FILETIME *lpFileTime,	// структура FILETIME
    LPSYSTEMTIME lpSystemTime	// структура SYSTEMTIME
);

Если выполнение функции удачное, то она вернет ненулевой результат. Смотрим пример:

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    HANDLE hFile=NULL;
    hFile=CreateFile("c:\\config.sys",GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL);
    if (hFile!=NULL)
    {
        FILETIME fc;
        FILETIME fa;
        FILETIME fw;
        if (GetFileTime(hFile,&fc,&fa,&fw)!=0)
        {
            SYSTEMTIME cm;
            if (FileTimeToSystemTime(&fc,&cm)!=0)
                cout << cm.wYear << " " << cm.wMonth << endl;
            else
                cout << "error convert" << endl;
        }
        else
            cout << "error gettime" << endl;
    }
    else
        cout << "error open" << endl;
}

Смотрим результат:

145_1.gif (2900 b)

Эти же данные отражаются в проводнике:

145_2.gif (2199 b)

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 146 - Функция LoadCursor

Эта функция позволяет получить нам указатель на курсор, мы ее уже пользовались в шагах "Как делали MFC - Регистрируем окно", "Шаг 134 - Смена курсора", "Шаг 66 - Использование анимационных курсоров". Давайте посмотри какая она в WIN32 API:

HCURSOR LoadCursor
(
    HINSTANCE hInstance,	//  указатель на модуль с курсором
    LPCTSTR lpCursorName	// имя курсора
);

В случае успеха она вернет указатель на курсор, иначе NULL. Для того, чтобы использовать стандартный курсор Windows, а их вы можете посмотреть в "Шаг 53 - Типы системных курсоров". hInstance нужно установить в NULL. Давайте попробуем:

// VC++ 6.0  Sample Code.
//
#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

int main(int argc, char* argv[])
{
    HCURSOR hc = LoadCursor(NULL,IDC_NO);
    if (hc==NULL)
        cout << "failed" << endl;
    return 0;
}

В результате мы получим указатель на курсор. Об этом говорит отсутствие сообщения:

146_1.gif (3271 b)

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 147 - Смена системного курсора

У нас есть возможность заменить системный курсор, то есть курсор которым пользуется система. Для этого есть функция SetSystemCursor:

BOOL SetSystemCursor
(
    HCURSOR hcur,	// указатель на курсор
    DWORD id		// идентификатор курсора в системе
);

Указатель на курсор понятно, а что такое идентификатор? Их этих идентификатор несколько:

  • OCR_APPSTARTING - запуск приложения
  • OCR_NORMAL - стандартный указатель
  • И так далее.

В системе предусмотрены разные курсоры на разные случаи жизни. Почитайте "Шаг 25 - Настройка вида курсора". Давайте попробуем эту функцию применить:

// VC++ 6.0 Sample Code
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

#define OCR_NORMAL          32512

int main(int argc, char* argv[])
{
    HCURSOR hc = LoadCursor(NULL,IDC_NO);
    if (hc==NULL) cout << "failed" << endl;
    if (SetSystemCursor (hc,OCR_NORMAL )==TRUE)
        cout << "OK" << endl;
      return 0;
}

В результате системный курсор измениться. При успешном выполнении функция вернет true. После перезагрузки все вернется на свое место. Для смены курсора навсегда нужно произвести записи в реестре, читайте "Шаг 26 - Где в реестре хранить информация о курсоре".

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 148 - О горячей точке курсора (Hot Spot)

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

148_1.gif (908 b)

И пиксела в середине курсора в виде перекрестия.

148_2.gif (869 b)

Когда производятся действия с мышью, драйвер мыши переводит действие в соответствующее сообщение мыши, которое включает координаты горячей точки. Так вот функции описанные в "Шаг 89 - SetCursorPos() и GetCursorPos()" имеют дело с горячей точкой. Наличие этой точки определяет конечно удобство работы в плане куда щелкать. Но она используется в функции создания курсора.

HCURSOR CreateCursor
(
    ......
    int xHotSpot,	// x coordinate of hot spot
    int yHotSpot,	// y coordinate of hot spot
    ......
);

И вот если так создавать курсор то она очень важна, иначе пользователь постоянно будет ошибаться.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 149 - SystemParametersInfo и смена рисунка рабочего стола

Фунция SystemParametersInfo может изменить рисунок рабочего стода. Вообще-то мы с ней один раз уже сталкивались вскользь в "Подробности - Просмотр видео и разворачивание проекта на весь экран". Она может очень много. В данном случае нас интересует параметр SETDESKWALLPAPER. Дальше указываеться имя BMP файла и команда изменения окна. Смотрим пример:

// VC++ Sample Code.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    char filename[10];
    strcpy(filename,"1.bmp");
    if (SystemParametersInfo(SPI_SETDESKWALLPAPER,0,
        &filename,SPIF_SENDWININICHANGE)==TRUE)
    {
        cout << "Ok change" << endl;
    }
    else
        cout << "Error change" << endl;
}

В результате у Вас сменится картинка рабочего стола. Я не указывал путь, а это значит что путь к картинку по умолчанию, то есть каталог Windows. Но это будет временная смена картинки, в реестр она не занесется и после перезагрузки пропадет. Почитайте "Шаг 33 - Где в реестре хранятся настойки рабочего стола" и вы сами убедитесь после выполнения программы. Потом можете перегрузиться для надежности. Для того, чтобы запись в реестр произошла и обои существовали после загрузки последним параметром должен быть SPIF_UPDATEINIFILE. В таком случае запись в реестр будет произведена.

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 150 - OpenClipboard и CloseClipboard

Для работы с буфером обмена его необходимо отрыть:

BOOL OpenClipboard
(
    HWND hWndNewOwner	// указатель на окно
);

После использования закрыть:

BOOL CloseClipboard(VOID);

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

150_1.gif (2513 b)

И код напишем для кнопок:

void COpenClipboardDlg::OnOpenClipboard()
{
    if (::OpenClipboard(this->m_hWnd)==0)
        AfxMessageBox("Error Open");
}

void COpenClipboardDlg::OnCloseCiplboard()
{
    if (::CloseClipboard()==0)
        AfxMessageBox("Error Close");
}

Только одно приложение может открыть буфер обмена. В момент открытия буфера он блокируется. Давайте попробуем. Запускаем приложение и нажимаем кнопку Open. А теперь попробуем что-то сделать, например, в Word. Скажем скопировать и вставить текст. Мы получим сообщение об ошибке.

150_2.gif (3852 b)

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

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 151 - Функция GetOpenClipboardWindow

Эта функция возвращает HWND окна, которое держит открытым буфер обмена.

HWND GetOpenClipboardWindow(VOID);

Давайте попробуем в приложение на основе MFC и диалогового окна:

151_1.gif (2206 b)

И код к нажатию на кнопку:

void CGetClipBoardDlg::OnGet()
{
    HWND hwnd=NULL;
    hwnd=::GetOpenClipboardWindow();
    if (hwnd!=NULL)
    {
        char buffer[100];
        ::GetWindowText(hwnd,(char*)&buffer,sizeof(buffer));
        AfxMessageBox(buffer);
    }
}

По нажатию на кнопку мы получаем HWND окна, которое держит открытым буфер обмена, а после этого используем функцию GetWindowText для извлечения данных об этом окне. Тестировать ее лучше вместе с программой из шага "Шаг 150 - OpenClipboard и CloseClipboard", так она позволяет держать буфер обмена открытым.

151_2.gif (4681 b)

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 152 - Hooks (перехват)

Понятие перехвата используется во многих областях. Например, даже при создании диалогового окна открытия файла мы может установить перехват подробнее читайте "Шаг 140 - Cтруктура OPENFILENAME". Перехват является точкой в обработка сообщений Microsoft Windows, где приложение может установить подпрограмму, чтобы проверить трафик сообщения в системе и обработать определенные тип сообщений прежде, чем они достигнут процедуры окна в которую посланы. Перехваты имеют тенденцию замедлять систему из-за того, что они увеличивают суммарное время обработки, которую система должна выполнить для каждого сообщения. У нас есть утилита SPY подробнее читайте "Шаг 47 - Как пользоваться SPY", которая умеет следить за сообщениями Windows для конкретного окна. Разработчики использующие MFC имеют еще одну дополнительную утилиту MFC Tracer, читайте "Шаг 44 - Знакомимся с MFC Tracer", "Шаг 227 - afxTraceFlags", которая позволяет следить за сообщениями. Можно воспользоваться и сторонними утилитами, которые в основном нацелены на слежение за пользователями читайте "Шаг 139 - Программа слежения WinGuard".

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

HHOOK SetWindowsHookEx
(
    int idHook,	// тип перехвата
    HOOKPROC lpfn,	// процедура перехвата
    HINSTANCE hMod,	// указатель приложения
    DWORD dwThreadId	// идентифкатор потока
);

А для отмены перехвата UnhookWindowsHookEx. Ну попробуем, что ли. MFC приложение Dialog Bases:

152_1.gif (2450 b)

Заводим глобальную переменную:

static char THIS_FILE[] = __FILE__;
#endif

HHOOK hk;

/////////////////////////////////////
// CAboutDlg dialog used for App About

А теперь процедуру обработки, запуск и остановка перехвата:

LRESULT  CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    MessageBox(NULL,"Hook","Hook",MB_OK);
    return CallNextHookEx(hk, nCode, wParam, lParam);
}

void CHookDlg::OnStart()
{
    hk = SetWindowsHookEx(WH_KEYBOARD,&HookProc, NULL, 0);
}

void CHookDlg::OnStop()
{
    UnhookWindowsHookEx(hk);
}

Все можно запускать. Теперь после запуска программы и нажатия на Start, где бы Вы не нажали клавишу тут Ваша программа получит сообщение. Вот я в WORD попытался нажать клавишу:

152_2.gif (3003 b)

Полный пример есть в проекте.

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 153 - GetSystemMetrics и иконы

Функция GetSystemMetrics уже использовалась нами ранее в "Шаг 73 - Функция AdjustWindowRect()", "Шаг 184 - Создаем хранитель экрана", "Шаг 19 - Full Screen + MFC". Но в скользь как бы. Она простая.

int GetSystemMetrics
(
    int nIndex	// идентификатор настройки
);

Используя идентификаторы:

SM_CXSMICON,
SM_CYSMICON

Мы можем получить рекомендуемый размер икон.

// GetSystemMetric.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    cout << GetSystemMetrics(SM_CXSMICON) << endl;
}

А вот и результат у меня на ПК:

153_1.gif (3350 b)

Он соответствует настройкам в реестре.

153_2.gif (1743 b)

Подробнее в шаге "Шаг 52 - Отображение икон".

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 154 - Что такое почтовые слоты MailSlot

MailSlot - это файл, который находится в памяти, и Вы можете используете стандартные файловые функции Win32, чтобы иметь доступ к нему. Данные в mailslot могут быть в любой форме, но общий размер не может быть больше 64K. В отличие от дисковых файлов, файлы MailSlot временные. Когда все указатели на MailSlot закрываются, MailSlot и все данные, которые он содержит, удаляются. Есть два вида программ использующих данную возможность:

MailSlot сервер
MailSlot клиент

MailSlot cервер - является процессом, который создает и, обладает MailSlot. Когда сервер создает MailSlot, он получает указатель. Этот указатель должен использоваться, когда процесс читает сообщения от MailSlot. Только процесс, который создает MailSlot или получил указатель некоторым другим механизмом может прочитать данные из MailSlot. Все MailSlot локальные на процессе, который создает их; процесс не может создать дистанционный MailSlot.

MailSlot Клиент - является процессом, который пишет сообщение в MailSlot. Любой процесс, который имеет имя MailSlot может записать в него информацию.

Для создания почтовых слотов используются имена. При создании имя должно быть в следующей форме.

\\.\mailslot\[path]name

Обратите внимание на то, что только локально можно создавать почтовый слот. А вот использоваться можно любые почтовые слоты. Форма имени при открытии почтового слота.

\\ComputerName\mailslot\[path]name
или
\\DomainName\mailslot\[path]name
Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 155 - Создаем сервер почтового слота

Для создания сервера почтового слота используется функция:

HANDLE CreateMailslot
{
    LPCTSTR lpName,				// имя
    DWORD nMaxMessageSize,			// максимальный размер
    DWORD lReadTimeout,			// интервал-тайм аута чтения
    LPSECURITY_ATTRIBUTES lpSecurityAttributes	// информация о безопасности
);

При успешном выполнении мы получим указатель при неуспешном INVALID_HANDLE_VALUE. Обратите внимание на то, что имя должно быть уникальное. Пробуем:

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    HANDLE hsl=NULL;
    hsl= CreateMailslot("\\\\.\\mailslot\\hello",0,MAILSLOT_WAIT_FOREVER,NULL);
    if (hsl!=INVALID_HANDLE_VALUE)
    {
        cout << "Ok Created mailslot" << endl;
    }
}

Имя я указал по правилам, дальше идет размер 0 говорить о том, что размер не лимитируется и дальше, что таймауты не ограничены. Запускаем и смотрим

155_1.gif (3281 b)

Получилось. Давайте дадим умышлено неправильное имя для этого слота:

hsl= CreateMailslot("\\\\.mailslot\\hello",0,MAILSLOT_WAIT_FOREVER,NULL);

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

if (hsl!=INVALID_HANDLE_VALUE)
{
    cout << "Ok Created mailslot" <<  endl;
    char buffer[255];
    DWORD nBytesRead;
    if (ReadFile(hsl, &buffer, 255, &nBytesRead, NULL)!=0)
    {
        cout <<  "Ok read" <<  endl;
        cout <<  buffer <<  endl;
    }
}
int i;
cin >> i;
Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 156 - Создаем клиента почтового слота

Клиент почтового слота должен использоваться функцию CreateFile для открытия слота, но с флагом FILE_SHARE_READ. Потом он может воспользоваться функций WriteFile для записи информации. Смотрим пример:

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    HANDLE hf=NULL;
    hf=CreateFile("\\\\.\\mailslot\\hello",GENERIC_WRITE,
        FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    if (hf!=INVALID_HANDLE_VALUE)
    {
        cout << "Ok Open" << endl;
        char buffer[255];
        strcpy(buffer,"hello mail slot");
        DWORD dwwr;
        if (WriteFile(hf,&buffer,strlen(buffer),&dwwr,NULL)!=0)
        {
            cout << "OK Write" << endl;
        }
    }
}

Если сервер будет запушен, то он получит сообщение:

156_1.gif (6821 b)

Да еще одно но. В MSDN написано, что если клиент открываеи слот прежде чем слот был создан сервером, то он получит INVALID_HANDLE_VALUE:

156_2.gif (2966 b)

Как раз этого INVALID_HANDLE_VALUE я и не получаю. Если ошибка в пути, то действительно файл не открывается.

CreateFile("\\\\.\\ailslot\\hello",

А при явном бредовом имени:

CreateFile(\\\\.\\mailslot\\hel23lo

Все происходит успешно кроме записи.

156_3.gif (3320 b)

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 157 - Посылка сообщения по сети - WinPopup своими руками

Итак, мы с Вами пробовали локального клиента, а теперь нам нужно попробовать обратиться по сети. Точно так же как это делает WinPopup подробнее читайте "Шаг 53 - Обмен сообщениями по сети". В шаге "Шаг 154 - Что такое почтовые слоты MailSlot" описаны правила для имен, но вот вопрос в том на какой почтовый слот отсылать это сообщение. Имя у этого слота messngr. Вот это мы и проверим. Пишем:

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    HANDLE hf=NULL;
    hf=CreateFile("\\\\Servers\\mailslot\\messngr",GENERIC_WRITE,
        FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    if (hf!=INVALID_HANDLE_VALUE)
    {
        cout << "Ok Open" << endl;
        char buffer[255];
        strcpy(buffer,"hello mail slot");
        DWORD dwwr;
        if (WriteFile(hf,&buffer,strlen(buffer),&dwwr,NULL)!=0)
        {
            cout << "OK Write" << endl;
        }
    }
}

Я отправляю сообщение на сервер. Почему? Чего то меня это вопрос интересует о Сервере и рабочей станции исходя из того, что провайдер у меня на Windows NT работает. И вообще в Интернет некоторое количество сервером присутствует. Смотрим.

157_1.gif (3414 b)

Отправилось. А что на сервере?

157_2.gif (4703 b)

Есть сообщение, но без опознавательных знаков. Кто куда послал неизвестно, это неплохо, если посмотреть с некоторой стороны.

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 158 - Поиск файлов

Для поиска файлов используется две функции. Первая функция начинает поиск:

HANDLE FindFirstFile
(
    LPCTSTR lpFileName,		// какой файл ищем можно указывать маску *, ?
    LPWIN32_FIND_DATA lpFindFileData	// указатель на структуру с информацией
);

В случае ошибке вернет INVALID_HANDLE_VALUE. Для продолжения поиска используется функция:

BOOL FindNextFile
(
    HANDLE hFindFile,			// указатель на поиск
    LPWIN32_FIND_DATA lpFindFileData	// указатель на структуру с информацией
);

А теперь пробуем все вместе:

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    WIN32_FIND_DATA FindFileData;
    HANDLE hf;
    hf=FindFirstFile("c:\\*", &FindFileData);
    if (hf!=INVALID_HANDLE_VALUE)
    {
        do
        {
            cout << FindFileData.cFileName << endl;
        }
        while (FindNextFile(hf,&FindFileData)!=0);
        FindClose(hf);
    }
}

И смотрим. Ага, сработало:

158_1.gif (5100 b)

Точно так же Вы можете получить список доступных сетевых ресурсов.

hf=FindFirstFile("\\\\Servers\\work\\*", &FindFileData);
Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 159 - Подходы к созданию сервера MailSlot

В шаге "Шаг 155 - Создаем сервер почтового слота". Мы использовали MAILSLOT_WAIT_FOREVER для того, чтобы заблокировать операции чтения, но можно и использовать таймаут, в результате которого через указанное время блокировка сервера будет снята. Тогда придется постоянно обращаться к функции ReadFile для того, чтобы получить сообщения. Можно вот так:

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    HANDLE hsl=NULL;
    hsl= CreateMailslot("\\\\.\\mailslot\\he",0,5,NULL);
    if (hsl!=INVALID_HANDLE_VALUE)
    {
        cout << "Ok Created mailslot" <<  endl;
        char buffer[255];
        DWORD nBytesRead;
        while (true)
        {
            if (ReadFile(hsl, &buffer, 255, &nBytesRead, NULL)!=0)
            {
                cout <<  "Ok read" <<  endl;
                cout <<  buffer <<  endl;
                int i;
                cin >> i;
                return;
            }
            cout << "time aut" << endl;
        }
    }
}

159_1.gif (5151 b)

Есть еще одна полезная функция которая может дать нам информацию, что в слоте что-то есть.

BOOL GetMailslotInfo
(
    HANDLE hMailslot,		// указатель на слот
    LPDWORD lpMaxMessageSize,	// максимальный размер
    LPDWORD lpNextSize,	// размер следующего
    LPDWORD lpMessageCount,	// количество сообщений
    LPDWORD lpReadTimeout	// тайм аут.
);

Можно и ее применить для того, чтобы обнаружить что-то в слоте.

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    HANDLE hsl=NULL;
    hsl= CreateMailslot("\\\\.\\mailslot\\he",0,5,NULL);
    if (hsl!=INVALID_HANDLE_VALUE)
    {
        cout << "Ok Created mailslot" <<  endl;
        char buffer[255];
        DWORD nBytesRead;
        while (true)
        {
            DWORD dwmes=0;
            if (GetMailslotInfo(hsl,NULL,NULL,&dwmes,NULL)!=0)
            {
                if (dwmes>0)
                {
                    if (ReadFile(hsl, &buffer, 255, &nBytesRead, NULL)!=0)
                    {
                        cout <<  "Ok read" <<  endl;
                        cout <<  buffer <<  endl;
                        int i;
                        cin >> i;
                        return;
                    }
                }
            }
            cout << "time aut" << endl;
        }
    }
}

Эффект тот же, то ведь есть и функция SetMailslotInfo, которая может изменять тайм аут. Соответственно можно регулировать частоту опроса от максимума до минимума в зависимости от интенсивности трафика сообщений.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 160 - Winpopup и mailslot как открывают секреты

Мы с Вами в шаге "Шаг 157 - Посылка сообщения по сети - WinPopup своими руками". Для посылки сообщения использовали почтовый слот messngr. Попытки поиска этого слота в MSDN нечего не дают.

160_1.gif (7057 b)

Так как же его можно было узнать. Из шага "Шаг 155 - Создаем сервер почтового слота". Мы знаем, что для создания почтового слота нужна текстовая строка. Получается, что она хранится где-то в файле. И если вдруг она не шифрованная, то мы спокойно можем ее найти. Нашим оружием хакера будет WordPad. Открываем в нем WinPopup.exe подробнее о нем "Шаг 53 - Обмен сообщениями по сети". Даем поиск на слово mailslot так как именно это имя будет строке и Вы об этом знаете если прочитали шаги. Ищем. С первой же попытки.

160_2.gif (4458 b)

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

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 161 - Понимание именованных каналов (PIPE), или выяснение конфигурации сервера

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

161_1.gif (2652 b)

То на сервере создан одноименный канал и мы можем его открыть.

HANDLE hf=NULL;
hf=CreateFile("\\\\Servers\\pipe\\spoolss",GENERIC_READ | GENERIC_WRITE,
    0,NULL,OPEN_EXISTING,0,NULL);
if (hf!=INVALID_HANDLE_VALUE)
{
    cout << "Ok Open" << endl;
}

161_2.gif (1598 b)

В отличии от почтовых слотов подробнее "Шаг 156 - Создаем клиента почтового слота", мы сможем открыть канал только в том случае, если этот канал реально существует. А вот теперь остановим сервис.

161_3.gif (3696 b)

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

\pipe\sql\query

Данный канал открыт, когда на сервере работает MS SQL Server. Кстати всяких каналов много, вот например.

\PIPE\SERVRCON
\PIPE\ALERTS
\PIPE\DNSSERVER

И так далее, конечно получить доступ Вы можете далеко не ко всем каналам, еще раз все зависит от запущенных сервисов.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 162 - Утилита для просмотра функций и связей в DLL

В шаге "Шаг 28 - Список функций из DLL AddressOfNames". Мы получали список функций из DLL программным путем. Но в поставку Visual Studio входит утилита Depends.exe, которую можно найти Tools.

162_1.gif (5230 b)

Запускайте ее, открывайте DLL, и смотрите какие функции есть внутри и с какими другими DLL связанна данная.

162_2.gif (10270 b)

Здесь Вы можете увидеть экспортируемы и импортируемые функции.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 163 - Программный вход и выход из сети

Microsoft, Microsoft - сколько мною времени потрачено на выяснение этой простой веши, как же программно зайти в сеть. То есть вызвать инициализацию для входа в сеть. Реализована она в Windows отвратно, читайте "Шаг 55 - Вход в сеть". При входе или выходе из сети выгружаются приложения. Но есть возможность это обойти. Сразу смотрим код.

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

typedef  BOOL (WINAPI LOGON)(LPSTR,HWND);
typedef  BOOL (WINAPI LOGOOFF)(LPSTR,HWND);

void main()
{
    HINSTANCE hModule=NULL;
    hModule=::LoadLibrary("mpr.dll");
    if (hModule!=NULL)
    {
        cout << "ok load" << endl;
        LOGON* logon=NULL;
        logon=(LOGON*)::GetProcAddress((HMODULE)hModule,"WNetLogonA");
        if (logon!=NULL)
        {
            cout << "OK Load" << endl;
            BOOL result;
            result=(*logon)(NULL,NULL);
            if (result==0)
            {
                cout << "Ok function" << endl;
                char c;
                cin >> c;
                LOGOOFF* logoof=NULL;
                logoof=(LOGOOFF*)::GetProcAddress((HMODULE)hModule,"WNetLogoffA");
                if (logoof!=NULL)
                {
                    cout << "Ok Function" << endl;
                    result=(*logoof)(NULL,NULL);
                    if (result==0)
                    {
                        cout << "Ok Exit Net" << endl;
                    }
                }
            } else cout << GetLastError() << endl;

        }
        ::FreeLibrary(hModule);
    }
    else cout << "error load Dll" << endl;
}

Здесь использованы две функции, такие как WnetLogonA и WnetLogoffA. В заголовочных файлах они не описаны и по этому придется вызывать их напрямую. Об этом читайте "Шаг 41 - Явный вызов функций DLL". Итак, что мы имеем. Выйдите из сети. Запустите программу и Вы увидите то, что наверно не видели не когда. Вход в сесть при работающих приложениях.

163_1.gif (9351 b)

Достаточно ввести пароль и Вы войдете в сеть. После ввода в окно буквы и нажатия Enter Вы выйдите из сети.

163_2.gif (4001 b)

Пароль нужно будет вводить только один раз. При всех остальных запусках и остановках работы с сетью пароль будет уже не нужен.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 164 - Извлечение паролей

Привет Артем! Вот тоже кусок кода про mpr.dll
Не знаю насколько этично его публиковать.
Откомпиль в 98 и запусти.
"Bulat" <raditch@ufacom.ru>

Пароли могут храниться локально, если такие у Вас есть, а проверить Вы это сможете, прочитав шаг "Шаг 57 - Редактор списка паролей", то мы можем воспользоваться этим и извлечь их. Опять могу сказать, что данный вопрос в MSDN практически не рассматривается. Функция упоминается, но параметры не приводятся.

#include "stdafx.h"
#include "windows.h"
#include "stdio.h"
#include "conio.h"

typedef struct tagPASSWORD_CACHE_ENTRY {
    WORD cbEntry;		// size of this entry, in bytes
    WORD cbResource;		// size of resource name, in bytes
    WORD cbPassword;		// size of password, in bytes
    BYTE iEntry;		// entry index
    BYTE nType;		// type of entry
    BYTE abResource[1];	// start of resource name
                // password immediately follows resource name
} PASSWORD_CACHE_ENTRY;

char buf[1024], ob1[1024];

BOOL CALLBACK pce(PASSWORD_CACHE_ENTRY *x, DWORD)
{
    memmove(buf, x->abResource, x->cbResource);
    buf[x->cbResource] = 0;
    CharToOem(buf, ob1);
    printf("%s : ", ob1);

    memmove(buf, x->abResource+x->cbResource, x->cbPassword);
    buf[x->cbPassword] = 0;
    CharToOem(buf, ob1);
    printf("%s\n", ob1);

    return TRUE;
}

void main()
{
    HINSTANCE hi = LoadLibrary("mpr.dll");
    if(!hi)
    {
        puts("Couldn't load mpr.dll");
        return;
    }
    WORD (__stdcall *enp)(LPSTR, WORD, BYTE, void*, DWORD) =
    (WORD (__stdcall *)(LPSTR, WORD, BYTE, void*, DWORD))GetProcAddress(hi, "WNetEnumCachedPasswords");
    if(!enp)
    {
        puts("Couldn't import function");
        return;
    }
    (*enp)(0, 0, 0xff, pce, 0);
    getch();
    FreeLibrary(hi);
}

А вот результат. Я правда пароли на всякий случай прикрыл списком из редактора паролей.

164_1.gif (4069 b)

Шаг прислал Bulat.

От Артема: Там Bulat писал о том, что этично ли писать такие веши на сайт или нет. Можно мое мнение? Вопрос не в этичности. Вопрос в знании правды, а вот знать правду этично или нет, каждый решает сам. Мало кто ответит на такой простой вопрос - что лучше знать или нет, если девушка изменяет? Насчет того, что данными знаниями могут воспользоваться для нанесения вреда. Опять вопрос философский, есть много примеров из истории человечества, например атомная бомба, которая теперь является гарантом мира как ни странно. И еще я тут смотрю, как обесценивается с каждым днем понятие специалиста в области компьютеров. Человек только заставку научился менять на Windows, а уже и зарплату ему подавай побольше и все такое. Может подобные материалы заставят задуматься людей о уровне своей квалификации. О том, что та же Windows 98 хоть и не NT, но довольно сложная OS и за кнопкой ПУСК и рабочим столом есть еще что то.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 165 - Получения дескриптора VXD

Для открытия VXD файла используется функция CreateFile с флагом FILE_FLAG_DELETE_ON_CLOSE что означаем что файл закрывается и удаляется из памяти когда на него нету указателя. Смотрим пример:

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

void main()
{
    HANDLE hDevice=NULL;
    hDevice = CreateFile("\\\\.\\NDIS", 0, 0, NULL,
        0, FILE_FLAG_DELETE_ON_CLOSE, NULL);

    if (hDevice!=INVALID_HANDLE_VALUE)
    {
        cout << "Ok" << endl;
        CloseHandle(hDevice);
    }
    else
    {
        DWORD error;
        error=GetLastError();
        cout << "Error Code " << error << endl;
        if (error==ERROR_FILE_NOT_FOUND)
            cout << "File Nof Found" << endl;
        if (error==ERROR_NOT_SUPPORTED)
            cout << "Not support IOST interface" << endl;
    }
}

Самое главное откуда взять имя. В данном случае имя это имя в реестре:

165_1.gif (2057 b)

Подробнее о реестре и где все это хранится читайте в шаге "Шаг 151 - Что такое VXD". Смотрим результат.

165_2.gif (2869 b)

Загрузился.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 166 - Функция DeviceIoControl

Данная функция используется для передачи команд устройствам, а точнее не им, а их виртуальным драйверам. Подробнее читайте "Шаг 151 - Что такое VXD". Для того, чтобы использовать ее нужен дескриптор VXD файла о том, как его получить читайте "Шаг 165 - Получения дескриптора VXD". Сама функция имеет следующий вид:

BOOL DeviceIoControl
(
    HANDLE hDevice,		// дескриптор устройства
    DWORD dwIoControlCode,	// код операции
    LPVOID lpInBuffer,		// буфер входных данных
    DWORD nInBufferSize,	// размер буфера входных данных
    LPVOID lpOutBuffer,	// буфер данных результата
    DWORD nOutBufferSize,	// размер буфера результата
    LPDWORD lpBytesReturned,	// адрес данных для вывода
    LPOVERLAPPED lpOverlapped	// адрес перекрывающей структуры
);

При успешном выполнении функция вернет ненулевое значение.

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 167 - Понимание функции DeviceIoControl

Со времен MS DOS не очень много чего изменилось. Как были устройства так они и есть. Как была идея использование прерываний так она и осталась. Сейчас нельзя напрямую получить доступ к устройствам. Для этого существуют VXD драйвера. Подробнее читайте "Шаг 151 - Что такое VXD". Основывается работа на использовании прерываний. Тут бы я посоветовал, если Вы вообще не знаете ассемблера прочитать шаги от "Шаг 1 - Где взять и установка" до "Шаг 19 - Функция 44H подфункция 08H INT 21H проверка носителя". Если ассемблер Вы знаете, то достаточно "Шаг 19 - Функция 44H подфункция 08H INT 21H проверка носителя". Итак, функция DeviceIoControl описанная в прошлом шаге может нам дать доступ к функциям прерывания INT21H 44H. Для этого нужно использовать код операции VWIN32_DIOC_DOS_IOCTL. То есть мы получаем доступ и функция контроля ввода вывода IOCTL по идеологии похожими на ДОС. Подробнее о IOCTL читайте "Шаг 15 - Что такое IOCTL". Смотрим код:

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

typedef struct DIOCRegs {
    DWORD reg_EBX;
    DWORD reg_EDX;
    DWORD reg_ECX;
    DWORD reg_EAX;
    DWORD reg_EDI;
    DWORD reg_ESI;
    DWORD reg_Flags;
} DIOC_REGISTERS;

#define VWIN32_DIOC_DOS_IOCTL 1

void main()
{
    HANDLE hDevice;
    hDevice = CreateFile("\\\\.\\vwin32", 0, 0, NULL,
        0,FILE_FLAG_DELETE_ON_CLOSE, NULL);
    if (hDevice != INVALID_HANDLE_VALUE)
    {
        DWORD dw;
        BOOL result;
        for (unsigned int x=15;x>0;x--)
        {
            DIOC_REGISTERS reg;
            reg.reg_EAX = 0x8;
            reg.reg_EBX = x;
            result = DeviceIoControl(hDevice,VWIN32_DIOC_DOS_IOCTL,
                &reg, sizeof(reg), &reg, sizeof(reg), &dw, 0);
            if (result != 0)
            {
                cout << x << "Ok - " << reg.reg_EAX << endl;
                if (reg.reg_EAX==0)
                    cout << " removable   " << endl;
                if (reg.reg_EAX==1)
                    cout << " not removable" << endl;
                if (reg.reg_EAX==0x0F)
                    cout << " error " << endl;
            }
            else
            {
                cout << GetLastError() << endl;
                cout << "Error" << endl;
            }
        }
        CloseHandle(hDevice);
    }
    else cout << "Error Open " << endl;
}

Мы вызываем функцию 08H которая может нам вернуть является ли диск извлекаемым или нет. Подробнее в шаге Функция 44H подфункция 08H INT 21H проверка носителя. А вот и результат.

167_1.gif (2840 b)

В отличии от версии 16 разрядной созданной на TASM мы смогли узнать что диск 2 (B) это ERROR и правда у меня он не установлен. А дисков у меня и правда 7.

167_2.gif (2152 b)

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

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 168 - Удаление файлов используемых системой в Windows 98

Время от времени приходится сталкиваться с проблемой перемещения или удаления файлов, которые используются системой в настоящий момент, будь то исполняемый модуль или DLL. Один из таких моментов описан в шаге "Шаг 37 - Война с W32.Nimda.E@mm (dr) virus". Если бы речь шла о Windows NT, то там все предельно просто и, можно сказать, красиво:

MoveFileEx(откуда, куда, MOVEFILE_DELAY_UNTIL_REBOOT)

И все! А хочешь удалить:

MoveFileEx(откуда, NULL, MOVEFILE_DELAY_UNTIL_REBOOT)

Тоже хорошо.

Но беда в том, что эта функция не поддерживается в Windows 9X, ну и ладно сделаем её сами, благо Microsoft оставил нам такую возможность. В Windows 9X используется тот же принцип, что и в NT - на диске сохраняется информация о перемещаемых файлах, которая используется при загрузке системы. Разница в том, что NT использует для этой цели реестр:

(HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations),

А 9Х - файл WININIT.INI, если вы заглянете в каталог Windows, то скорей всего вы его там не найдете, вместо этого там лежит WININIT.BAK. Если мы заглянем в него, то увидим что-нибудь типа:

[rename]
C:\WINDOWS\SYSTEM\OLEAUT32.DLL=C:\WINDOWS\SYSTEM\OLEAUT32.001
NUL=C:\WINDOWS\SYSTEM\DDHELP.EXE
......

Здесь то, что осталось после инсталляции (у меня от DirectX SDK). Думаю, что детального описания не требуется, в отличие от MoveFileEx, здесь изменено направление - куда=откуда, а вместо NULL - NUL. Одно небольшое замечание: файл WININIT.INI используется в WININIT.EXE при запуске системы, оно не является приложением Win32 и стартует до загрузки защищенного режима диска, поэтому имена файлов (и пути разумеется) должны быть "короткими" (в формате 8.3). Ну а теперь посмотрим что мы с этого имеем. За основу возьмем код Джеффри Рихтера (Jeffry Richter) из Win32 Q&A, выкинем все "лишнее", дадим функции новое имя и снабдим нашими комментариями. Вот её реализация:

BOOL MoveFileOnReboot (LPCTSTR pszExisting, LPCTSTR pszNew)
{
    BOOL bResult = FALSE;

    //буфер для нашей строки: куда=откуда
    char	szRenameLine[1024];
    //длина строки; заодно заполним буфер
    int		cchRenameLine = wsprintfA(szRenameLine,
    #ifdef UNICODE
        "%ls=%ls\r\n",
    #else
        "%hs=%hs\r\n",
    #endif
        (pszNew == NULL) ? __TEXT("NUL") : pszNew, pszExisting); //если NULL,
                         //то строка будет NUL=откуда

    //запомним как зовется секция в WININIT.INI,
    char szRenameSec[] = "[Rename]\r\n";
    //а длину сосчитаем по ходу
    int cchRenameSec = sizeof(szRenameSec) - 1;

    HANDLE hfile, hfilemap;
    DWORD dwFileSize, dwRenameLinePos;
    TCHAR szPathnameWinInit[_MAX_PATH];
    //Сообразим полный путь к WININIT.INI
    GetWindowsDirectory(szPathnameWinInit, _MAX_PATH);
    lstrcat(szPathnameWinInit, __TEXT("\\WinInit.Ini"));
    // Откроем или создадим WININIT.INI.
    hfile = CreateFile(szPathnameWinInit,
            GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
    if(hfile == INVALID_HANDLE_VALUE)
        return bResult;
    //Создаем hfilemap с учетом длины названия нашей секции
    //и нашей строки
    dwFileSize = GetFileSize(hfile, NULL);
    hfilemap = CreateFileMapping(hfile, NULL, PAGE_READWRITE, 0,
                dwFileSize + cchRenameLine + cchRenameSec, NULL);
    if(hfilemap != NULL)
    {
        //Проецируем WININIT.INI в память.
        LPSTR pszWinInit = (LPSTR)MapViewOfFile(hfilemap,
            FILE_MAP_WRITE, 0, 0, 0);
        if(pszWinInit != NULL)
        {
            // Ищем секцию [Rename]
            LPSTR pszRenameSecInFile = strstr(pszWinInit, szRenameSec);
            if(pszRenameSecInFile == NULL)
            {
                //Секции нет - будем добавлять.
                dwFileSize += wsprintfA(&pszWinInit[dwFileSize], "%s",
                            szRenameSec);
                //Позиция с которой вставлять
                dwRenameLinePos = dwFileSize;
            }
            else
            {
                //Секция есть
                PSTR pszFirstRenameLine = strchr(pszRenameSecInFile, '\n');
                // Сдвинем содержимое файла на длину нашей строки,
                // всегда будет добавлятся в начало списка
                pszFirstRenameLine++;	// 1-й символ новой строки
                memmove(pszFirstRenameLine + cchRenameLine, pszFirstRenameLine,
                    pszWinInit + dwFileSize - pszFirstRenameLine);
                // Позиция с которой будем вставлять
                dwRenameLinePos = pszFirstRenameLine - pszWinInit;
            }
            // Вставляем строку
            memcpy(&pszWinInit[dwRenameLinePos], szRenameLine,cchRenameLine);

            UnmapViewOfFile(pszWinInit);
            // Новая длина файла.
            dwFileSize += cchRenameLine;
            bResult = TRUE; //...все было просто здорово
        }
        CloseHandle(hfilemap);
    }
    //Добавляем EOF.
    SetFilePointer(hfile, dwFileSize, NULL, FILE_BEGIN);
    SetEndOfFile(hfile);
    CloseHandle(hfile);
    return bResult;
}

В качестве примера небольшой проект: при запуске приложения выводим диалог для ввода пароля и запускаем приложение, если введен неправильный пароль мы тихо удаляем программку. Запустите ее и не забудьте заглянуть в WININIT.INI. Конечно же это не защита, да и сам пример не претендует на изящность, главное - показать, что функция действительно работает. Здесь лишь принцип, и не сам принцип, а его идея. Суть в том, что мы усыпляем бдительность "не хорошего" юзера, даем ему поработать, а после всего уходим не прощаясь (помня о нанесенной обиде :)). Конечно, это подойдет не всегда и не всем, для того чтобы программе удалить себя, можно, к примеру, создав "на лету" batch с бесконечным циклом удаления exeшника. Единственное нормальное применение этому это, наверно, инсталлятор или функция обновления в самой программе.

Загрузить проект | Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 169 - Чтение секторов с диска в Win32

Сектора с диска в Win32 читаются точно так же, как и в DOS "Шаг 21 - Функция абсолютного чтения с диска 25h". Только придется нам использовать DeviceIoControl, читайте "Шаг 167 - Понимание функции DeviceIoControl". Итак, вся проблема в том какая функция, вот она:

#define VWIN32_DIOC_DOS_INT25 2

Аналог функции из DOS. Осталось только настроить регистры и вперед.

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

typedef struct DIOCRegs {
    DWORD reg_EBX;
    DWORD reg_EDX;
    DWORD reg_ECX;
    DWORD reg_EAX;
    DWORD reg_EDI;
    DWORD reg_ESI;
    DWORD reg_Flags;
} DIOC_REGISTERS;

#define VWIN32_DIOC_DOS_INT25 2

void main()
{
    HANDLE hDevice;
    hDevice = CreateFile("\\\\.\\vwin32", 0, 0, NULL,
        0,FILE_FLAG_DELETE_ON_CLOSE, NULL);
    if (hDevice != INVALID_HANDLE_VALUE)
    {
        DWORD dw;
        BOOL result;

        DIOC_REGISTERS reg;

        char data[512];

        reg.reg_EAX = 3;
        reg.reg_ECX = 1;
        reg.reg_EDX = 0;
        reg.reg_EBX =(unsigned long) &data;
        result = DeviceIoControl(hDevice,VWIN32_DIOC_DOS_INT25,
            &reg, sizeof(reg),&reg, sizeof(reg), &dw, 0);
        if (result != 0)
        {
            cout << "Ok - " << endl;
            cout << data << endl;
        }
        else
        {
            cout << GetLastError() << endl;
            cout << "Error" << endl;
        }
        CloseHandle(hDevice);
    }
    else cout << "Error Open " << endl;
}

И результат смотрим точно такой, как и при использовании TASM. Но есть одно, но Вы видите не всю строку, так как среди прочитанных данных есть символ окончания строки.

169_1.gif (3301 b)

Предыдущий Шаг | Следующий Шаг
Автор Каев Артем.


Шаг 170 - Создание дочерних окон на C

Это довольно упрощенный пример для шага "1.26.2 Создание, перечисление и изменение размеров дочерних окон". Все максимально упрощено. За основу взят шаг "Шаг 4 - Окно Windows на С". Вот в него мы и добавляем изменения. Итак, смотрим код.

// ChildWin.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "windows.h"
#include "windowsx.h"

// Идентификаторы окон
#define ID_FIRSTCHILD	100
#define ID_SECONDCHILD	101
#define ID_THIRDCHILD	102

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,LPARAM);
LRESULT CALLBACK ChildProc(HWND, UINT, WPARAM,LPARAM);

HINSTANCE hinst;

int APIENTRY WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow)
{
    HWND hwnd;
    MSG msg;
    WNDCLASS w;
    hinst=hInstance;
    memset(&w,0,sizeof(WNDCLASS));
    w.style = CS_HREDRAW | CS_VREDRAW;
    w.lpfnWndProc = WndProc;
    w.hInstance = hInstance;
    w.hbrBackground = GetStockBrush(WHITE_BRUSH);
    w.lpszClassName = "C Windows";
    w.hCursor=LoadCursor(NULL,IDC_ARROW);
    RegisterClass(&w);
    hwnd = CreateWindow("C Windows","C Windows", WS_OVERLAPPEDWINDOW,
        10,10,600,480,NULL,NULL,hInstance,NULL);
    ShowWindow(hwnd,nCmdShow);
    UpdateWindow(hwnd);
    while(GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wparam,LPARAM lparam)
{
    switch(Message)
    {
    case WM_CREATE:	// создание основного окна
        for (int i = 0; i < 3; i++)	// Создание трех  дочерних окна
        {
            WNDCLASS w;
            memset(&w,0,sizeof(WNDCLASS));
            w.lpfnWndProc = ChildProc;
            w.hInstance = hinst;
            w.hbrBackground = GetStockBrush(WHITE_BRUSH);
            w.lpszClassName = "ChildWClass";
            w.hCursor=LoadCursor(NULL,IDC_CROSS);
            RegisterClass(&w);
            HWND child;
            child=CreateWindowEx(0,"ChildWClass",(LPCTSTR) NULL,
                WS_CHILD | WS_BORDER | WS_VISIBLE ,i*10,i*10,
                50,50,hwnd,(HMENU) (int) (ID_FIRSTCHILD + i),hinst,NULL);
            ShowWindow(child,SW_NORMAL);
            UpdateWindow(child);
        }
        return 0;
    }

    if (Message == WM_DESTROY )
    {
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd,Message,wparam,lparam);
}

LRESULT CALLBACK ChildProc(HWND hwnd, UINT Message, WPARAM wparam,LPARAM lparam)
{
    if (Message == WM_DESTROY )
    {
        return 0;
    }
    return DefWindowProc(hwnd,Message,wparam,lparam);
}

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

170_1.gif (1869 b)

Если обратили внимание, я добавил разные описания курсоров:

// родительское окно
w.hCursor=LoadCursor(NULL,IDC_ARROW);
// дочернее окно
w.hCursor=LoadCursor(NULL,IDC_CROSS);

Вы можете поводить мышкой и увидите, что курсор в дочернем окне изменяться.

Загрузить проект | Предыдущий Шаг
Автор Каев Артем.


Глава 7 - Hook-метод

Примечание переводчика: hook-метод – это специальный прием, который позволяет отслеживать в системе или программе некоторые события и фильтровать их. Надо отметить, что в справочнике по API термин hook procedure переводится двояко: то как фильтр-процедура, то как подключаемая процедура. И тот, и другой перевод применяется в русскоязычной литературе по API. Поэтому условимся, что в главах справочника оба перевода будут применяться как синонимы, чтобы в тексте избегать утомительных повторений (тавтологий).

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

Этот краткий обзор описывает Windows hook-точки и объясняет, как использовать их в базирующейся на Win32 прикладной программе.

Следующий Шаг
Автор Владимир Соковиков.


7.1 - О Hook-точках

Hook-точки имеют тенденцию замедлять систему, потому что они увеличивают суммарное время обработки, за которое система должна выполнить ее для каждого сообщения. Вы должны устанавливать hook-точку, только тогда, когда это необходимо и удалять ее как можно скорее.


7.2 - Цепочки hook-точек

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

Windows поддерживает отдельную цепочку hook-точек для каждого типа hook-точки. Цепочка hook-точек (hook chain) - список указателей на специальные, определяемые программой функции повторного вызова называемые подключаемыми процедурами (hook procedure). Когда попадается сообщение, который связано со специфическим типом hook-точки, Windows передает это сообщение в каждую подключаемую процедуру, вызываемую одну за другой в цепочке hook-точек. Действие, которое может выбрать подключаемая процедура, зависит от типа включенной hook-точки. Подключаемые процедуры для некоторых типов hook-точек могут только отслеживать сообщения; другие могут изменять сообщения или останавливать их продвижение по цепочке, не давая достигать им следующей подключаемой процедуры или окна назначения.


7.3 - Подключаемые процедуры (Hook procedures)

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

Синтаксис

LRESULT CALLBACK HookProc
(
    int nCode,
    WPARAM wParam,
    LPARAM lParam
)

HookProc - метка - заместитель для определяемого программой названия процедуры.

Параметр nCode - код hook-точки, который подключаемая процедура использует, чтобы определить действие на исполнение. Значение кода hook-точки зависит от ее типа; каждый тип имеет свой собственный характерный набор кодов hook-точки. Значения параметров wParam и lParam зависят от кода hook-точки, но они обычно содержат информацию о сообщении, которое было отправлено или передано.

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

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

Подключаемая процедура может быть глобальной, контролируя сообщения для всех потоков в системе, или она может быть для конкретного потока, контролируя сообщения только для отдельного потока. Глобальная фильтр - процедура может быть вызвана применительно к любой прикладной программе, так что процедура должна быть в отдельном модуле динамически подключаемой библиотеки (DLL). Конкретный поток вызывает подключаемую процедуру только применительно к связанному потоку. Если прикладная программа устанавливает фильтр - процедуру для одного из своих собственных потоков, подключаемая процедура может быть или в том же самом модуле, как остальная часть кода приложения, или в динамически подключаемой библиотеке (DLL). Если прикладная программа устанавливает фильтр - процедуру для потока другой прикладной программы, процедура должна быть в динамически подключаемой библиотеке (DLL). За большей информацией обратитесь к статье. Библиотеки Динамической связи.

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


7.4 - Типы hook-точек

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

Hook-точки WH_CALLWNDPROC и WH_CALLWNDPROCRET
Hook-точка WH_CBT
Hook-точка WH_DEBUG
Hook-точка WH_FOREGROUNDIDLE
Hook-точка WH_GETMESSAGE
Hook-точка WH_JOURNALPLAYBACK
Hook-точка WH_JOURNALRECORD
Hook-точка WH_KEYBOARD
Hook-точка WH_MOUSE
Hook-точки WH_MSGFILTER и WH_SYSMSGFILTER
Hook-точка WH_SHELL


7.4.1 - Hook-точки WH_CALLWNDPROC и WH_CALLWNDPROCRET

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

Hook-точка WH_CALLWNDPROCRET передает адрес структуры CWPRETSTRUCT в подключаемую процедуру. Структура содержит возвращаемое значение из оконной процедуры, которая обработала сообщение, а также параметры сообщения, связанные с ним. Деление на подклассы окон не работает для сообщений, установленных между процессами.

Для получения дополнительной информации, см. функции CallWndProc и CallWndRetProc.


7.4.2 - Hook-точка WH_CBT

Windows вызывает подключаемую процедуру WH_CBT перед активизацией, созданием, разрушением, уменьшением, максимизированием, перемещением, или установкой размеров окна; перед завершением системной команды; перед удалением события мыши или клавиатуры из системной очереди сообщений; перед установкой фокуса ввода; или перед синхронизацией системной очереди сообщений. Значение, возвращаемое подключаемой процедурой, определяет, позволяет ли Windows или не допускает одно из этих действий. Hook-точка WH_CBT предназначена прежде всего для основной компьютерной подготовки (CBT) прикладной программы.

Для получения дополнительной информации, см. функцию CBTProc.


7.4.3 - Hook-точка WH_DEBUG

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

Для получения дополнительной информации, см. функцию DebugProc.


7.4.4 - Hook-точка WH_FOREGROUNDIDLE

Hook-точка WH_FOREGROUNDIDLE позволяет вам выполнять низкоприоритетные задачи в тот период, когда приоритетный поток не используется.

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

За большей информацией обратитесь к статье Функция ForegroundIdleProc.


7.4.5 - Hook-точка WH_GETMESSAGE

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

Для получения дополнительной информации, см. статью Функция GetMsgProc.


7.4.6 - Hook-точка WH_JOURNALPLAYBACK

Hook-точка WH_JOURNALPLAYBACK дает возможность прикладной программе вставлять сообщения в системную очередь сообщений. Вы можете использовать эту hook-точку, чтобы воспроизвести ряд событий от мыши и клавиатуры, занесенных в список ранее при помощи использования hook-точки WH_JOURNALRECORD. Нормальный ввод данных от мыши и клавиатуры блокируется то тех пор, пока установлена hook-точка WH_JOURNALPLAYBACK. Hook-точка WH_JOURNALPLAYBACK является глобальной hook-точкой , то есть не может быть использована как hook-точка, определяемая потоком.

Hook-точка WH_JOURNALPLAYBACK возвращает значение блокировки времени. Это значение сообщает системе, сколько миллисекунд необходимо ждать перед обработкой текущего сообщения от hook-точки воспроизведения. Это дает возможность hook-точке управлять величиной времени воспроизводимых событий.

Для получения дополнительной информации, см. статью Функция JournalPlaybackProc.


7.4.7 - Hook-точка WH_JOURNALRECORD

Hook-точка WH_JOURNALRECORD дает Вам возможность контролировать и занести в список входящие события. Как правило, Вы используете эту hook-точку, чтобы записать в список последовательности событий от мыши и клавиатуры, чтобы воспроизвести их позже, используя hook-точку WH_JOURNALPLAYBACK. Hook-точка WH_JOURNALRECORD - глобальная hook-точка, это означает, что она не может быть использована как hook-точка, определяемая потоком.

Для получения дополнительной информации, см. статью Функция JournalRecordProc.


7.4.8 - Hook-точка WH_KEYBOARD

Hook-точка WH_KEYBOARD дает возможность прикладной программе контролировать поток сообщений для сообщений WM_KEYDOWN и WM_KEYUP, которые функция GetMessage или PeekMessage намеревается возвратить. Вы можете использовать hook-точку WH_KEYBOARD, чтобы контролировать ввод с клавиатуры, переданный в очередь сообщений.

Для получения дополнительной информации, см. статью о функции KeyboardProc.


7.4.9 - Hook-точка WH_MOUSE

Hook-точка WH_MOUSE дает возможность Вам контролировать сообщения мыши, которые функция GetMessage или PeekMessage намеревается возвратить. Вы можете использовать hook-точку WH_MOUSE, чтобы контролировать ввод мыши, переданный в очередь сообщений.

Для получения дополнительной информации, см. статью о функции MouseProc.


7.4.10 Hook-точки WH_MSGFILTER и WH_SYSMSGFILTER

Hook-точки WH_MSGFILTER и WH_SYSMSGFILTER дают возможность Вам контролировать сообщения, которые будут обработаны меню, линейкой прокрутки, окном сообщений или диалоговым окном, и обнаруживать, когда другое окно собирается стать активным в результате нажима пользователем комбинации клавиш ALT+TAB или ALT+ESC. Hook-точка WH_MSGFILTER может контролировать только сообщения переданные в меню, линейку прокрутки, окну сообщений или блоку диалога, созданному прикладной программой, которая установила подключаемую процедуру. Hook-точка WH_SYSMSGFILTER контролирует такие сообщения для всех прикладных программ.

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

Прикладная программа может вызывать hook-точку WH_MSGFILTER непосредственно, вызывая функцию CallMsgFilter. Используя эту функцию, прикладная программа может использовать тот же самый код, чтобы фильтровать сообщения в ходе модальных циклов, поскольку он используется в основном цикле сообщений. Поступив так, вы инкапсулируйте операции фильтрации в подключаемой процедуре WH_MSGFILTER и вызываете CallMsgFilter между обращениями к функциям GetMessage и DispatchMessage.

while (GetMessage(&msg, (HWND) NULL, 0, 0))
{
    if (!CallMsgFilter(&qmsg, 0))
        DispatchMessage(&qmsg);
}

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

Для получения дополнительной информации, см. статью о функции MessageProc и SysMsgProc.


7.4.11 - Hook-точки WH_SHELL

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

Для получения дополнительной информации, см. статью о функции ShellProc.


7.5 - Использование hook-точек

Установка и освобождение подключаемой процедуры
Отслеживание системных событий


7.5.1 - Установка и освобождение подключаемых процедур (Hook Procedures)

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

Вы должны поместить глобальную подключаемую процедуру в динамически подключаемой библиотеке (DLL), отделенной от прикладной программы, устанавливающей подключаемую процедуру. Приложение установки должно иметь дескриптор модуля динамически подключаемой библиотеки (DLL) прежде, чем оно может установить подключаемую процедуру. Функция LoadLibrary, когда дается имя динамически подключаемой библиотеке (DLL), возвращает дескриптор модуля DLL. После того, как Вы получите дескриптор, Вы можете вызвать функцию GetProcAddress, чтобы получить адрес подключаемой процедуры. Наконец, Вы используете SetWindowsHookEx, чтобы установить адрес подключаемой процедуры в соответствующую цепочку hook-точек. SetWindowsHookEx передает дескриптор модуля, указатель на точку входа подключаемой процедуры и 0 для идентификатора потока, указывая, что подключаемая процедура должна быть связана со всеми потоками в системе. Эта последовательность действий показывается в следующем примере.

HOOKPROC hkprcSysMsg;
static HINSTANCE hinstDLL;
static HHOOK hhookSysMsg;
hinstDLL = LoadLibrary((LPCTSTR) "c:\\windows\\sysmsg.dll");
hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "SysMessageProc");
hhookSysMsg = SetWindowsHookEx(WH_SYSMSGFILTER, hkprcSysMsg, hinstDLL, 0);

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

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

Альтернативный метод для установки глобальной подключаемой процедуры состоит в том, чтобы предусмотреть инсталляционную функцию в динамически подключаемой библиотеке (DLL), наряду с подключаемой процедурой. С этим методом, прикладная программа установки не нуждается в дескрипторе модуля DLL. Связываясь с DLL, прикладная программа получает доступ к инсталляционной функции. Инсталляционная функция может снабдить модуль динамически подключаемой библиотеки (DLL) дескриптором и другие деталями при обращении к SetWindowsHookEx. Динамически подключаемая библиотека (DLL) может также содержать функцию, которая освобождает глобальную подключаемую процедуру; прикладная программа может вызывать при завершении функцию этой освобождающейся hook-точки.


7.5.2 - Отслеживание системных событий

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

WH_CALLWNDPROC
WH_CBT
WH_DEBUG
WH_GETMESSAGE
WH_KEYBOARD
WH_MOUSE
WH_MSGFILTER

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

#define NUMHOOKS 7

// Глобальные переменные

typedef struct _MYHOOKDATA
{
    int nType;
    HOOKPROC hkprc;
    HHOOK hhook;
} MYHOOKDATA;

MYHOOKDATA myhookdata[NUMHOOKS];

LRESULT WINAPI MainWndProc(HWND hwndMain, UINT uMsg, WPARAM wParam,
    LPARAM lParam)
{
    static BOOL afHooks[NUMHOOKS];
    int index;
    static HMENU hmenu;

    switch (uMsg)
    {
        case WM_CREATE:

            // Сохранение дескриптора меню.

            hmenu = GetMenu(hwndMain);

            // Инициализация структуры с данными hook-точки. Идентификаторы
            // элементов меню определены от 0 до 6 в заголовочном
            // файле. Они могут быть использованы для идентификации массива
            // элементов или здесь или в ходе обработки сообщения WM_COMMAND.

            myhookdata[IDM_CALLWNDPROC].nType = WH_CALLWNDPROC;
            myhookdata[IDM_CALLWNDPROC].hkprc = CallWndProc;
            myhookdata[IDM_CBT].nType = WH_CBT;
            myhookdata[IDM_CBT].hkprc = CBTProc;
            myhookdata[IDM_DEBUG].nType = WH_DEBUG;
            myhookdata[IDM_DEBUG].hkprc = DebugProc;
            myhookdata[IDM_GETMESSAGE].nType = WH_GETMESSAGE;
            myhookdata[IDM_GETMESSAGE].hkprc = GetMsgProc;
            myhookdata[IDM_KEYBOARD].nType = WH_KEYBOARD;
            myhookdata[IDM_KEYBOARD].hkprc = KeyboardProc;
            myhookdata[IDM_MOUSE].nType = WH_MOUSE;
            myhookdata[IDM_MOUSE].hkprc = MouseProc;
            myhookdata[IDM_MSGFILTER].nType = WH_MSGFILTER;
            myhookdata[IDM_MSGFILTER].hkprc = MessageProc;

            // Инициализируем все флажки в массиве в ЛОЖЬ(FALSE)

            memset(afHooks, FALSE, sizeof(afHooks));

            return 0;

        case WM_COMMAND:
            switch (LOWORD(wParam))
            {
                 // Пользователь выбрал команду hook-точки из меню.

                case IDM_CALLWNDPROC:
                case IDM_CBT:
                case IDM_DEBUG:
                case IDM_GETMESSAGE:
                case IDM_KEYBOARD:
                case IDM_MOUSE:
                case IDM_MSGFILTER:

                    // Используем идентификатор элемента меню как индекс
                    // внутри массива структур с данными hook-точек.

                    index = LOWORD(wParam);

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

                    if (!afHooks[index])
                    {
                        myhookdata[index].hhook = SetWindowsHookEx(
                            myhookdata[index].nType,
                            myhookdata[index].hkprc,
                            (HINSTANCE) NULL, GetCurrentThreadId());
                        CheckMenuItem(hmenu, index,
                            MF_BYCOMMAND | MF_CHECKED);
                        afHooks[index] = TRUE;
                    }

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

                    else
                    {
                        UnhookWindowsHookEx(myhookdata[index].hhook);
                        CheckMenuItem(hmenu, index,
                            MF_BYCOMMAND | MF_UNCHECKED);
                        afHooks[index] = FALSE;
                    }

                default:
                    return (DefWindowProc(hwndMain, uMsg, wParam,
                        lParam));
            }
            break;

            //
            // Обработка других сообщений.
            //

        default:
            return DefWindowProc(hwndMain, uMsg, wParam, lParam);
    }
    return NULL;
}

/****************************************************************
 Подключаемая процедура WH_CALLWNDPROC

 ****************************************************************/

LRESULT WINAPI CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    CHAR szCWPBuf[256];
    CHAR szMsg[16];
    HDC hdc;
    static int c = 0;
    int cch;

    if (nCode < 0)								  // не делать обработку сообщения
        return CallNextHookEx(myhookdata[CALLWNDPROC].hhook,
          nCode, wParam, lParam);

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

    LookUpTheMessage((PMSG) lParam, szMsg);

    hdc = GetDC(hwndMain);

    switch (nCode)
    {
        case HC_ACTION:
            cch = wsprintf(szCWPBuf,
               "CALLWNDPROC - tsk: %ld, msg: %s, %d times   ",
                wParam, szMsg, c++);
            TextOut(hdc, 2, 15, szCWPBuf, cch);
            break;

        default:
            break;
    }

    ReleaseDC(hwndMain, hdc);

    return CallNextHookEx(myhookdata[CALLWNDPROC].hhook,
         nCode, wParam, lParam);
}

/****************************************************************
 Подключаемая процедура WH_GETMESSAGE

 ****************************************************************/

LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    CHAR szMSGBuf[256];
    CHAR szRem[16];
    CHAR szMsg[16];
    HDC hdc;
    static int c = 0;
    int cch;

    if (nCode < 0) // сообщение не обрабатывать

        return CallNextHookEx(myhookdata[GETMESSAGE].hhook,
        nCode, wParam, lParam);

    switch (nCode)
    {
        case HC_ACTION:
            switch (wParam)
            {
                case PM_REMOVE:
                    lstrcpy(szRem, "PM_REMOVE");
                    break;

                case PM_NOREMOVE:
                    lstrcpy(szRem, "PM_NOREMOVE");
                    break;

                default:
                    lstrcpy(szRem, "Unknown");
                    break;
            }

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

            LookUpTheMessage((PMSG) lParam, szMsg);

            hdc = GetDC(hwndMain);
            cch = wsprintf(szMSGBuf,
                "GETMESSAGE - wParam: %s, msg: %s, %d times   ",
                szRem, szMsg, c++);
            TextOut(hdc, 2, 35, szMSGBuf, cch);
            break;

        default:
            break;
    }

    ReleaseDC(hwndMain, hdc);
    return CallNextHookEx(myhookdata[GETMESSAGE].hhook,
         nCode, wParam, lParam);
}

/****************************************************************
 Подключаемая процедура WH_DEBUG

 ****************************************************************/

LRESULT CALLBACK DebugProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    CHAR szBuf[128];
    HDC hdc;

    static int c = 0;
    int cch;

    if (nCode < 0)  // не обрабатывайте сообщение
        return CallNextHookEx(myhookdata[DEBUG].hhook, nCode,
                                               wParam, lParam);

    hdc = GetDC(hwndMain);

    switch (nCode)
    {
        case HC_ACTION:
            cch = wsprintf(szBuf,
                "DEBUG - nCode: %d, tsk: %ld, %d times   ",
                nCode,wParam, c++);
            TextOut(hdc, 2, 55, szBuf, cch);
            break;

        default:
            break;
    }

    ReleaseDC(hwndMain, hdc);
    return CallNextHookEx(myhookdata[DEBUG].hhook, nCode,
         wParam, lParam);

}

/****************************************************************
 Подключаемая процедура WH_CBT

 ****************************************************************/

LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    CHAR szBuf[128];
    CHAR szCode[128];
    HDC hdc;

    static int c = 0;
    int cch;

    if (nCode < 0)  // не обрабатывать сообщение
        return CallNextHookEx(myhookdata[CBT].hhook, nCode, wParam, lParam);

    hdc = GetDC(hwndMain);

    switch (nCode)
    {
        case HCBT_ACTIVATE:
            lstrcpy(szCode, "HCBT_ACTIVATE");
            break;

        case HCBT_CLICKSKIPPED:
            lstrcpy(szCode, "HCBT_CLICKSKIPPED");
            break;

        case HCBT_CREATEWND:
            lstrcpy(szCode, "HCBT_CREATEWND");
            break;

        case HCBT_DESTROYWND:
            lstrcpy(szCode, "HCBT_DESTROYWND");
            break;

        case HCBT_KEYSKIPPED:
            lstrcpy(szCode, "HCBT_KEYSKIPPED");
            break;

        case HCBT_MINMAX:
            lstrcpy(szCode, "HCBT_MINMAX");
            break;

        case HCBT_MOVESIZE:
            lstrcpy(szCode, "HCBT_MOVESIZE");
            break;

        case HCBT_QS:
            lstrcpy(szCode, "HCBT_QS");
            break;

        case HCBT_SETFOCUS:
            lstrcpy(szCode, "HCBT_SETFOCUS");
            break;

        case HCBT_SYSCOMMAND:
            lstrcpy(szCode, "HCBT_SYSCOMMAND");
            break;

        default:
            lstrcpy(szCode, "Unknown");
            break;
    }

    cch = wsprintf(szBuf, "CBT - nCode: %s, tsk: %ld, %d
times   ", szCode, wParam, c++);

    TextOut(hdc, 2, 75, szBuf, cch);
    ReleaseDC(hwndMain, hdc);
    return CallNextHookEx(myhookdata[CBT].hhook, nCode,
 wParam, lParam);

}

/****************************************************************
 Подключаемая процедура WH_MOUSE

 ****************************************************************/

LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    CHAR szBuf[128];
    CHAR szMsg[16];
    HDC hdc;
    static int c = 0;
    int cch;

    if (nCode < 0)  // не обрабатывать сообщение
        return CallNextHookEx(myhookdata[MOUSE].hhook, nCode,
                                              wParam, lParam);

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

    LookUpTheMessage((PMSG) lParam, szMsg);

    hdc = GetDC(hwndMain);
    cch = wsprintf(szBuf,
      "MOUSE - nCode: %d, msg: %s, x: %d, y: %d, %d times   ", nCode, szMsg, LOWORD(lParam), HIWORD(lParam), c++);

    TextOut(hdc, 2, 95, szBuf, cch);
    ReleaseDC(hwndMain, hdc);
    return CallNextHookEx(myhookdata[MOUSE].hhook, nCode,
         wParam, lParam);

}

/****************************************************************
 Подключаемая процедура WH_KEYBOARD

 ****************************************************************/

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    CHAR szBuf[128];
    HDC hdc;
    static int c = 0;
    int cch;

    if (nCode < 0)  // сообщение не обрабатывать
        return CallNextHookEx(myhookdata[KEYBOARD].hhook,
               nCode, wParam, lParam);

    hdc = GetDC(hwndMain);
    cch = wsprintf(szBuf, "KEYBOARD - nCode: %d, vk: %d, %d times ", nCode, wParam, c++);

    TextOut(hdc, 2, 115, szBuf, cch);
    ReleaseDC(hwndMain, hdc);
    return CallNextHookEx(myhookdata[KEYBOARD].hhook, nCode, wParam, lParam);

}

/****************************************************************
 Подключаемая процедура WH_MSGFILTER

 ****************************************************************/

LRESULT CALLBACK MessageProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    CHAR szBuf[128];
    CHAR szMsg[16];
    CHAR szCode[32];
    HDC hdc;
    static int c = 0;
    int cch;

    if (nCode < 0)  // сообщение не обрабатывать
        return CallNextHookEx(myhookdata[MSGFILTER].hhook, nCode,
                wParam, lParam);

    switch (nCode)
    {
        case MSGF_DIALOGBOX:
            lstrcpy(szCode, "MSGF_DIALOGBOX");
            break;

        case MSGF_MENU:
            lstrcpy(szCode, "MSGF_MENU");
            break;

        case MSGF_SCROLLBAR:
            lstrcpy(szCode, "MSGF_SCROLLBAR");
            break;

        case MSGF_NEXTWINDOW:
            lstrcpy(szCode, "MSGF_NEXTWINDOW");
            break;

        default:
            wsprintf(szCode, "Unknown: %d", nCode);
            break;
    }

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

    LookUpTheMessage((PMSG) lParam, szMsg);

    hdc = GetDC(hwndMain);
    cch = wsprintf(szBuf,
        "MSGFILTER  nCode: %s, msg: %s, %d times	",
        szCode, szMsg, c++);
    TextOut(hdc, 2, 135, szBuf, cch);
    ReleaseDC(hwndMain, hdc);
    return CallNextHookEx(myhookdata[MSGFILTER].hhook,
    nCode, wParam, lParam);
}


7.5 - Справочник по hook-точкам

Ниже перечисленные функции, структуры и сообщения связаны с hook-точками.


7.5.1 - Функции hook-точек

Следующие функции используются с hook-точками.
CallMsgFilter
CallNextHookEx
CallWndProc
CallWndRetProc
CBTProc
DebugProc
ForegroundIdleProc
GetMsgProc
JournalPlaybackProc
JournalRecordProc
KeyboardProc
MessageProc
MouseProc
SetWindowsHookEx
ShellProc
SysMsgProc
UnhookWindowsHookEx

Устаревшие функции
DefHookProc
SetWindowsHook
UnhookWindowsHook


7.5.1.1 - Функция CallMsgFilter

(ФильтрВызываемыхСообщений)

Функция CallMsgFilter передает заданное сообщение и код hook-точки в подключаемые процедуры, связанные с hook-точками WH_MSGFILTER и WH_SYSMSGFILTER. Подключаемая процедура WH_SYSMSGFILTER или WH_MSGFILTER является определяемой программой функцией повторного вызова, которая исследует и, необязательно, модифицирует сообщения для диалогового окна, окна сообщений, меню или линейки прокрутки.

Синтаксис

BOOL CallMsgFilter
(
    LPMSG lpMsg,		// указатель на структуру с данными сообщения
    int nCode 		// код hook-точки
);

Параметры
lpMsg
Указатель на структуру MSG, содержащую сообщение, которое будет передано в подключаемые процедуры.
nCode
Устанавливает определяемый программой код, использованный подключаемой процедурой, чтобы определить, как обрабатывать сообщение. Код не должен иметь того же самого значения, что и определяемые системой коды hook-точек (MSGF_ и HC _) связанных с hook-точками WH_MSGFILTER и WH_SYSMSGFILTER.

Возвращаемые значения
Если прикладная программа затем должно обработать сообщение, возвращаемое значение нулевое.
Если прикладная программа затем не обрабатывает сообщение, возвращаемое значение отлично от нуля.

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

Смотри также
MessageProc, MSG, SetWindowsHookEx, SysMsgProc

Размещение и совместимость CallMsgFilter

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


7.5.1.2 - Функция CallNextHookEx

(ВызовСледующейHookточкиРасширенный)

Функция CallNextHookEx передает информацию hook-точки в следующую подключаемую процедуру в текущей цепочке hook-точек. Эта функция заменяет функцию DefHookProc.

Синтаксис

LRESULT CallNextHookEx
(
    HHOOK hhk,		// дескриптор текущей hook-точки
    int nCode,		// код hook-точки, передаваемый в подключаемую процедуру
    WPARAM wParam,		// значение, передаваемое в подключаемую процедуру
    LPARAM lParam 		// значение, передаваемое в подключаемую процедуру
);

Параметры
hhk
Идентифицирует текущую hook-точку. Прикладная программа принимает этот дескриптор в результате предыдущего вызова функции SetWindowsHookEx.
nCode
Определяет код hook-точки, переданный в текущую подключаемую процедуру. Следующая фильтр - процедура использует этот код, чтобы определить, как обрабатывать информацию hook-точки.
wParam
Определяет значение wParam, переданное в текущую подключаемую процедуру. Значение этого параметра зависит от типа hook-точки, связанной с текущей цепочкой hook-точек.
lParam
Определяет значение lParam, переданное в текущую подключаемую процедуру. Значение этого параметра зависит от типа hook-точки, связанной с текущей цепочкой hook-точек.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - величина, возвращенная следующей подключаемой процедурой в цепочке. Текущая фильтр - процедура должна также возвратить это значение. Значение возвращаемой величины зависит от типа hook-точки. Для получения дополнительной информации смотри описания индивидуальных подключаемых процедур.

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

Смотри также
SetWindowsHook, SetWindowsHookEx, UnhookWindowsHook, UnhookWindowsHookEx

Размещение и совместимость CallNextHookEx

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


7.5.1.3 - Функция CallWndProc

(ВызовОконнойПроцедуры)

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

CallWndProc - метка - заместитель для определяемого программой или определенного библиотекой имени функции.

Синтаксис

LRESULT CALLBACK CallWndProc
(
    int nCode,		// код hook-точки
    WPARAM wParam,		// флажок текущей обработки
    LPARAM lParam 		// адрес структуры с данными сообщения
);

Параметры
nCode
Определяет должна ли подключаемая процедура обрабатывать сообщение. Если nCode - HC_ACTION, фильтр - процедура должна обработать сообщение. Если nCode - меньше чем нуль, подключаемая процедура должна передать сообщение в функцию CallNextHookEx без дальнейшей обработки и должна возвратить значение, возвращенное CallNextHookEx.
wParam
Определяет, не отправлено ли сообщение текущим процессом. Если сообщение посылается текущим процессом, оно отлично от нуля; иначе, оно значение ПУСТО (NULL).
lParam
Указатель на структуру CWPSTRUCT, которая содержит подробности о сообщении.

Возвращаемые значения
Величина возвращаемого значения должна быть нуль.

Замечания
Подключаемая процедура CallWndProc может исследовать сообщение, но она не может изменить его. После того как фильтр - процедура возвратит управление системе, сообщение передается в оконную процедуру.
Прикладная программа устанавливает подключаемую процедуру, определяя тип hook-точки WH_CALLWNDPROC и адрес фильтр - процедуры при вызове функции SetWindowsHookEx.
Hook-точка WM_CALLWNDPROC вызывается в контексте потока, который вызывает SendMessage, а не потока, который принимает сообщение.

Смотри также
CallNextHookEx, CWPSTRUCT, SendMessage, SetWindowsHookEx

Размещение и совместимость CallWndProc

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			Определенная пользователем
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			HOOKPROC


7.5.1.4 - Функция CallWndRetProc

(ПовторныйВызовОконнойПроцедуры)

[Теперь поддерживается Windows NT]

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

Синтаксис

LRESULT CALLBACK CallWndRetProc
(
    int nCode,	// код hook-точки
    WPARAM wParam,	// флажок текущей обработки
    LPARAM lParam	// адрес структуры с данными сообщения
);

Параметры
nCode
Определяет должна ли подключаемая процедура обрабатывать сообщение. Если nCode - HC_ACTION, фильтр - процедура должна обработать сообщение. Если nCode - меньше чем нуль, подключаемая процедура должна передать сообщение в функцию CallNextHookEx без дальнейшей обработки и должна возвратить значение, возвращенное CallNextHookEx.
wParam
Определяет, не отправлено ли сообщение текущим процессом. Если сообщение отправляется текущим процессом, оно отлично от нуля; иначе, оно значение ПУСТО (NULL).
lParam
Указатель на структуру CWPRETSTRUCT, которая содержит подробности о сообщении.

Возвращаемые значения
Величина возвращаемого значения должна быть нуль.

Замечания
Прикладная программа устанавливает подключаемую процедуру, определяя тип hook-точки WH_CALLWNDPROCRET и адрес фильтр - процедуры при вызове функции SetWindowsHookEx. CallWndRetProc - метка - заместитель для определяемого программой или определенного библиотекой имени функции.

Смотри также
CallNextHookEx, CallWndProc, CWPRETSTRUCT, SendMessage, SetWindowsHookEx.

Размещение и совместимость CallWndRetProc

Windows NT				Да
Win95					Да
Win32s					Нет
Импортируемая библиотека			Определенная пользователем
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			HOOKPROC


7.5.1.5 - Функция CBTProc

(ПроцедураМашиннойПодготовки)

Подключаемая процедура CBTProc - это определяемая программой или определенная библиотекой функция повторного вызова, которую вызывает система перед активизацией, созданием, разрушением, уменьшением, увеличением, перемещением, или установлением размеров окна; перед завершением системной команды; перед удалением события мыши или клавиатуры из системной очереди сообщений; перед установкой фокуса клавиатуры; или перед синхронизацией системной очереди сообщений. Значение, возвращаемое подключаемой процедурой, определяет, разрешит или запретит операционная система Windows одно из этих действий. Прикладная программа машинной подготовки (computer-based training) (CBT) использует эту фильтр - процедуру, чтобы принять полезные уведомления от системы.

Синтаксис

LRESULT CALLBACK CBTProc
(
    int nCode,		// код hook-точки
    WPARAM wParam,	// зависит от кода hook-точки
    LPARAM lParam	// зависит от кода hook-точки
);

Параметры
nCode
Определяет код, который подключаемая процедура использует, чтобы установить, как обрабатывать сообщение. Этот параметр может быть одним из следующих значений:

  • HCBT_ACTIVATE - Система собирается активизировать окно
  • HCBT_CLICKSKIPPED - Система удаляет сообщение мыши из системной очереди сообщений. После приема этого кода hook-точки, CBT приложение должно установить подключаемую процедуру WH_JOURNALPLAYBACK в ответ на сообщение мыши.
  • HCBT_CREATEWND - Окно готовится быть созданным. Система вызывает подключаемую процедуру перед отправкой сообщения WM_CREATE или WM_NCCREATE окну. Если фильтр - процедура возвращает значение, отличающееся от нуля, система разрушает окно; функция CreateWindow возвращает значение NULL (ПУСТО), но сообщение WM_DESTROY не отправляется окну. Если подключаемая процедура возвращает значение ноль, окно создается как обычно.Окно было создано во время уведомления HCBT_CREATEWND, но его конечный размер и позицию не возможно было определить, а его родительское окно не возможно было установить. Система имеет возможность оправить сообщения недавно созданному окну, несмотря на то, что оно еще не приняло сообщения WM_CREATE или WM_NCCREATE. Она имеет также возможность изменить и позицию недавно созданного окна в Z-последовательности, изменяя член hwndInsertAfter структуры CBT_CREATEWND.
  • HCBT_DESTROYWND - Окно собирается быть разрушенным.
  • HCBT_KEYSKIPPED - Система удалила сообщение клавиатуры из системной очереди сообщений. После приема этого кода hook-точки, прикладная программа CBT должна установить подключаемую процедуру WH_JOURNALPLAYBACK в ответ на сообщение клавиатуры.
  • HCBT_MINMAX - Окно намеревается быть свернутым или развернутым.
  • HCBT_MOVESIZE - Окно намеревается быть перемещенным или изменить свои размеры.
  • HCBT_QS - Система извлекла сообщение WM_QUEUESYNC из системной очереди сообщений.
  • HCBT_SETFOCUS - Окно собирается принять фокус клавиатуры.
  • HCBT_SYSCOMMAND - Системная команда собирается быть завершенной. Это позволяет прикладной программе CBT предотвратить переключение задач посредством комбинаций "горячих клавиш -"hot key".

Если nCode - меньше чем нуль, подключаемая процедура должна передать сообщение в функцию CallNextHookEx без дальнейшей обработки и должна возвратить значение, возвращенное CallNextHookEx.

wParam
Зависит от параметра nCode. За подробностями обратитесь в. следующий раздел Замечаний.
lParam
Зависит от параметра nCode. За подробностями обратитесь в. следующий раздел Замечаний.

Возвращаемые значения
Для действий, соответствующих ниже перечисленным кодам hook-точек CBT, величина возвращаемого значения должна быть 0, чтобы позволить операцию, или 1, чтобы запретит ее:

HCBT_ACTIVATE
HCBT_CREATEWND
HCBT_DESTROYWND
HCBT_MINMAX
HCBT_MOVESIZE
HCBT_SETFOCUS
HCBT_SYSCOMMAND

Для операций, соответствующих ниже перечисленным кодам hook-точек CBT, величина возвращаемого значения игнорируется:

HCBT_CLICKSKIPPED
HCBT_KEYSKIPPED
HCBT_QS

Замечания
Подключаемая процедура не должна устанавливать фильтр - процедуру WH_JOURNALPLAYBACK кроме как в ситуациях, описанных в предшествующем перечне кодов hook-точек.
Эта подключаемая процедура должна быть в динамически подключаемой библиотеке (DLL). Прикладная программа устанавливает фильтр - процедуру, определяя тип hook-точки WH_CBT и адрес подключаемой процедуры при вызове функции SetWindowsHookEx.
Нижеследующая таблица описывает параметры wParam и lParam для каждого кода hook-точки HCBT_:
Код | wParam | lParam
HCBT_ACTIVATE | Определяет дескриптор окна, собирающегося быть активизированным. | Определяет дальний указатель на структуру CBTACTIVATESTRUCT, содержащую дескриптор активного окна и определяет, не изменяется ли активность из-за щелчка мыши.
HCBT_CLICKSKIPPED | Идентифицирует сообщение мыши, удаленное из системной очереди сообщений. | Определяет дальний указатель на структуру MOUSEHOOKSTRUCT, содержащей код местоположения курсора и дескриптор окна, для которого предназначено сообщение мыши. Значение HCBT_CLICKSKIPPED отправляется подключаемой процедуре CBTProc только тогда, если установлена hook-точка WH_MOUSE. За перечнем кодов местоположения курсора, обратитесь к статье WM_NCHITTEST.
HCBT_CREATEWND | Определяет дескриптор нового окна. | Определяет дальний указатель на структуру CBT_CREATEWND, содержащую параметры инициализации для окна. Параметры включают в себя координаты и размеры окна. Изменяя эти параметры, подключаемая процедура CBTProc может установить начальный размер и позицию окна.
HCBT_DESTROYWND | Определяет дескриптор окна, собирающегося быть разрушенным. | Не определяется и должен быть установлен в нуль.
HCBT_KEYSKIPPED | Идентифицирует код виртуальной клавиши. | Определяет повторный счет, скэн-код, код клавиши перехода, предыдущее состояние клавиши и код контекста. Значение HCBT_KEYSKIPPED отправляется подключаемой процедуре CBTProc только тогда, если установлена hook-точка WH_KEYBOARD. Для получения дополнительной информации, см. сообщение WM_KEYDOWN или WM_KEYUP.
HCBT_MINMAX | Определяет дескриптор свертываемого или развертываемого окна. | Определяет младшее слово значения показа окна (SW _), определенное операцией. Для получения списка значений показа окна, см. ShowWindow. Старшее слово не определяется.
HCBT_MOVESIZE | Определяет дескриптор окна, которое будет перемещено или установлено с другими размерами. | Определяет дальний указатель на структуру RECT, содержащую координаты окна. Изменяя значения в структуре, подключаемая процедура CBTProc может устанавливать конечные координаты окна.
HCBT_QS | Не определяется и должен быть установлен в нуль. | Не определяется и должен быть установлен в нуль.
HCBT_SETFOCUS | Определяет дескриптор окна, получающего фокус клавиатуры. | Определяет дескриптор окна, теряющего фокус клавиатуры.
HCBT_SYSCOMMAND | Определяет значение системной команды (SC_), которое устанавливается командой системы. Для получения дополнительной информации о значениях системных команд, см. WM_SYSCOMMAND. | lСодержит те же самые данные что и значение lParam сообщения WM_SYSCOMMAND: Если команда системного меню выбрана мышью, младшее слово содержит x-координату курсора, в экранных координатах, а старшее слово содержит y-координату; иначе, параметр не используется.

CBTProc - метка - заместитель для определяемого программой или определенного библиотекой имени функции.

Смотри также
CallNextHookEx, CreateWindow, SetWindowsHookEx, WM_SYSCOMMAND

Размещение и совместимость CBTProc

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			Определенная пользователем
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			HOOKPROC


7.5.1.6 - Функция DebugProc

(ПроцедураОтладки)

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

Синтаксис

LRESULT CALLBACK DebugProc
(
    int nCode,	// код hook-точки
    WPARAM wParam,	// тип hook-точки,собирающейся быть вызванной
    LPARAM lParam	// адрес структуры с информацией об отладке
);

Параметры
nCode
Определяет, должна ли подключаемая процедура обрабатывать сообщение. Если nCode - HC_ACTION, фильтр - процедура должна обработать сообщение. Если nCode - меньше чем нуль, подключаемая процедура должна передать сообщение в функцию CallNextHookEx без дальнейшей обработки и должна возвратить значение, возвращенное CallNextHookEx.
wParam
Определяет тип hook-точки, собирающейся быть вызванной. Этот параметр может быть одним из следующих значений:

  • WH_CALLWNDPROC - Устанавливает подключаемую процедуру, которая отслеживает сообщения, отправленные оконной процедуре. Для получения дополнительной информации, см. описание фильтр - процедуры CallWndProc.
  • WH_CALLWNDPROCRET - Устанавливает подключаемую процедуру, которая отслеживает сообщения, которые только что были обработаны оконной процедурой. Для получения дополнительной информации, см. описание фильтр - процедуры CallWndRetProc.
  • WH_CBT - Устанавливает подключаемую процедуру, которая принимает уведомления, полезные для машинной подготовки (CBT) прикладной программы. Для получения дополнительной информации, см. описание подключаемой процедуры CBTProc.
  • WH_DEBUG - Устанавливает фильтр - процедуру, полезную для отладки других подключаемых процедур. Для получения дополнительной информации, см. описание подключаемой процедуры DebugProc.
  • WH_GETMESSAGE - Устанавливает подключаемую процедуру, которая отслеживает сообщения, задержанные в очереди сообщений. Для получения дополнительной информации, см. описание фильтр - процедуры GetMsgProc.
  • WH_JOURNALPLAYBACK - Устанавливает подключаемую процедуру, которая регистрирует сообщения, предварительно записанные фильтр - процедурой WH_JOURNALRECORD. Для получения дополнительной информации, см. описание подключаемой процедуры JournalPlaybackProc.
  • WH_JOURNALRECORD - Устанавливает подключаемую процедуру, которая заносит в список входящие сообщения, зарегистрированные в системной очереди сообщений. Эта hook-точка полезна для записи макрокоманд. Для получения дополнительной информации, см. описание подключаемой процедуры JournalRecordProc.
  • WH_KEYBOARD - Устанавливает подключаемую процедуру, которая отслеживает сообщения о нажатиях клавиш. Для получения дополнительной информации, см. описание фильтр - процедуры KeyboardProc.
  • WH_MOUSE - Устанавливает подключаемую процедуру, которая отслеживает сообщения мыши. Для получения дополнительной информации, см. описание фильтр - процедуры MouseProc.
  • WH_MSGFILTER - Устанавливает подключаемую процедуру, которая отслеживает сообщения, сгенерированные в результате события ввода данных в диалоговом окне, окне сообщений, меню или в линейке прокрутки. Фильтр - процедура отслеживает эти сообщения только для прикладной программы, которая установила подключаемую процедуру. Для получения дополнительной информации, см. описание фильтр - процедуры MessageProc.
  • WH_SHELL - Устанавливает подключаемую процедуру, которая принимает уведомление полезное для оболочки прикладной программы. Для получения дополнительной информации, см. описание фильтр - процедуры ShellProc.
  • WH_SYSMSGFILTER - Устанавливает подключаемую процедуру, которая отслеживает сообщения, сгенерированные в результате события ввода данных в блоке диалога, окне сообщений, меню, или линейке прокрутки. Подключаемая процедура контролирует эти сообщения для всех прикладных программ в системе. Для получения дополнительной информации, см. описание подключаемой процедуры SysMsgProc.

lParam
Указывает на структуру DEBUGHOOKINFO, которая содержит параметры для передачи в подключаемую процедуру назначения.

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

Замечания
Прикладная программа устанавливает эту подключаемую процедуру, при помощи определения типа hook-точки как WH_DEBUG и указателя на фильтр - процедуру при вызове функции SetWindowsHookEx.
CallWndProc и CallWndRetProc - метки - заместители для определяемых программой или определенных библиотекой имен функции.

Смотри также
CallNextHookEx, CallWndProc, CallWndRetProc, CBTProc, DEBUGHOOKINFO, GetMsgProc, JournalPlaybackProc, JournalRecordProc, KeyboardProc, MessageProc, MouseProc, SetWindowsHookEx, ShellProc, SysMsgProc

Размещение и совместимость DebugProc

Windows NT				Да
Win95					Нет
Win32s					Нет
Импортируемая библиотека			Определенная пользователем
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			HOOKPROC


7.5.1.7 - Функция ForegroundIdleProc

(ПроцедураПереднийПланВОжидание)

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

Синтаксис

DWORD ForegroundIdleProc
(
    int code,		// код hook-точки
    DWORD wParam,	// не используется
    LONG lParam	// не используется
);

Параметры
code
Определяет, должна ли подключаемая процедура обрабатывать сообщение. Если code является HC_ACTION, фильтр - процедура должна обработать сообщение. Если code - меньше чем нуль, подключаемая процедура должна передать сообщение в функцию CallNextHookEx без дальнейшей обработки и должна возвратить значение, возвращенное CallNextHookEx.
wParam
Не используется
lParam
Не используется

Замечания
Прикладная программа устанавливает эту подключаемую процедуру, при помощи определения типа hook-точки как WH_FOREGROUNDIDLE и указателя на подключаемую процедуру при вызове функции SetWindowsHookEx.
ForegroundIdleProc - метка - заместитель для определяемого программой имени функции.
Это - hook-точка устанавливается потоком.

Смотри также
CallNextHookEx, SetWindowsHookEx

Размещение и совместимость ForegroundIdleProc

Windows NT			Да
Win95				Нет
Win32s				Нет
Импортируемая библиотека		Определенная пользователем
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		HOOKPROC


7.5.1.8 - Функция GetMsgProc

(ПроцедураПолученияСообщения)

Подключаемая процедура GetMsgProc - определяемая программой или определенная библиотекой функция повторного вызова, которую система вызывает всякий раз, когда функция GetMessage извлекает сообщение из очереди сообщений прикладной программы. Перед передачей извлеченного сообщения в оконную процедуру назначения, система передает сообщение в подключаемую процедуру.

Синтаксис

LRESULT CALLBACK GetMsgProc
(
    int code,		// код hook-точки
    WPARAM wParam,	// флажок удаления
    LPARAM lParam	// адрес структуры с сообщением
);

Параметры
code
Определяет, должна ли подключаемая процедура обрабатывать сообщение. Если code - HC_ACTION, фильтр - процедура должна обработать сообщение. Если code - меньше чем нуль, фильтр - процедура должна передать сообщение в функцию CallNextHookEx без дальнейшей обработки и должна возвратить значение, возвращенное CallNextHookEx.
wParam
Определяет, было ли сообщение удалено из очереди. Этот параметр может быть одним из следующих значений:

  • PM_NOREMOVE - Определяет, что сообщение не было удалено из очереди. (Прикладная программа вызвала функцию PeekMessage, установив флажок PM_NOREMOVE.)
  • PM_REMOVE - Определяет, что сообщение было удалено из очереди. (Прикладная программа вызвала GetMessage, или она вызвала функцию PeekMessage, установив флажок PM_REMOVE.)

lParam
Указывает на структуру MSG, которая содержит подробности о сообщении.

Возвращаемые значения
Возвращаемое значение должно быть ноль.

Замечания
Подключаемая процедура GetMsgProc может исследовать или изменить сообщение. После того, как фильтр - процедура возвратит управление системе, функция GetMessage возвращает значение сообщения, вместе с любыми изменениями, в прикладную программу, которая первоначально вызвала её.
Прикладная программа устанавливает эту подключаемую процедуру, определяя тип hook-точки как WH_GETMESSAGE и адрес подключаемой процедуры при вызове функции SetWindowsHookEx.
GetMsgProc - метка - заместитель для определяемого программой или определенного библиотекой имени функции.

Смотри также
CallNextHookEx, GetMessage, MSG, PeekMessage, SetWindowsHookEx

Размещение и совместимость GetMsgProc

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		Определяется пользователем
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		HOOKPROC


7.5.1.9 - Функция JournalPlaybackProc

(ПроцедураВоспроизведенияПротокола)

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

Синтаксис

LRESULT CALLBACK JournalPlaybackProc
(
    int code,		// код hook-точки
    WPARAM wParam,	// не определяется
    LPARAM lParam	// адрес обрабатываемого сообщения
);

Параметры
code
Определяет код, который подключаемая процедура использует, чтобы определить, как обрабатывать сообщение. Этот параметр может быть одно из следующих значений:

  • HC_GETNEXT - Подключаемая процедура должна копировать текущее сообщение от мыши или клавиатуры в структуре EVENTMSG, указанной параметром lParam.
  • HC_NOREMOVE - Прикладная программа вызвала функцию PeekMessage с wRemoveMsg установленным в PM_NOREMOVE, указывая этим, что сообщение не удалено из очереди сообщений после обработки PeekMessage.
  • HC_SKIP - Подключаемая процедура должна приготовиться копировать следующее сообщение от мыши или клавиатуры в структуре EVENTMSG, указанной lParam. После приема кода HC_GETNEXT, фильтр - процедура должна скопировать сообщение в структуру.
  • HC_SYSMODALOFF - Системно - модальное диалоговое окно было разрушено. Подключаемая процедура должна продолжить воспроизводить сообщения.
  • HC_SYSMODALON - Системно - модальное диалоговое окно отображается на экране. Пока блок диалога не разрушен, подключаемая процедура должна прекратить воспроизводить сообщения.

Если code - меньше чем нуль, подключаемая процедура должна передать сообщение в функцию CallNextHookEx без дальнейшей обработки и должна возвратить значение, возвращенное CallNextHookEx.
wParam
Устанавливается в значение ПУСТО (NULL).
lParam
Указывает на структуру EVENTMSG, которая предоставляет сообщение, обрабатываемое подключаемой процедурой. Этот параметр допустим, только тогда, когда параметра code равен HC_GETNEXT.

Возвращаемые значения
Чтобы заставить систему ждать перед обработкой сообщения, величина возвращаемого значения должна быть количеством времени, в тактах системных часов, количество которых система должна ждать. (Это значение может быть подсчитано, путем вычисления разности между членами time текущего и предыдущего входящих сообщений.) Чтобы обработать сообщение немедленно, величина возвращаемого значения должна быть нулевая. Величина возвращаемого значения используется, только тогда, если код hook-точки - HC_GETNEXT; иначе, она игнорируется.

Замечания
Подключаемая процедура JournalPlaybackProc должна копировать входящее сообщение в параметр lParam. Сообщение, должно быть предварительно записано при помощи использования фильтр - процедуры JournalRecordProc, которая не должна изменять сообщение.
Чтобы извлекать то же самое сообщение снова и снова, подключаемая процедура может быть вызвана несколько раз с параметром code установленным в HC_GETNEXT без промежуточного вызова code установленным в HC_SKIP.
Если code - HC_GETNEXT и величина возвращаемого значения больше чем нуль, система бездействует количество миллисекунд, заданных величиной возвращаемого значения. Когда система продолжит свою работу, она снова вызывает подключаемую процедуру с установкой code в HC_GETNEXT, чтобы извлечь то же самое сообщение. Величина возвращаемого значения этого нового вызова JournalPlaybackProc должна быть нулевая; иначе, система возвратится в состояние бездействия на число миллисекунд, заданных величиной возвращаемого значения, вызовет JournalPlaybackProc снова, и так далее по кругу. Система, будет находиться в состоянии зависания.
В отличие от большинства других глобальных подключаемых процедур, фильтр - процедуры JournalRecordProc и JournalPlaybackProc всегда вызываются в контексте потока, который устанавливает hook-точку.
После возвращения фильтр - процедурой управления системе, сообщение продолжает обрабатываться. Если code - HC_SKIP, подключаемая процедура должна приготовиться возвратить следующее зарегистрированное сообщение о событии при своем следующем вызове.
Прикладная программа устанавливает подключаемую процедуру JournalPlaybackProc, путем определения типа hook-точки как WH_JOURNALPLAYBACK и адреса подключаемой процедуры при вызове функции SetWindowsHookEx.
Подключаемая процедура Win32 JournalRecordProc не должна находиться в динамически компонуемой библиотеке.
Подключаемая процедура Win32 JournalRecordProc может находиться непосредственно в прикладной программе.
Если пользователь нажимает CTRL+ESC или CTRL+ALT+DEL в ходе воспроизведения протокола, система останавливает считывание, отцепляет процедуру считывания протокола и отсылает сообщение WM_CANCELJOURNAL в ведущую протокол прикладную программу.
Если подключаемая процедура возвращает сообщение в диапазоне от WM_KEYFIRST до WM_KEYLAST, применяются следующие условия:

  • Член paramL структуры EVENTMSG определяет код виртуальной клавиши, которая была нажата.
  • Член paramH структуры EVENTMSG определяет скэн-код.
  • Не имеется никакого способа, чтобы определить повторный счет. Событие всегда принимается, чтобы предоставить одно событие связанное с клавишей.

JournalPlaybackProc - метка - заместитель для определяемого программой или определенного библиотекой имени функции.

Смотри также
CallNextHookEx, EVENTMSG, JournalRecordProc, PeekMessage, SetWindowsHookEx, WM_CANCELJOURNAL

Размещение и совместимость JournalPlaybackProc

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		Определяется пользователем
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		HOOKPROC


7.5.1.10 - Функция JournalRecordProc

(ПроцедураЗаписиПротокола)

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

Синтаксис

LRESULT CALLBACK JournalRecordProc
(
    int code,		// код hook-точки
    WPARAM wParam,	// не определяется
    LPARAM lParam	// адрес обрабатываемого сообщения
);

Параметры
code
Определяет, как обрабатывать сообщение. Этот параметр может быть одним из следующих значений:

  • HC_ACTION - Параметр lParam указывает на структуру EVENTMSG, которая содержит информацию о сообщении, удаленном из системной очереди. Подключаемая процедура должна записать содержимое структуры, путем копирования его в буфер или файл.
  • HC_SYSMODALOFF - Системно- модальное диалоговое окно было разрушено. Подключаемая процедура должна возобновить запись.
  • HC_SYSMODALON - Системно- модальное диалоговое окно было разрушено. До тех пор пока диалоговое окно является разрушенным, подключаемая процедура должна прекратить запись.

Если code является меньшим чем нуль, подключаемая процедура должна передать сообщение в функцию CallNextHookEx без дальнейшей его обработки и должна возвратить значение, возвращенное CallNextHookEx. wParam
Определяет значение ПУСТО (NULL).
lParam
Указывает на структуру EVENTMSG, которая содержит сообщение, которое будет записано.

Возвращаемые значения
Возвращаемое значение игнорируется.

Замечания
Подключаемая процедура JournalRecordProc должна копировать, но не изменять сообщения. После того, как фильтр - процедура возвратит управление системе, обработка сообщения продолжится.
Прикладная программа устанавливает подключаемую процедуру JournalRecordProc при помощи определения типа hook-точки как WH_JOURNALRECORD и ее адреса при вызове функции SetWindowsHookEx.
Фильтр - процедура Win32 JournalRecordProc не должна находиться в динамически подключаемой библиотеке. Подключаемая процедура Win32 JournalRecordProc может находиться непосредственно в прикладной программе.
В отличие от большинства других глобальных подключаемых процедур, фильтр - процедуры JournalRecordProc и JournalPlaybackProc всегда вызываются в контексте потока, который установил hook-точку.
Прикладная программа, которая установила подключаемую процедуру JournalRecordProc, должна отслеживать виртуальный клавишный код VK_CANCEL (который реализуется у большинства клавиатур комбинацией клавиш CTRL+BREAK). Этот виртуальный клавишный код должен интерпретироваться прикладной программой как сигнал, что пользователь желает остановить запись протокола. Прикладная программа должна ответить окончанием записываемой последовательности и удалением подключаемой процедуры JournalRecordProc. Удаление важно. Оно предохраняет ведущую протокол прикладную программу от застопоривания системы, которое приводит к зависанию внутри фильтр - процедуры.
Эта роль в качестве сигнала для остановки записи протокола, означает, что комбинация клавиш CTRL+BREAK не может самостоятельно быть записана. Поскольку комбинация клавиш CTRL+C не имеет подобной роли как сигнал к ведению протокола, она может быть записана. Имеются две других комбинации клавиш, которые не могут быть записаны: CTRL+ESC и CTRL+ALT+DEL. Эти две комбинации клавиш заставляют систему остановить все ведущие протокол действия (запись или считывание), удалить все ведущие протокол hook-точки и известить о сообщении WM_CANCELJOURNAL ведущую протокол прикладную программу.
JournalRecordProc является меткой-заместителем для определяемого программой или определяемого библиотекой имени функции.

Смотри также
CallNextHookEx, EVENTMSG, JournalPlaybackProc, SetWindowsHookEx, WM_CANCELJOURNAL

Размещение и совместимость JournalRecordProc

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			Определяется пользователем
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			HOOKPROC


7.5.1.11 - Функция KeyboardProc

(ПроцедураКлавиатуры)

Подключаемая процедура KeyboardProc является определяемой программой или библиотекой функцией повторного вызова, которую система вызывает всякий раз, когда прикладная программа вызывает функцию GetMessage или PeekMessage и имеется сообщение клавиатуры (WM_KEYUP или WM_KEYDOWN), которое надо обработать.

Синтаксис

LRESULT CALLBACK KeyboardProc
(
    int code,		// код hook-точки
    WPARAM wParam,	// код виртуальной клавиши
    LPARAM lParam	// информация о сообщении нажатой клавиши
);

Параметры
code
Определяет код, который подключаемая процедура использует, чтобы определить, как обработать сообщение. Этот параметр может быть одним из следующих значений:

  • HC_ACTION - Параметры wParam и lParam содержат информацию о сообщении нажатой клавиши.
  • HC_NOREMOVE - Параметры wParam и lParam содержат информацию о сообщении нажатой клавиши, но сообщение нажатой клавиши не удаляется из очереди сообщений. (Прикладная программа вызвала функцию PeekMessage, установив флажок PM_NOREMOVE.)

Если code - меньше чем нуль, подключаемая процедура должна передать сообщение в функцию CallNextHookEx без дальнейшей обработки, а возвратить должна значение возвращенное CallNextHookEx.
wParam
Определяет виртуальный код клавиши, которая создала сообщение нажатой клавиши.
lParam
Определяет счет повторений, скэн-код, флажок расширенной - клавиши, контекстный код, флажок предыдущего состояния клавиши и флажок переходного состояния. Этот параметр может быть комбинацией следующих значений:

  • 0-15 - Определяет счет повторений. Значением является число нажатий клавиши, которое повторено в результате пользовательского удерживания нажатия клавиши.
  • 16-23 - Определяет скэн-код. Значение зависит от фирмы-изготовителя оборудования (OEM).
  • 24 - Определяет, является ли клавиша расширенной клавишей, типа функциональной или клавиши на цифровой клавиатуре. Если клавиша является расширенной, это значение равно 1, иначе, оно - 0.
  • 25-28 - Зарезервировано.
  • 29 - Определяет код контекста. Это значение является 1, если нажата клавиша ALT; иначе, оно - 0.
  • 30 - Определяет предыдущее состояние клавиши. Это значение является 1, если клавиша была нажата перед отправкой сообщения. Оно - 0, если клавиша была не нажата.
  • 31 - Определяет переходное состояние. Это значение 0, если клавиша нажимается и 1, если клавиша отпускается.

Для получения дополнительной информации о параметре lParam, см. Флажки сообщения нажатия клавиши.

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

Замечания
Прикладная программа устанавливает подключаемую процедуру, путем определения типа hook-точки как WH_KEYBOARD и ее адреса при вызове функции SetWindowsHookEx.
KeyboardProc - метка - заместитель для определяемого программой или определенного библиотекой имени функции.

Смотри также
CallNextHookEx, GetMessage, PeekMessage, SetWindowsHookEx, WM_KEYUP, WM_KEYDOWN

Размещение и совместимость KeyboardProc

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		Определяется пользователем
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		HOOKPROC


7.5.1.12 - Функция MessageProc

(ПроцедураСообщения)

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

Синтаксис

LRESULT CALLBACK MessageProc
(
    int code,		// код hook-точки
    WPARAM wParam,	// не определен
    LPARAM lParam	// адрес структуры с данными сообщения
);

Параметры
code
Определяет тип события ввода, которое генерировало сообщение. Этот параметр может быть одним из следующих значений:

  • MSGF_DDEMGR - Произошло событие ввода, в то время как Библиотека Управления Динамического обмена данными (DDEML- Dynamic Data Exchange Management Library.) ожидала для окончания работы синхронизацию групповой операции (транзакции). Для получения дополнительной информации о DDEML, см. Библиотеку Управления Динамическим обменом данными.
  • MSGF_DIALOGBOX - Произошло событие ввода в окне сообщений или диалоговом окне.
  • MSGF_MENU - Произошло событие ввода в меню.
  • MSGF_NEXTWINDOW - Произошло событие ввода в результате нажима пользователем комбинации клавиш ALT+TAB, чтобы включить другое окно.
  • MSGF_SCROLLBAR - Произошло событие ввода в линейке прокрутки.

Если code является меньше чем нуль, подключаемая процедура должна передать сообщение в функцию CallNextHookEx без дальнейшей его обработки и должна возвратить значение, возвращенное CallNextHookEx.
wParam
Устанавливает значение ПУСТО (NULL).
lParam
Указывает на структуру MSG
.

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

Замечания
Прикладная программа устанавливает подключаемую процедуру, путем определения типа hook-точки как WH_MSGFILTER и ее адреса при вызове функции SetWindowsHookEx.
Если прикладная программа, которая использует DDEML и выполняет синхронные передачи данных, сообщения должны обрабатываться перед тем, как они распределены, она должна использовать hook-точку WH_MSGFILTER.
MessageProc - метка - заместитель для определяемого программой имени функции.

Смотри также
CallNextHookEx, SetWindowsHookEx, MSG

Размещение и совместимость MessageProc

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			Определется пользователем
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			HOOKPROC


7.5.1.13 - Функция MouseProc

(ПроцедураМыши)

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

Синтаксис

LRESULT CALLBACK MousedProc
(
    int nCode,		// код hook-точки
    WPARAM wParam,	// идентификатор сообщения
    LPARAM lParam	// координаты мыши
);

Параметры
nCode
Определяет код, который подключаемая процедура использует, чтобы определить, как обработать сообщение. Этот параметр может быть одним из следующих значений:

  • HC_ACTION - Параметры wParam и lParam содержат информацию о сообщении мыши.
  • HC_NOREMOVE - Параметры wParam и lParam содержат информацию о сообщении мыши, но сообщение мыши не удаляется из очереди сообщений. (Прикладная программа вызвала функцию PeekMessage, установив флажок PM_NOREMOVE.)

Если nCode - меньше чем нуль, подключаемая процедура должна передать сообщение в функцию CallNextHookEx без дальнейшей обработки, а возвратить должна значение возвращенное CallNextHookEx.
wParam
Определяет идентификатор сообщения мыши.
lParam
Указывает на структуру MOUSEHOOKSTRUCT.

Возвращаемые значения
Чтобы дать возможность системе обработать сообщение, величина возвращаемого значения должна быть нулевая. Чтобы сбросить сообщение, величина возвращаемого значения должна быть значением отличным от нуля.

Замечания
Подключаемая процедура не должна устанавливать функцию повторного вызова JournalPlaybackProc.
Прикладная программа устанавливает подключаемую процедуру, путем определения типа hook-точки как WH_MOUSE и ее адреса при вызове функции SetWindowsHookEx.
MouseProc - метка - заместитель для определяемого программой или определенного библиотекой имени функции.

Смотри также
CallNextHookEx, GetMessage, JournalPlaybackProc, MOUSEHOOKSTRUCT, PeekMessage, SetWindowsHookEx

Размещение и совместимость MouseProc

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			Определется пользователем
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			HOOKPROC


7.5.1.14 - Функция SetWindowsHookEx

(УстановкаНоокОкнаРасширенная)

Функция SetWindowsHookEx устанавливает определяемую программой подключаемую процедуру в цепочку hook-точек. Прикладная программа устанавливает фильтр - процедуру, чтобы контролировать некоторые типы событий в системе. Подключаемая процедура может контролировать события связанные или с конкретным потоком или со всеми потоками в системе. Эта функция заменяет функцию SetWindowsHook.

Синтаксис

HHOOK SetWindowsHookEx
(
    int idHook,		// тип hook-точки, которая устанавливается
    HOOKPROC lpfn,	// адрес подключаемой процедуры
    HINSTANCE hMod,	// дескриптор экземпляра прикладной программы
    DWORD dwThreadId	// идентификация потока, который устанавливает hook-точку
);

Параметры
idHook
Определяет тип подключаемой процедуры, которая будет установлена. Этот параметр может быть одним из следующих значений:

  • WH_CALLWNDPROC - Устанавливает подключаемую процедуру, которая контролирует сообщения до того, как система отправит их оконной процедуре предназначения. Для получения дополнительной информации, см. подключаемую процедуру CallWndProc.
  • WH_CALLWNDPROCRET - Устанавливает подключаемую процедуру, которая контролирует сообщения после того, как они были обработаны оконной процедурой предназначения. Для получения дополнительной информации, см. подключаемую процедуру CallWndRetProc.
  • WH_CBT - Устанавливает подключаемую процедуру, которая принимает уведомления, полезные для машинной подготовки (CBT) прикладной программы. Для получения дополнительной информации, см. подключаемую процедуру CBTProc.
  • WH_DEBUG - Устанавливает подключаемую процедуру, полезную для отладки других фильтр - процедур. Для получения дополнительной информации, см. подключаемую процедуру DebugProc.
  • WH_GETMESSAGE - Устанавливает подключаемую процедуру, которая контролирует сообщения, задержанные в очереди сообщений. Для получения дополнительной информации, см. подключаемую процедуру GetMsgProc.
  • WH_JOURNALPLAYBACK - Устанавливает подключаемую процедуру, которая задерживает сообщения, предварительно записанные подключаемой процедурой WH_JOURNALRECORD. Для получения дополнительной информации, см. подключаемую процедуру JournalPlaybackProc.
  • WH_JOURNALRECORD - Устанавливает подключаемую процедуру, которая записывает входящие сообщения, задерживаемые в системной очереди сообщений. Эта hook-точка полезна для регистрации макрокоманд. Для получения дополнительной информации, см. подключаемую процедуру JournalRecordProc.
  • WH_KEYBOARD - Устанавливает подключаемую процедуру, которая контролирует сообщения нажатия клавиш. Для получения дополнительной информации, см. подключаемую процедуру KeyboardProc.
  • WH_MOUSE - Устанавливает подключаемую процедуру, которая контролирует сообщения мыши. Для получения дополнительной информации, см. подключаемую процедуру MouseProc.
  • WH_MSGFILTER - Устанавливает подключаемую процедуру, которая контролирует сообщения, созданные в результате события ввода в диалоговом окне, окне сообщений, меню или линейке прокрутки. Для получения дополнительной информации, см. подключаемую процедуру MessageProc.
  • WH_SHELL - Устанавливает подключаемую процедуру, которая принимает уведомления, полезные для оболочки прикладных программ. Для получения дополнительной информации, см. подключаемую процедуру ShellProc.
  • WH_SYSMSGFILTER - Устанавливает подключаемую процедуру, которая контролирует сообщения, созданные в результате события ввода диалоговом окне, окне сообщений, меню или линейке прокрутки. Фильтр - процедура контролирует эти сообщения для всех прикладных программ в системе. Для получения дополнительной информации, см. подключаемую процедуру SysMsgProc.

lpfn
Указывает на подключаемую процедуру. Если параметр dwThreadId нулевой или он определяет идентификатор потока, созданного другим процессом, параметр lpfn должен указывать на фильтр - процедуру в динамически компонуемой библиотеке (DLL). Иначе, lpfn может указывать на подключаемую процедуру в коде, связанном с текущим процессом.
hMod
Идентифицирует динамически подключаемую библиотеку (DLL), содержащую фильтр - процедуру, указанную lpfn параметром. Параметр hMod должен быть установлен в значение ПУСТО (NULL), если параметр dwThreadId определяет поток, созданный текущим процессом и, если подключаемая процедура внутри кода, связанного с текущим процессом.
dwThreadId
Определяет идентификатор потока, с которым подключаемая процедура должна быть связана. Если этот параметр нулевой, фильтр - процедура связана со всеми существующими потоками.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - дескриптор подключаемой процедуры.
Если функция не выполняет задачу, величина возвращаемого значения ПУСТО (NULL).

Замечания
Если параметр hMod значение ПУСТО (NULL), а параметр dwThreadId нулевой или определяет идентификатор потока, созданного другим процессом, может произойти ошибка.
Формирование цепочки со следующей подключаемой процедурой (то есть вызов функции CallNextHookEx) необязателен. Прикладная программа или библиотека могут вызывать следующую фильтр - процедуру или до или после любой обработки в своей собственной подключаемой процедуре. Хотя сцепление со следующей hook-точкой необязательно, это настоятельно рекомендуется; иначе, другие прикладные программы, которые установили hook-точки, не будут принимать уведомления hook-точки и, в результате, могут повести себя неправильно.
Перед завершением, прикладная программа должна вызвать функцию UnhookWindowsHookEx, чтобы освободить системные ресурсы, связанные с hook-точкой.
Область действия hook-точки зависит от типа hook-точки. Некоторые hook-точки могут быть установлены только с системными возможностями; другие могут также быть установлены только для конкретного потока, как показано в следующем списке:

  • WH_CALLWNDPROC - Поток или система
  • WH_CBT - Поток или система
  • WH_DEBUG - Поток или система
  • WH_GETMESSAGE - Поток или система
  • WH_JOURNALPLAYBACK - Система только
  • WH_JOURNALRECORD - Система только
  • WH_KEYBOARD - Поток или система
  • WH_MOUSE - Поток или система
  • WH_MSGFILTER - Поток или система
  • WH_SHELL - Поток или система
  • WH_SYSMSGFILTER - Система только

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

Смотри также
CallNextHookEx, CallWndProc, CallWndRetProc, CBTProc, DebugProc, GetMsgProc, JournalPlaybackProc, JournalRecordProc, KeyboardProc, MouseProc, MessageProc, ShellProc, SysMsgProc, UnhookWindowsHookEx

Размещение и совместимость SetWindowsHookEx

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					WinNT
Замечания по платформе			Не имеется


7.5.1.15 - Функция ShellProc

(ПроцедураОболочки)

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

Синтаксис

LRESULT CALLBACK ShellProc
(
    int nCode,		// код hook-точки
    WPARAM wParam,	// информация, определяемая событием
    LPARAM lParam	// информация, определяемая событием
);

Параметры
nCode
Определяет код hook-точки. Этот параметр может быть одним из следующих значений:

  • HSHELL_ACTIVATESHELLWINDOW - Оболочка должна активизировать свое главное окно.
  • HSHELL_GETMINRECT - Только для Windows 95: окно свертывается или развертывается, а система нуждается в координатах свернутого (минимизированного) прямоугольника окна. Параметр wParam содержит дескриптор окна, а параметр lParam содержит адрес структуры RECT, которая принимает координаты.
  • HSHELL_LANGUAGE - Только для Windows 95: язык клавиатуры был изменен, или была загружена новая раскладка символов на клавиатуре.
  • HSHELL_REDRAW - Только для Windows 95: заголовок окна в панели задач был перерисован. Параметр wParam содержит дескриптор окна.
  • HSHELL_TASKMAN - Только для Windows 95: пользователь выбрал список задач. Параметр wParam не определен и должен игнорироваться. Оболочка прикладной программы, которая предоставляет список задач, должна возвратить значение ИСТИНА (TRUE), чтобы воспрепятствовать Windows запустить список его задач.
  • HSHELL_WINDOWACTIVATED - Только для Windows 95: активизация была заменена в другом, не имеющем владельца, окне верхнего уровня. Параметр wParam содержит дескриптор окна.
  • HSHELL_WINDOWCREATED - Было создано не имеющее владельца окно верхнего уровня. Окно существует только тогда, когда система вызывает функцию ShellProc.
  • HSHELL_WINDOWDESTROYED - Не имеющее владельца окно верхнего уровня собирается быть разрушенным. Окно все еще существует когда система вызывает функцию ShellProc.

Если nCode - меньше чем нуль, подключаемая процедура должна передать сообщение в функцию CallNextHookEx без дальнейшей обработки, а возвратить должна значение возвращенное CallNextHookEx.
wParam
Определяет дополнительную информацию, которую может потребовать оболочка прикладной программы. Если параметр nCode - HSHELL_ACTIVATESHELLWINDOW, то параметр wParam не используется. Если nCode - HSHELL_WINDOWCREATED или HSHELL_WINDOWDESTROYED, wParam определяет дескриптор создаваемого или разрушаемого окна, соответственно.
lParam
Windows 95:
Определяет дополнительную информацию. Точное значение зависит от значения параметра nCode. Если nCode - HSHELL_GETMINRECT, lParam - LPRECT. Если nCode - HSHELL_WINDOWSACTIVATED, lParam - fFullScreen. Если nCode - HSHELL_REDRAW, lParam - fNewFlash.
Windows NT:
Этот параметр должен быть равен нулю.

Возвращаемые значения
Возвращаемое значение должно быть равно нулю.

Замечания
Прикладная программа устанавливает подключаемую процедуру, путем определения типа hook-точки как WH_SHELL и ее адреса при вызове функции SetWindowsHookEx.
ShellProc - метка - заместитель для определяемого программой или определенного библиотекой имени функции.

Смотри также
CallNextHookEx, SendMessage, SetWindowsHookEx

Размещение и совместимость ShellProc

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			Определяется поьзователем
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			HOOKPROC


7.5.1.16 - Функция SysMsgProc

(ПроцедураСистемныхСообщений)

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

Синтаксис

LRESULT CALLBACK SysMsgProc
(
    int nCode,		// флажок сообщения
    WPARAM wParam,	// не определен
    LPARAM lParam	// адрес структуры с данными сообщения
);

Параметры
nCode
Определяет тип события ввода, которое генерировало сообщение. Этот параметр может быть одним из следующих значений:

  • MSGF_DIALOGBOX - Произошло событие ввода в окне сообщений или диалоговом окне.
  • MSGF_MENU - Произошло событие ввода в меню.
  • MSGF_SCROLLBAR - Произошло событие ввода в линейке прокрутки.
  • MSGF_NEXTWINDOW - Произошло событие ввода в результате пользовательского нажатия комбинации клавиш ALT+TAB, чтобы активизировать другое окно.

Если nCode - меньше чем нуль, подключаемая процедура должна передать сообщение в функцию CallNextHookEx без дальнейшей обработки, а возвратить должна значение возвращенное CallNextHookEx.
wParam
Определяет значение ПУСТО (NULL)
lParam
Указывает на структуру MSG сообщения.

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

Замечания
Прикладная программа устанавливает подключаемую процедуру, путем определения типа hook-точки как WH_SYSMSGFILTER и ее адреса при вызове функции SetWindowsHookEx.
SysMsgProc - метка - заместитель для определенного библиотекой имени функции.

Смотри также
CallNextHookEx, MSG, SetWindowsHookEx

Размещение и совместимость SysMsgProc

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			Определяется поьзователем
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			HOOKPROC


7.5.1.17 - Функция UnhookWindowsHookEx

(УдалитьНоокОкнаРасширенная)

Функция UnhookWindowsHookEx удаляет подключаемую процедуру, установленную в цепочку hook-точек функцией SetWindowsHookEx.

Синтаксис

BOOL UnhookWindowsHookEx
(
    HHOOK hhk	// дескриптор подключаемой процедуры, которая удаляется
);

Параметры
hhk
Идентифицирует hook-точку, которая будет удалена. Этот параметр - дескриптор hook-точки, полученный предыдущим вызовом к SetWindowsHookEx.

Возвращаемые значения
Если функция завершилась успешно, возвращается значение отличное от нуля.
Если функция потерпела неудачу, возвращаемое значение - ноль.

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

Смотри также
SetWindowsHookEx, UnhookWindowsHook

Размещение и совместимость UnhookWindowsHookEx

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


7.5.1.18 - Функция DefHookProc

(ПроцедураНоокПоУмолчанию)

Функция DefHookProc устарела. Она предусмотрена только для совместимости с 16-разрядными версиями Windows. Базирующиеся на Win32 прикладные программы должны использовать функцию CallNextHookEx.


7.5.1.19 - Функция SetWindowsHook

(УстановкаНоокОкна)

Функция SetWindowsHook устаревшая. Эта функция предусмотрена только для совместимости с 16-разрядными версиями Windows. Базирующиеся на Win32 прикладные программы должны использовать функцию SetWindowsHookEx.


7.5.1.20 - Функция UnhookWindowsHook

(УдалениеНоокОкна)

Функция UnhookWindowsHook устаревшая, но предусмотрена для совместимости с 16-разрядными версиями Windows. Для базирующихся на Win32 прикладных программ, используйте функцию UnhookWindowsHookEx.


7.5.2 - Структуры для hook-точек

Ниже перечисленные структуры используются с hook-точками.
CBT_CREATEWND
CBTACTIVATESTRUCT
CWPRETSTRUCT
CWPSTRUCT
DEBUGHOOKINFO
EVENTMSG
MOUSEHOOKSTRUCT


7.5.2.1 - Структура CBT_CREATEWND

Структура CBT_CREATEWND содержит информацию, передаваемую в подключаемую процедуру WH_CBT до того, как окно создается.

Синтаксис

typedef struct tagCBT_CREATEWND
{
    LPCREATESTRUCT lpcs;
    HWND hwndInsertAfter;
} CBT_CREATEWND;

Члены структуры
lpcs
Указывает на структуру CREATESTRUCT, которая содержит параметры инициализации для окна, собирающегося быть созданным.
hwndInsertAfter
Идентифицирует окно, чья позиция в Z-последовательности предшествует позиции такого же создаваемого окна.

Смотри также
CBTProc, CREATESTRUCT, SetWindowsHookEx

Размещение и совместимость CBT_CREATEWND

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


7.5.2.2 - Структура CBTACTIVATESTRUCT

Структура CBTACTIVATESTRUCT содержит информацию, передаваемую в подключаемую процедуру WH_CBT до того, как окно активизировано.

Синтаксис

typedef struct tagCBTACTIVATESTRUCT
{
    BOOL fMouse;
    HWND hWndActive;
} CBTACTIVATESTRUCT;

Члены структуры
fMouse
Определяет, активизируется ли окно в результате щелчка мыши. Это значение - ИСТИНА (TRUE), если щелчок мыши вынуждает активизацию или ЛОЖЬ(FALSE), если этого - нет.
hWndActive
Идентифицирует активное окно.

Смотри также
SetWindowsHookEx

Размещение и совместимость CBTACTIVATESTRUCT

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			-
Заголовочный файл				winuser.h
Unicode					No
Замечания по платформе			Не имеется


7.5.2.3 - Структура CWPRETSTRUCT

Структура CWPRETSTRUCT определяет параметры сообщения, посылаемые в подключаемую процедуру WH_CALLWNDPROCRET.

Синтаксис

typedef struct tagCWPRETSTRUCT
{
    LRESULT lResult;
    LPARAM lParam;
    WPARAM wParam;
    DWORD message;
    HWND hwnd;
} CWPRETSTRUCT;

Члены структуры
lResult
Определяет величину возвращаемого значения оконной процедурой, которая обработала сообщение, заданное значением message.
lParam
Определяет дополнительную информацию о сообщении. Точное значение зависит от величины message.
wParam
Определяет дополнительную информацию о сообщении. Точное значение зависит от величины message.
message
Определяет сообщение.
hwnd
Идентифицирует окно, которое обработало сообщение, заданное значением message.

Смотри также
CallWndRetProc, SetWindowsHook, SetWindowsHookEx

Размещение и совместимость CWPRETSTRUCT

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


7.5.2.4 - Структура CWPSTRUCT

Структура CWPSTRUCT определяет параметры сообщения, посылаемые в подключаемую процедуру WH_CALLWNDPROC.

Синтаксис

typedef struct tagCWPSTRUCT
{
    // cwps
    LPARAM lParam;
    WPARAM wParam;
    UINT message;
    HWND hwnd;
} CWPSTRUCT;

Члены структуры
lParam
Определяет дополнительную информацию о сообщении. Точное предназначение зависит от значения message.
wParam
Определяет дополнительную информацию о сообщении. Точное предназначение зависит от значения message.
message
Определяет сообщение
hwnd
Идентифицирует окно, которое принимает сообщение.

Смотри также
CallWndProc, SetWindowsHook, SetWindowsHookEx

Размещение и совместимость CWPSTRUCT

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


7.5.2.5 - Структура DEBUGHOOKINFO

Структура DEBUGHOOKINFO содержит отладочную информацию.

Синтаксис

typedef struct tagDEBUGHOOKINFO {
    DWORD idThread;
    DWORD idThreadInstaller;
    LPARAM lParam;
    WPARAM wParam;
    int code;
} DEBUGHOOKINFO;

Члены структуры
idThread
Идентифицирует поток, содержащий функцию фильтра.
idThreadInstaller
Идентифицирует поток, который установил функцию фильтра отладки.
lParam
Определяет значение, которое будет отправлено в hook-точку в параметре lParam функции повторного вызова DebugProc.
wParam
Определяет значение, которое будет отправлено в hook-точку в параметре wParam функции повторного вызова DebugProc
code
Определяет значение, которое будет отправлено в hook-точку в параметре nCode функции повторного вызова DebugProc

Смотри также
DebugProc, SetWindowsHook, SetWindowsHookEx

Размещение и совместимость DEBUGHOOKINFO

Windows NT			Да
Win95				Нет
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


7.5.2.6 - Структура EVENTMSG

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

Синтаксис

typedef struct tagEVENTMSG
{
    UINT message;
    UINT paramL;
    UINT paramH;
    DWORD time;
    HWND hwnd;
} EVENTMSG;

Члены структуры
message
Определяет сообщение.
paramL
Определяет дополнительную информацию о сообщении. Точное предназначение зависит от значения message.
paramH
Определяет дополнительную информацию о сообщении. Точное предназначение зависит от значения message.
time
Определяет время, в которое сообщение было переслано.
hwnd
Идентифицирует окно, которому сообщение было передано.

Смотри также
JournalPlaybackProc, SetWindowsHookEx

Размещение и совместимость EVENTMSG.

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


7.5.2.7 - Структура MOUSEHOOKSTRUCT

Структура MOUSEHOOKSTRUCT содержит информацию о событии нажатия кнопки мыши.

Синтаксис

typedef struct tagMOUSEHOOKSTRUCT {
    POINT pt;
    HWND hwnd;
    UINT wHitTestCode;
    DWORD dwExtraInfo;
} MOUSEHOOKSTRUCT;

Члены структуры
pt
Определяет структуру POINT, которая содержит x- и y-координаты курсора, в экранных координатах.
hwnd
Идентифицирует окно, которое примет сообщение мыши, соответствующее событию нажатия кнопки мыши.
wHitTestCode
Определяет значение местоположения курсора. За списком значений местоположения курсора, обратитесь к описанию сообщения WM_NCHITTEST.
dwExtraInfo
Определяет дополнительную информацию, связанную с сообщением.

Смотри также
GetMessageExtraInfo, POINT, SetWindowsHook, SetWindowsHookEx, WM_NCHITTEST

Размещение и совместимость MOUSEHOOKSTRUCT

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


7.5.3 - Сообщения hook-точек

Следующие сообщения используются с hook-точками.
WM_CANCELJOURNAL
WM_QUEUESYNC


7.5.3 1 - Сообщение WM_CANCELJOURNAL

Сообщение WM_CANCELJOURNAL посылается прикладной программе, когда пользователь отменяет ведущийся протокол действий прикладной программы. Сообщение посылается с дескриптором окна имеющим значение ПУСТО (NULL).

Синтаксис

WM_CANCELJOURNAL
wParam = 0;  //не используется, должно быть, нуль
lParam = 0;  // не используется, должно быть, нуль

Параметры
У этого сообщения нет параметров.

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

Замечания
Режимы записи и воспроизведения протокола - режимы, возложенные на систему, которые позволяют прикладной программе последовательно записывать или воспроизводить ввод пользователя. Система вводит эти режимы тогда, когда прикладная программа устанавливает подключаемую процедуру JournalRecordProc или JournalPlaybackProc. Когда система находится в любом из этих режимов, ведущих протокол, прикладные программы должны делать по очереди чтение вводимых данных из входной очереди. Если какая-либо прикладная программа останавливает чтение вводимой информации, пока система находится в режиме ведения протокола, другие прикладные программы вынуждены ждать.
Чтобы гарантировать устойчивость системы, для любой прикладной программой, которой нельзя зависать, Windows NT автоматически отменяет любые ведущие протокол действия, когда пользователь нажимает CTRL+ESC или CTRL+ALT+DEL.
Система тогда отключает любые фильтр - процедуры ведущие протокол, и посылает сообщение WM_CANCELJOURNAL со значением дескриптора окна ПУСТО (NULL) в прикладную программу, которая установила ведущую протокол hook-точку.
Так как сообщение WM_CANCELJOURNAL имеет дескриптор окна ПУСТО (NULL), оно не может быть послано оконной процедуре. Имеются два способа для прикладной программы, чтобы увидеть сообщение WM_CANCELJOURNAL: Если прикладная программа запускает свой собственный главный цикл сообщений, она должна перехватить сообщение между своим вызовом GetMessage или PeekMessage и своим вызовом DispatchMessage. Если прикладная программа не запускает свой собственный главный цикл сообщений, она должна установить подключаемую процедуру GetMsgProc (через вызов SetWindowsHookEx, определяя тип hook-точки как WH_GetMessage), которая отслеживает это сообщение.
Когда прикладная программа видит сообщение WM_CANCELJOURNAL, она может предположить два обстоятельства: пользователь преднамеренно отменил режим записи или воспроизведения протокола и система уже отключила любую подключаемую процедуру записи или воспроизведения протокола.
Обратите внимание!, что комбинация клавиш, упоминаемая выше (CTRL+ESC или CTRL+ALT+DEL), заставляет систему отменить ведение протокола. Если какая либо из прикладных программ зависает, они дают пользователю средства возвращения управляемости. Виртуальный код клавиши VK_CANCEL (обычно реализованный как комбинация клавиш CTRL+BREAK) - это то, что прикладная программа, которая находится в режиме записи протокола, должна ожидать как сигнал, что пользователь желает отменить ведущее протокол действие. Разницей является то, что наблюдение за VK_CANCEL является предложенным поведением для ведущих протокол прикладных программ, принимая во внимание, что CTRL+ESC или CTRL+ALT+DEL заставляют систему отменить ведение протокола независимо от поведения прикладной программы, ведущей протокол.

Смотри также
DispatchMessage, GetMessage, JournalPlaybackProc, JournalRecordProc, GetMsgProc, PeekMessage, SetWindowsHookEx

Размещение и совместимость WM_CANCELJOURNAL

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


7.5.3 2 - Сообщение WM_QUEUESYNC

Сообщение WM_QUEUESYNC посылается прикладной программой машинной подготовки (CBT), чтобы отделить введенные пользователем сообщения от других сообщений, переданных через подключаемую процедуру WH_JOURNALPLAYBACK.

Синтаксис

WM_QUEUESYNC
wParam = 0; //не используется, должно быть, нуль
lParam = 0; // не используется, должно быть, нуль

Параметры
У этого сообщения нет параметров.

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

Замечания
Всякий раз, когда CBT приложение использует подключаемую процедуру WH_JOURNALPLAYBACK, первое и последнее сообщения - это WM_QUEUESYNC. Это позволяет CBT прикладной программе прерывать и проверять инициализированные пользователем сообщения без прерывания таким же образом событий, которыми оно передается.
Если прикладная программа определяет дескриптор окна ПУСТО (NULL), сообщение пересылается в очередь сообщений активного окна.

Размещение и совместимость WM_QUEUESYNC

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется
Предыдущий Шаг


Глава 3. Буфер обмена

Буфер обмена (clipboard)- набор функций и сообщений, который делает возможным передачу данных в прикладные программы, разработанные при помощи Microsoft ® Win32 ® прикладного программного интерфейса (API). Поскольку все прикладные программы имеют доступ к буферу обмена, данные могут быть легко перемещаемы между приложениями или внутри прикладной программы.

Этот краткий обзор не описывает, как копировать и вставлять связанные или внедренные объекты. Для информации относительно этих тем, см. Справочник программиста по OLE (OLE Programmer's Reference).

Следующий Шаг


3.1 - О буфере обмена

Запоминаемый объект в буфере обмена может быть в любом формате данных, называемом форматом буфера обмена (clipboard format). Каждый формат идентифицирован значением целого числа без знака(unsigned integer). Для стандартных (предопределенных) форматов буфера обмена, это значение - константа, определенная в Win32 API; для зарегистрированных форматов буфера обмена, оно - возвращаемое значение функции RegisterClipboardFormat.

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

Буфер обмена управляется пользователем. Окно должно передавать данные в буфер обмена или из него только в ответ на команду от пользователя. Окно не должно использовать буфер обмена для передачи данных без извещения об этом пользователя.


3.2 - Форматы буфера обмена

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


3.2.1 - Зарегистрированные форматы буфера обмена

Многие прикладные программы работают с данными, которые не могут быть переданы в стандартном формате буфера обмена без потери информации. Эти программы могут создавать свои собственные форматы буфера обмена. Формат буфера обмена, который используется прикладной программой, в противоположность стандартному формату, называется зарегистрированным форматом буфера обмена (registered clipboard format). Например, если бы программа обработки текстов скопировала форматированный текст в буфер обмена, который использует стандартный текстовый формат, информация форматирования была бы потеряна. Решение проблемы состоит в том, чтобы зарегистрировать новый формат буфера обмена, такой как расширенный текстовый формат (Rich Text Format - RTF).

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

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

Для ознакомления со списком стандартных форматов буфера обмена, см. функцию SetClipboardData.


3.2.2 - Собственные форматы буфера обмена

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

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

Для получения дополнительной информации о сообщении WM_DESTROYCLIPBOARD, см. Монопольное использование буфера обмена (Clipboard Ownership).

Прикладная программа может помещать дескрипторы данных в буфер обмена, определяя собственный формат в диапазоне с CF_GDIOBJFIRST по CF_GDIOBJLAST. При использовании значений в этом диапазоне, дескриптор данных является не дескриптором объекта GDI, а дескриптором, назначенным функцией GlobalAlloc с флажками GMEM_MOVEABLE и GMEM_DDESHARE. Когда буфер обмена освобождается, система автоматически удаляет объект, использующий функцию GlobalFree.


3.2.3 - Параллельные форматы буфера обмена

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

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

Например, предположим, что пользователь копирует стилизованный текст из документа текстового процессора. Окно, содержащее документ, может сначала поместить данные в буфер обмена в зарегистрированном формате, типа RTF. Впоследствии, окно поместит данные в буфер обмена в менее квалифицирующем формате, типа текстового (CF_TEXT).

Когда содержание буфера обмена вставляется в другое окно, окно возвращает обратно данные в наиболее квалифицирующем формате, который оно распознает. Если окно распознает RTF, соответствующие данные вставляются в документ. Иначе, текстовые данные вставляются в документ, а информация о форматировании текста теряется.


3.2.4 - Синтезируемые форматы буфера обмена

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

Формат Буфера обмена	Формат преобразования	Платформа поддержки
CF_BITMAP			CF_DIB			Windows NT, Windows 95
CF_DIB			CF_BITMAP			Windows NT, Windows 95
CF_DIB			CF_PALETTE		Windows NT, Windows 95
CF_ENHMETAFILE		CF_METAFILEPICT		Windows NT, Windows 95
CF_METAFILEPICT		CF_ENHMETAFILE		Windows NT, Windows 95
CF_OEMTEXT		CF_TEXT			Windows NT, Windows 95
CF_OEMTEXT		CF_UNICODETEXT		Windows NT
CF_TEXT			CF_OEMTEXT		Windows NT, Windows 95
CF_TEXT			CF_UNICODETEXT		Windows NT
CF_UNICODETEXT		CF_OEMTEXT		Windows NT
CF_UNICODETEXT		CF_TEXT			Windows NT

Если система обеспечивает преобразование между параллельными форматами, нет никакой выгоды от размещения параллельных форматов в буфере обмена. При копировании точечных рисунков, самое лучшее, в буфер обмена поместить только формат CF_DIB. Это потому, что цвета в аппаратно-зависимом точечном рисунке (CF_BITMAP) взаимосвязаны с палитрой системы, которая может измениться до того, как точечный рисунок будет вставлен. Если только формат CF_DIB находится в буфере обмена, а окно запрашивает формат CF_BITMAP, система представляет аппаратно-зависимый точечный рисунок (DIB), используя текущую палитру этого момента.

Если Вы помещаете формат CF_BITMAP в буфер обмена (а не CF_DIB), система выполняет формат буфера обмена CF_DIB, как только буфер обмена будет закрыт. Это гарантирует то, что используется правильная палитра для создания DIB. Преобразования между другими форматами буфера обмена происходят после запроса.


3.3 - Действия Буфера обмена

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

Чтобы поместить данные в буфер обмена или извлечь данные из него, окно должно сначала открыть буфер обмена, используя функцию OpenClipboard. Одновременно только одно окно может иметь открытым буфер обмена. Чтобы выяснить, какое окно имеет открытый буфер обмена, вызовите функцию GetOpenClipboardWindow. Когда окно закончит работу, оно должно закрыть буфер обмена, вызвав функцию CloseClipboard.


3.3.1 - Операции Вырезать (Cut) и Копировать (Copy)

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

После очистки буфера обмена, окно помещает данные в него в стольких форматах, сколько это возможно, упорядоченных от наиболее квалифицирующего формата буфера обмена до наименее квалифицирующего. Для каждого формата, окно вызывает функцию SetClipboardData, устанавливая идентификатор формата и глобальный дескриптор памяти. Дескриптор памяти может быть НОЛЬ (NULL), указывая, что окно показывает данные по запросу. Для получения дополнительной информации, см. Отсроченная запись.


3.3.2 - Операция Вставить (Paste)

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

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

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


3.4 - Монопольное использование буфера обмена

Владелец буфера обмена (clipboard owner) - окно, связанное информацией с буфером обмена. Окно становится владельцем буфера обмена, когда оно помещает данные в буфер обмена - в особенности, когда оно вызывает функцию EmptyClipboard. Окно остается владельцем буфера обмена до тех пор, пока оно не закрыто, или пока другое окно не освободит буфер обмена.

Когда буфер обмена очищается, владелец буфера обмена получает сообщение WM_DESTROYCLIPBOARD. Перечисление ниже - некоторые причины, почему окно должно обрабатывать это сообщение:

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

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

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


3.5 - Отсроченная запись

При размещении формата в буфере обмена, окно может задержать запись данных в этом формате, пока данные не нужны. Чтобы сделать это, прикладная программа может для параметра hData функции SetClipboardData установить НОЛЬ (NULL). Это полезно, если прикладная программа поддерживает несколько форматов буфера обмена, некоторые или все из которых занимают много времени для записи. Передавая дескриптор НОЛЬ (NULL), окно предоставляет сложные форматы буфера обмена только тогда, если и когда они необходимы.

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

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

Прикладная программа не должна открывать буфер обмена перед вызовом SetClipboardData в ответ на сообщение WM_RENDERFORMAT или WM_RENDERALLFORMATS.

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


3.6 - Память и буфер обмена

Объект памяти, который должен быть помещен в буфер обмена, должен быть размещен, при помощи использования функции GlobalAlloc с флажками GMEM_DDESHARE и GMEM_MOVEABLE.

Как только объект памяти помещен в буфер обмена, монопольное использование этого дескриптора памяти переходит к системе. Когда буфер обмена очищается, а объект памяти имеет один из следующих форматов буфера обмена, система освобождает объект памяти, обращаясь к обозначенной функции Win32:

Наименование функции, которая освобождает объект 	Формат буфера обмена
DeleteMetaFile						CF_DSPENHMETAFILE
                            CF_DSPMETAFILEPICT
                            CF_ENHMETAFILE
                            CF_METAFILEPICT
DeleteObject						CF_BITMAP
                            CF_DSPBITMAP
                            CF_PALETTE
GlobalFree						CF_DIB
                            CF_DSPTEXT
                            CF_OEMTEXT
                            CF_TEXT
                            CF_UNICODETEXT

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


3.7 - Окно просмотра буфера обмена

Окно просмотра буфера обмена (clipboard viewer) - окно, которое отображает текущее содержание буфера обмена. Окно окна просмотра буфера обмена - удобство для пользователя и не воздействует на функции сообщаемых данных буфера обмена.

Как правило, окно окна просмотра буфера обмена может отображать, по крайней мере, три наиболее общих формата: CF_TEXT, CF_BITMAP и CF_METAFILEPICT. Если окно не делает данные доступными в каком-либо из этих трех форматов, оно должно обеспечить данные в форме отображения данных на дисплее или использовать формат владельца - отображающего данные на дисплее.

Цепочка окон просмотра буфера обмена (clipboard viewer chain) - соединение двух или больше объектов так, чтобы они были зависимы работе друг от друга. Эта взаимозависимость (цепочка) позволяет всем запущенным окнам просмотра буфера обмена прикладных программ принимать сообщения, посланные текущему буферу обмена.


3.8 - Окна просмотра буфера обмена

Окно добавляет себя к цепочке окон просмотра буфера обмена при помощи вызова функции SetClipboardViewer. Возвращаемое значение - дескриптор следующего окна в цепочке. Чтобы извлечь информацию о дескрипторе первого окна в цепочке, вызовите функцию GetClipboardViewer.

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

Перед закрытием, окно просмотра буфера обмена должно удаляться из цепочки окон просмотра буфера обмена, путем вызова функции ChangeClipboardChain. Затем система посылает сообщение WM_CHANGECBCHAIN первому окну в цепочке.

Для получения дополнительной информации об обработке сообщений WM_DRAWCLIPBOARD и WM_CHANGECBCHAIN, см. Создание окна просмотра буфера обмена.


3.9 - Форматы отображения данных на дисплее

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

Имеется четыре формата отображения данных на дисплее: CF_DSPBITMAP, CF_DSPMETAFILEPICT, CF_DSPTEXT и CF_DSPENHMETAFILE. Эти форматы отображения записываются таким же образом, как и стандартные форматы, которыми являются CF_BITMAP, CF_TEXT, CF_METAFILEPICT и CF_ENHMETAFILE.


3.10 - Запись данных приложением в собственно формате

Для владельца буфера обмена, который не использует, какой-либо из стандартных общеупотребительных форматов буфера обмена, как вариант для обеспечения формата записи данных должен использоваться формат записи данных приложения - владельца (CF_OWNERDISPLAY) буфера обмена.

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


3.11 - Команды буфера обмена

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

  • Вырезать (Cut) - Помещает копию текущего выбора в буфер обмена и удаляет выбранное из документа. Предыдущее содержание буфера обмена разрушается.
  • Копировать (Copy) - Помещает копию текущего выбора в буфер обмена. Документ остается неизменным. Предыдущее содержание буфера обмена разрушается.
  • Вставить (Paste) - Заменяет текущий выбор на содержание буфера обмена. Содержание буфера обмена не изменяется.
  • Удалить (Delete) - Удаляет текущий выбор из документа. Содержание буфера обмена не изменяется. Эта команда не включается в буфер обмена, но она должна быть представлена вместе с командами буфера обмена в меню Редактирования (Edit).


3.12 - Использование буфера обмена

Выполнение команд Вырезать (Cut), Копировать (Copy) и Вставить (Paste)

Создание окна просмотра буфера обмена


3.12.1 - Выполнение команд Вырезать (Cut), Копировать (Copy) и Вставить (Paste)

Этот раздел описывает, как стандартные команды Вырезать (Cut), Копировать (Copy) и Вставить (Paste) выполняются в прикладной программе. Пример в этом разделе использует эти методы для помещения данных в буфер обмена, используя зарегистрированный формат буфера обмена, формат CF_OWNERDISPLAY и формат CF_TEXT. Зарегистрированный формат используется, чтобы представить прямоугольные или эллиптические текстовые окна, называемые ярлыками (labels).


3.12.2 - Выбор Данных

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


3.13 - Создание Меню Редактирования

Прикладная программа должна загрузить таблицу клавиш-ускорителей, содержащую стандартные ускорители клавиатуры для команд меню Редактирование (Edit). Функция TranslateAccelerator должна быть добавлена к циклу сообщений прикладной программы, чтобы клавиши - ускорители дали желаемый результат. Для получения дополнительной информации о ускорителях клавиатуры, см. Ускорители клавиатуры.


3.13.1 - Обработка сообщения WM_INITMENUPOPUP

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

Ниже следует выбирающая (case) структура WM_INITMENUPOPUP для прикладной программы, которая называется Меткой (Label).

case WM_INITMENUPOPUP:
    InitMenu((HMENU) wParam);
    break;

Функция InitMenu определяется, как указано ниже.

void WINAPI InitMenu(HMENU hmenu)
{
    int  cMenuItems = GetMenuItemCount(hmenu);
    int  nPos;
    UINT id;
    UINT fuFlags;
    PLABELBOX pbox = (hwndSelected == NULL) ? NULL :
        (PLABELBOX) GetWindowLong(hwndSelected, 0);

    for (nPos = 0; nPos < cMenuItems; nPos++)
    {
        id = GetMenuItemID(hmenu, nPos);
        switch (id)
        {
            case IDM_CUT:
            case IDM_COPY:
            case IDM_DELETE:
                if (pbox == NULL || !pbox->fSelected)
                    fuFlags = MF_BYCOMMAND | MF_GRAYED;
                else if (pbox->fEdit)
                    fuFlags = (id != IDM_DELETE && pbox->ichSel
                        == pbox->ichCaret) ?
                        MF_BYCOMMAND | MF_GRAYED :
                        MF_BYCOMMAND | MF_ENABLED;
                else
                    fuFlags = MF_BYCOMMAND | MF_ENABLED;

                EnableMenuItem(hmenu, id, fuFlags);
                break;

            case IDM_PASTE:
                if (pbox != NULL && pbox->fEdit)
                    EnableMenuItem(hmenu, id,
                        IsClipboardFormatAvailable(CF_TEXT) ?
                        MF_BYCOMMAND | MF_ENABLED :
                        MF_BYCOMMAND | MF_GRAYED);
                else
                    EnableMenuItem(hmenu, id,
                        IsClipboardFormatAvailable(
                            uLabelFormat) ?
                            MF_BYCOMMAND | MF_ENABLED :
                            MF_BYCOMMAND | MF_GRAYED);
        }
    }
}


3.13.2 - Обработка сообщения WM_COMMAND

Чтобы обрабатывать команды меню, добавьте выбирающую структуру WM_COMMAND к основной оконной процедуре вашей прикладной программы. Ниже следует выбирающая структура WM_COMMAND для оконной процедуры прикладной программы Метка (Lebel).

case WM_COMMAND:
    switch (LOWORD(wParam))
    {
        case IDM_CUT:
            if (EditCopy())
                EditDelete();
            break;
        case IDM_COPY:
            EditCopy();
            break;
        case IDM_PASTE:
            EditPaste();
            break;
        case IDM_DELETE:
            EditDelete();
            break;
        case IDM_EXIT:
            DestroyWindow(hwnd);
    }
    break;

Чтобы выполнить команды Копировать (Copy) и Вырезать(Cut), оконная процедура вызывает определяемую программой функцию EditCopy. Для получения дополнительной информации, см. Копирование информации в буфер обмена. Чтобы выполнить команду Вставить (Paste), оконная процедура вызывает определяемую программой функцию EditPaste. Для получения дополнительной информации о функции EditPaste, см. Вставка информации из буфера обмена.


3.13.3 - Копирование информации в Буфер обмена

В прикладной программе Метка, функция EditCopy, определяемая программой, копирует текущий выбор в буфер обмена. Эта функция делает следующее:

  1. Открывает буфер обмена путем вызова функции OpenClipboard.
  2. Очищает буфер обмена путем вызова функции EmptyClipboard.
  3. Вызывает функцию SetClipboardData для каждого формата буфера обмена, которыми обеспечена прикладная программа.
  4. Закрывает буфер обмена путем вызова функции CloseClipboard.

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

#define BOX_ELLIPSE 0
#define BOX_RECT 1
#define CCH_MAXLABEL 80
#define CX_MARGIN 12

typedef struct tagLABELBOX {	// box (окно)
    RECT rcText;		// координаты прямоугольника, содержащего текст
    BOOL fSelected;		// ИСТИНА (TRUE), если выбрана пометка
    BOOL fEdit;		// ИСТИНА (TRUE), если выбран текст
    int nType;		// прямоугольный или эллиптический
    int ichCaret;		// позиция каретки
    int ichSel;		// с ichCaret, разграничивает выбор
    int nXCaret;		// позиция окна в соответствии с ichCaret
    int nXSel;		// позиция окна в соответствии с ichSel
    int cchLabel;		// длина текста в atchLabel
    TCHAR atchLabel[CCH_MAXLABEL];
} LABELBOX, *PLABELBOX;

Ниже следует функция EditCopy.

BOOL WINAPI EditCopy(VOID)
{
    PLABELBOX pbox;
    LPTSTR lptstrCopy;
    HGLOBAL hglbCopy;
    int ich1, ich2, cch;

    if (hwndSelected == NULL) return FALSE;

    // Открываем буфер обмена и очищаем его.

    if (!OpenClipboard(hwndMain))
        return FALSE;
    EmptyClipboard();

    // Получаем указатель на структуру для выбора пометки.

    pbox = (PLABELBOX) GetWindowLong(hwndSelected, 0);

    // Если текст выбран, он копируется с использованием формата CF_TEXT.
    if (pbox->fEdit)
    {
        if (pbox->ichSel == pbox->ichCaret)	// нулевая длина
        {
            CloseClipboard();		// выбор
            return FALSE;
        }
        if (pbox->ichSel < pbox->ichCaret)
        {
            ich1 = pbox->ichSel;
            ich2 = pbox->ichCaret;
        }
        else
        {
            ich1 = pbox->ichCaret;
            ich2 = pbox->ichSel;
        }
        cch = ich2 - ich1;

        // Распределяем глобальный объект памяти для текста.
        hglbCopy = GlobalAlloc(GMEM_DDESHARE,
            (cch + 1) * sizeof(TCHAR));
        if (hglbCopy == NULL)
        {
            CloseClipboard();
            return FALSE;
        }

        // Блокируем дескриптор и копируем текст в буфер.
        lptstrCopy = GlobalLock(hglbCopy);
        memcpy(lptstrCopy, &pbox->atchLabel[ich1],
            cch * sizeof(TCHAR));
        lptstrCopy[cch] = (TCHAR) 0;	// Символ пробела

        GlobalUnlock(hglbCopy);

        // Помещаем дескриптор в буфер обмена.
        SetClipboardData(CF_TEXT, hglbCopy);
    }
    // Если никакой текст не выбран, пометка скопирована как единое целое.
    else
    {
        // Сохраним скопированную пометку как локальный объект памяти.
        // Эта копирование используется для представления данных по запросу.
        // Оно освобождается в ответ на сообщение WM_DESTROYCLIPBOARD.

        pboxLocalClip = (PLABELBOX) LocalAlloc(
            LMEM_FIXED,
            sizeof(LABELBOX));

        if (pboxLocalClip == NULL)
        {
            CloseClipboard();
            return FALSE;
        }
        memcpy(pboxLocalClip, pbox, sizeof(LABELBOX));
        pboxLocalClip->fSelected = FALSE;
        pboxLocalClip->fEdit = FALSE;

        // Помещаем зарегистрированный формат, собственный формат
        // и формат CF_TEXT записи данных
        // в буфере обмена, используя отсроченную запись.
        SetClipboardData(uLabelFormat, NULL);
        SetClipboardData(CF_OWNERDISPLAY, NULL);
        SetClipboardData(CF_TEXT, NULL);
    }
    // Закроем буфер обмена.
    CloseClipboard();
    return TRUE;
}


3.13.4 - Вставка информации из буфера обмена

В прикладной программе Метка, определяемая программой, функция EditPaste вставляет содержимое буфера обмена. Эта функция делает следующее:

  1. Открывает буфер обмена путем вызова функции OpenClipboard.
  2. Устанавливает, какой доступен формат буфера обмена для возврата информации.
  3. Извлекает дескриптор данных в избранном формате при помощи вызова функции GetClipboardData.
  4. Вставляет скопированные данные в документ. Дескриптор, возвращенный GetClipboardData, все еще принадлежит буферу обмена, так что прикладная программа не должна освобождать его или оставлять заблокированным.
  5. Закрывает буфер обмена при помощи вызова функции CloseClipboard.

Если пометка выбрана и содержит курсор, функция EditPaste вставляет текст из буфера обмена в месте расположения курсора. Если ничего не выбрано, или если пометка выбрана, функция создает новую пометку в буфере обмена, используя определяемую программой структуру LABELBOX. Структура LABELBOX помещает в буфер обмена, используя зарегистрированный формат буфера обмена.

Ниже показана функция EditPaste.

VOID WINAPI EditPaste(VOID)
{
    PLABELBOX pbox;
    HGLOBAL hglb;
    LPTSTR lptstr;
    PLABELBOX pboxCopy;
    int cx, cy;
    HWND hwnd;

    pbox = hwndSelected == NULL ? NULL :
        (PLABELBOX) GetWindowLong(hwndSelected, 0);

    // Если приложение в режиме редактирования,
    // получите текст буфера обмена

    if (pbox != NULL && pbox->fEdit)
    {
        if (!IsClipboardFormatAvailable(CF_TEXT))
            return;
        if (!OpenClipboard(hwndMain))
            return;

        hglb = GetClipboardData(CF_TEXT);
        if (hglb != NULL)
        {
            lptstr = GlobalLock(hglb);
            if (lptstr != NULL)
            {
                // Обращаемся к определяемой прикладной программой функции
                // ReplaceSelection, чтобы вставить текст и перерисовать окно.

                ReplaceSelection(hwndSelected, pbox, lptstr);
                GlobalUnlock(hglb);
            }
        }
        CloseClipboard();
        return;
    }

    // Если приложение не в режиме редактирования,
    // создаем метку окна.

    if (!IsClipboardFormatAvailable(uLabelFormat))
        return;
    if (!OpenClipboard(hwndMain))
        return;

    hglb = GetClipboardData(uLabelFormat);
    if (hglb != NULL)
    {
        pboxCopy = GlobalLock(hglb);
        if (pboxCopy != NULL)
        {
            cx = pboxCopy->rcText.right + CX_MARGIN;
            cy = pboxCopy->rcText.top * 2 + cyText;
            hwnd = CreateWindowEx(
                WS_EX_NOPARENTNOTIFY | WS_EX_TRANSPARENT,
                atchClassChild, NULL, WS_CHILD, 0, 0, cx, cy,
                hwndMain, NULL, hinst, NULL);

            if (hwnd != NULL)
            {
                pbox = (PLABELBOX) GetWindowLong(hwnd, 0);
                memcpy(pbox, pboxCopy, sizeof(LABELBOX));
                ShowWindow(hwnd, SW_SHOWNORMAL);
                SetFocus(hwnd);
            }
            GlobalUnlock(hglb);
        }
    }
    CloseClipboard();
}


3.13.5 - Регистрация формата буфера обмена

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

// Регистрация формата буфера обмена.
LoadString(hinstCurrent, IDS_FORMATNAME, atchTemp,
    sizeof(atchTemp));
uLabelFormat = RegisterClipboardFormat(atchTemp);
if (uLabelFormat == 0)
    return FALSE;


3.14 - Обработка сообщений WM_RENDERFORMAT и WM_RENDERALLFORMATS

Если окно передает в функцию SetClipboardData значение дескриптора НОЛЬ (NULL), оно должно обработать сообщения WM_RENDERFORMAT и WM_RENDERALLFORMATS, чтобы предоставить данные по запросу.

Если сообщение WM_RENDERFORMAT откладывает запись в специфическом формате, а прикладная программа запросила данные в этом формате, сообщение посылается владельцу буфера обмена. Если сообщение WM_RENDERFORMAT - сообщение об отложенной записи одного или большего количества форматов, сообщение посылается владельцу буфера обмена перед тем, как буфер будет разрушен.

Чтобы записать формат буфера обмена, оконная процедура должна поместить дескриптор данных в буфер обмена, используя функцию SetClipboardData. Она не должна открывать буфер обмена перед вызовом SetClipboardData.

Приложение Метка обрабатывает сообщения WM_RENDERFORMAT и WM_RENDERALLFORMATS следующим образом.

case WM_RENDERFORMAT:
    RenderFormat((UINT) wParam);
    break;

case WM_RENDERALLFORMATS:
    RenderFormat(uLabelFormat);
    RenderFormat(CF_TEXT);
    break;

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

void WINAPI RenderFormat(UINT uFormat)
{
    HGLOBAL hglb;
    PLABELBOX pbox;
    LPTSTR lptstr;
    int cch;

    if (pboxLocalClip == NULL)
        return;

    if (uFormat == CF_TEXT)
    {
        // Размещение буфера для текста.
        cch = pboxLocalClip->cchLabel;
        hglb = GlobalAlloc(GMEM_DDESHARE,
            (cch + 1) * sizeof(TCHAR));
        if (hglb == NULL)
            return;

        // Копирование текста из pboxLocalClip.
        lptstr = GlobalLock(hglb);
        memcpy(lptstr, pboxLocalClip->atchLabel,
            cch * sizeof(TCHAR));
        lptstr[cch] = (TCHAR) 0;
        GlobalUnlock(hglb);

        // Поместим дескриптор в буфер обмена
        SetClipboardData(CF_TEXT, hglb);
    }
    else if (uFormat == uLabelFormat)
    {
        hglb = GlobalAlloc(GMEM_DDESHARE, sizeof(LABELBOX));
        if (hglb == NULL)
            return;
        pbox = GlobalLock(hglb);

        memcpy(pbox, pboxLocalClip, sizeof(LABELBOX));
        GlobalUnlock(hglb);

        SetClipboardData(uLabelFormat, hglb);
    }
}


3.15 - Обработка сообщения WM_DESTROYCLIPBOARD

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

case WM_DESTROYCLIPBOARD:
    if (pboxLocalClip != NULL)
    {
        LocalFree(pboxLocalClip);
        pboxLocalClip = NULL;
    }
    break;


3.16 - Использование собственного формата записи данных в буфере обмена

Если окно помещает информацию в буфер обмена, используя формат буфера обмена CF_OWNERDISPLAY, оно должно делать следующее:

Обработать сообщение WM_PAINTCLIPBOARD. Это сообщение посылается владельцу буфера обмена, когда часть окна просмотра буфера обмена должна быть перерисована.

Обработать сообщение WM_SIZECLIPBOARD Это сообщение посылается владельцу буфера обмена, когда было изменено окно просмотра буфера обмена или изменилось его содержание. Как правило, окно отвечает на это сообщение, устанавливая позиции прокрутки и область окна просмотра буфера обмена. В ответ на это сообщение, прикладная программа Метки также модифицирует структуру SIZE для окна просмотра буфера обмена.

Обработать сообщения WM_HSCROLLCLIPBOARD и WM_VSCROLLCLIPBOARD. Эти сообщения посылаются владельцу буфера обмена, когда в окне просмотра буфера обмена происходит событие с полосой прокрутки окна.

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

Оконная процедура приложения Метки (Label) обрабатывает эти сообщения, следующим образом.

LRESULT CALLBACK MainWindowProc(hwnd, msg, wParam, lParam)
HWND hwnd;
UINT msg;
WPARAM wParam;
LPARAM lParam;
{
    static RECT rcViewer;

    RECT rc;
    LPRECT lprc;
    LPPAINTSTRUCT lpps;

    switch (msg)
    {
        //
        // Дескриптор другого сообщения.
        //

        case WM_PAINTCLIPBOARD:
            // Определение габаритов метки
            SetRect(&rc, 0, 0,
                pboxLocalClip->rcText.right + CX_MARGIN,
                pboxLocalClip->rcText.top * 2 + cyText
            );

            // Центровка изображения в окне просмотра буфера обмена.
            if (rc.right < rcViewer.right)
            {
                rc.left = (rcViewer.right - rc.right) / 2;
                rc.right += rc.left;
            }
            if (rc.bottom < rcViewer.bottom)
            {
                rc.top = (rcViewer.bottom - rc.bottom) / 2;
                rc.bottom += rc.top;
            }

            // Прорисовка изображения с использованием установок структуры PAINTSTRUCT,
            // путем вызова определяемой приложением функции PaintLabel.

            lpps = (LPPAINTSTRUCT) GlobalLock((HGLOBAL) lParam);
            PaintLabel(lpps, pboxLocalClip, &rc);
            GlobalUnlock((HGLOBAL) lParam);
            break;

        case WM_SIZECLIPBOARD:
            // Сохранение размера окна в статической
            // структуре RECT.
            lprc = (LPRECT) GlobalLock((HGLOBAL) lParam);
            memcpy(&rcViewer, lprc, sizeof(RECT));
            GlobalUnlock((HGLOBAL) lParam);

            // Установка значения прокрутки в ноль (это разрушение
            // необходимо для обработки сообщений WM_HSCROLLCLIPBOARD и
            // WM_VSCROLLCLIPBOARD).

            SetScrollRange((HWND) wParam, SB_HORZ, 0, 0, TRUE);
            SetScrollRange((HWND) wParam, SB_VERT, 0, 0, TRUE);
            break;

        case WM_ASKCBFORMATNAME:
            LoadString(hinst, IDS_OWNERDISPLAY,
                (LPSTR) lParam, wParam);
            break;

        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}


3.17 - Создание Окна просмотра в Буфере обмена

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

Добавить окно к цепочке окон просмотра буфера обмена.

Обработать сообщение WM_CHANGECBCHAIN.

Обработать сообщение WM_DRAWCLIPBOARD.

Удалить окно из цепочки окон просмотра буфера обмена прежде, чем оно будет разрушено.


3.17.1 - Добавление окна в цепочку окон просмотра буфера обмена

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

Следующий пример добавляет окно к цепочке окон просмотра буфера обмена в ответ на сообщение WM_CREATE.

case WM_CREATE:
    // Добавление окна к цепочке окон просмотра буфера обмена.
    hwndNextViewer = SetClipboardViewer(hwnd);
    break;


3.17.2 - Обработка сообщения WM_CHANGECBCHAIN

Окно окна просмотра буфера обмена принимает сообщение WM_CHANGECBCHAIN, когда другое окно удаляется из цепочки окон просмотра буфера обмена. Если удаляемое окно - следующее окно в цепочке, окно, принимающее сообщение, должно отцепить следующее окно из цепочки. Иначе, это сообщение должно быть передано в следующее окно в цепочке.

Следующий пример показывает обработку сообщения WM_CHANGECBCHAIN.

case WM_CHANGECBCHAIN:
    // Если следующее окно закрывается, восстановление цепочки

    if ((HWND) wParam == hwndNextViewer)
        hwndNextViewer = (HWND) lParam;

    // Иначе, передача сообщения следующей связи
    else if (hwndNextViewer != NULL)
        SendMessage(hwndNextViewer, uMsg, wParam, lParam);
    break;


3.17.3 - Удаление окна из цепочки окон просмотра буфера обмена

Чтобы удалить окно из цепочки окон просмотра буфера обмена, окно вызывает функцию ChangeClipboardChain. Следующий пример удаляет окно из цепочки окон просмотра буфера обмена в ответ на сообщение WM_DESTROY.

case WM_DESTROY:
    ChangeClipboardChain(hwnd, hwndNextViewer);
    PostQuitMessage(0);
    break;


3.17.4 - Обработка сообщения WM_DRAWCLIPBOARD

Сообщение WM_DRAWCLIPBOARD предупреждает окно просмотра буфера обмена, что содержание буфера обмена изменилось. Окно должно сделать следующее при обработке сообщения WM_DRAWCLIPBOARD:

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

Извлечь информацию о данных буфера обмена и отобразить это в окне. Или, если формат буфера обмена - CF_OWNERDISPLAY, послать сообщение WM_PAINTCLIPBOARD владельцу буфера обмена.

Послать сообщение следующему окну в цепочке окон просмотра буфера обмена.

Как пример обработки сообщения WM_DRAWCLIPBOARD, см. листинг примера в Примере Окна просмотра буфера обмена.


3.17.5 - Пример листинга Окна Просмотра буфера обмена

Следующий пример показывает простую прикладную программу окна просмотра буфера обмена.

HINSTANCE hinst;
UINT uFormat = (UINT)(-1);
BOOL fAuto = TRUE;

LRESULT APIENTRY MainWndProc(hwnd, uMsg, wParam, lParam)
HWND hwnd;
UINT uMsg;
WPARAM wParam;
LPARAM lParam;
{
    static HWND hwndNextViewer;

    HDC hdc;
    HDC hdcMem;
    PAINTSTRUCT ps;
    LPPAINTSTRUCT lpps;
    RECT rc;
    LPRECT lprc;
    HGLOBAL hglb;
    LPSTR lpstr;
    HBITMAP hbm;
    HENHMETAFILE hemf;
    HWND hwndOwner;

    switch (uMsg)
    {
        case WM_PAINT:
            hdc = BeginPaint(hwnd, &ps);

            // Переход в зависимости от формата буфера обмена
            switch (uFormat)
            {
                case CF_OWNERDISPLAY:
                    hwndOwner = GetClipboardOwner();
                    hglb = GlobalAlloc(GMEM_DDESHARE,
                        sizeof(PAINTSTRUCT));
                    lpps = GlobalLock(hglb);
                    memcpy(lpps, &ps, sizeof(PAINTSTRUCT));

                    GlobalUnlock(hglb);

                    SendMessage(hwndOwner, WM_PAINTCLIPBOARD,
                        (WPARAM) hwnd, (LPARAM) hglb);

                    GlobalFree(hglb);
                    break;

                case CF_BITMAP:
                    hdcMem = CreateCompatibleDC(hdc);
                    if (hdcMem != NULL)
                    {
                        if (OpenClipboard(hwnd))
                        {
                            hbm = (HBITMAP)GetClipboardData(uFormat);
                            SelectObject(hdcMem, hbm);
                            GetClientRect(hwnd, &rc);

                            BitBlt(hdc, 0, 0, rc.right, rc.bottom,
                                hdcMem, 0, 0, SRCCOPY);
                            CloseClipboard();
                        }
                        DeleteDC(hdcMem);
                    }
                    break;

                case CF_TEXT:
                    if (OpenClipboard(hwnd))
                    {
                        hglb = GetClipboardData(uFormat);
                        lpstr = GlobalLock(hglb);

                        GetClientRect(hwnd, &rc);
                        DrawText(hdc, lpstr, -1, &rc, DT_LEFT);

                        GlobalUnlock(hglb);
                        CloseClipboard();
                    }
                    break;

                case CF_ENHMETAFILE:
                    if (OpenClipboard(hwnd))
                    {
                        hemf = GetClipboardData(uFormat);
                        GetClientRect(hwnd, &rc);
                        PlayEnhMetaFile(hdc, hemf, &rc);
                        CloseCowner-displaylipboard();
                    }
                    break;

                case 0:
                    GetClientRect(hwnd, &rc);
                    DrawText(hdc, "The clipboard is empty.", -1,
                        &rc, DT_CENTER | DT_SINGLELINE |
                        DT_VCENTER);
                    break;

                default:
                    GetClientRect(hwnd, &rc);
                    DrawText(hdc, "Unable to display format.", -1,
                        &rc, DT_CENTER | DT_SINGLELINE |
                        DT_VCENTER);
            }
            EndPaint(hwnd, &ps);
            break;

        case WM_SIZE:
            if (uFormat == CF_OWNERDISPLAY)

            {
                hwndOwner = GetClipboardOwner();
                hglb = GlobalAlloc(GMEM_DDESHARE, sizeof(RECT));
                lprc = GlobalLock(hglb);
                GetClientRect(hwnd, lprc);
                GlobalUnlock(hglb);

                SendMessage(hwndOwner, WM_SIZECLIPBOARD,
                    (WPARAM) hwnd, (LPARAM) hglb);

                GlobalFree(hglb);
            }
            break;

        case WM_CREATE:

            // Добавим окно к цепочке окон просмотра буфера обмена.

            hwndNextViewer = SetClipboardViewer(hwnd);
            break;

        case WM_CHANGECBCHAIN:

            // Если следующее окно закрывается, восстанавливаем цепочку.

            if ((HWND) wParam == hwndNextViewer)
                hwndNextViewer = (HWND) lParam;

            // Иначе, передаем сообщение в следующее звено.

            else if (hwndNextViewer != NULL)
                SendMessage(hwndNextViewer, uMsg, wParam, lParam);
            break;

        case WM_DESTROY:
            ChangeClipboardChain(hwnd, hwndNextViewer);
            PostQuitMessage(0);
            break;

        case WM_DRAWCLIPBOARD:  // буфер обмена изменил содержание.

            // Модифицируем окно, используя Автоформат буфера обмена

            SetAutoView(hwnd);

            // Передаем сообщение следующему окну в цепочке окон просмотра буфера обмена

            SendMessage(hwndNextViewer, uMsg, wParam, lParam);
            break;

        case WM_INITMENUPOPUP:
            if (!HIWORD(lParam))
                InitMenu(hwnd, (HMENU) wParam);
            break;

        case WM_COMMAND:
            switch (LOWORD(wParam))
            {
                case IDM_EXIT:
                    DestroyWindow(hwnd);
                    break;

                case IDM_AUTO:
                    SetAutoView(hwnd);
                    break;

                default:
                    fAuto = FALSE;
                    uFormat = LOWORD(wParam);
                    InvalidateRect(hwnd, NULL, TRUE);
            }
            break;

        default:
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return (LRESULT) NULL;
}

void WINAPI SetAutoView(HWND hwnd)
{
    static UINT auPriorityList[] = {
        CF_OWNERDISPLAY,
        CF_TEXT,
        CF_ENHMETAFILE,
        CF_BITMAP

    };

    uFormat = GetPriorityClipboardFormat(auPriorityList, 4);
    fAuto = TRUE;

    InvalidateRect(hwnd, NULL, TRUE);
    UpdateWindow(hwnd);
}
void WINAPI InitMenu(HWND hwnd, HMENU hmenu)
{
    UINT uFormat;
    char szFormatName[80];
    LPCSTR lpFormatName;
    UINT fuFlags;
    UINT idMenuItem;

    // Если меню - не отображаемое меню, никакой инициализации не надо.

    if (GetMenuItemID(hmenu, 0) != IDM_AUTO)
        return;

    // Удаляем все пункты меню за исключением первого.

    while (GetMenuItemCount(hmenu) > 1)
        DeleteMenu(hmenu, 1, MF_BYPOSITION);

    // Проверьте или не проверяйте пункт Автоменю.

    fuFlags = fAuto ? MF_BYCOMMAND | MF_CHECKED :
        MF_BYCOMMAND | MF_UNCHECKED;
    CheckMenuItem(hmenu, IDM_AUTO, fuFlags);

    // Если не имеется никаких форматов буфера обмена, возврат из функции

    if (CountClipboardFormats() == 0)
        return;

    // Откроем буфер обмена.

    if (!OpenClipboard(hwnd))
        return;

    // Добавим разделитель, а затем пункт меню для каждого формата.
    AppendMenu(hmenu, MF_SEPARATOR, 0, NULL);
    uFormat = EnumClipboardFormats(0);

    while (uFormat)
    {
         // Вызовем определяемую программой функцию, чтобы получить имя формата буфера обмена.
        lpFormatName = GetPredefinedClipboardFormatName(uFormat);
        // Для зарегистрированных форматов, получим зарегистрированное имя.

        if (lpFormatName == NULL)
        {
            if (GetClipboardFormatName(uFormat, szFormatName,sizeof(szFormatName)))
                lpFormatName = szFormatName;
            else
                lpFormatName = "(unknown)";
        }

        // Добавим пункт меню для формата.
        // Для воспроизводимых форматов, используем ID формата для ID меню.

        if (IsDisplayableFormat(uFormat))
        {
            fuFlags = MF_STRING;
            idMenuItem = uFormat;
        }
        else
        {
            fuFlags = MF_STRING | MF_GRAYED;
            idMenuItem = 0;
        }
        AppendMenu(hmenu, fuFlags, idMenuItem, lpFormatName);

        uFormat = EnumClipboardFormats(uFormat);
    }
    CloseClipboard();

}

BOOL WINAPI IsDisplayableFormat(UINT uFormat)
{
    switch (uFormat)
    {
        case CF_OWNERDISPLAY:
        case CF_TEXT:
        case CF_ENHMETAFILE:
        case CF_BITMAP:
            return TRUE;
    }
    return FALSE;
}


3.18 - Справочник по Буферу обмена

Следующие функции, структуры и сообщения связаны с буфером обмена.


3.18.1 - Функции Буфера обмена

Ниже перечислены функции, используемые с буфером обмена:

ChangeClipboardChain
CloseClipboard
CountClipboardFormats
EmptyClipboard
EnumClipboardFormats
GetClipboardData
GetClipboardFormatName
GetClipboardOwner
GetClipboardViewer
GetOpenClipboardWindow
GetPriorityClipboardFormat
IsClipboardFormatAvailable
OpenClipboard
RegisterClipboardFormat
SetClipboardData
SetClipboardViewer


3.18.1.1 - Функция ChangeClipboardChain

(ИзменитьЦепочкуБуфераОбмена).

Функция ChangeClipboardChain удаляет определяемое окно из цепочки окон просмотра буфера обмена.

Синтаксис

BOOL ChangeClipboardChain
(
    HWND hWndRemove,		// дескриптор удаляемого окна
    HWND hWndNewNext		// дескриптор следующего окна
);

Параметры
hWndRemove
Идентифицирует окно, которое будет удалено из цепочки. Дескриптор должен быть передан в функцию SetClipboardViewer.
hWndNewNext
Идентифицирует окно, которое следует за hWndRemove окном в цепочке окон просмотра буфера обмена. (Это - дескриптор, возвращенный функцией SetClipboardViewer, если последовательность не была изменена в ответ на сообщение WM_CHANGECBCHAIN.

Возвращаемые значения
Возвращаемое значение указывает результат переданного сообщения WM_CHANGECBCHAIN окнам в цепочке окон просмотра буфера обмена. Поскольку окно в цепочке обычно возвращает ЛОЖЬ(FALSE), когда оно обрабатывает WM_CHANGECBCHAIN, возвращаемое значение из ChangeClipboardChain - обычно ЛОЖЬ(FALSE). Если имеется только одно окно в цепочке, возвращаемое значение - обычно ИСТИНА (TRUE).

Замечания
Окно, идентифицированное как hWndNewNext заменяет hWndRemove окно в цепочке. Функция SetClipboardViewer посылает сообщение WM_CHANGECBCHAIN первому окну в цепочке окон просмотра буфера обмена.

Смотри также
SetClipboardViewer, WM_CHANGECBCHAIN

Размещение и совместимость ChangeClipboardChain

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		WNDENUMPROC


3.18.1.2 - Функция CloseClipboard

(ЗакрытьБуферОбмена).

Функция CloseClipboard закрывает буфер обмена.

Синтаксис

BOOL CloseClipboard(VOID)

Параметры
У этой функции нет параметров.

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

Замечания
Когда окно заканчивает проверку или изменяет буфер обмена, он закрывается при помощи вызова CloseClipboard. Это дает возможность другим окнам обратиться к буферу обмена.
Не помещайте объект в буфер обмена после вызова CloseClipboard.

Смотри также
GetOpenClipboardWindow, OpenClipboard

Размещение и совместимость CloseClipboard

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		WNDENUMPROC


3.18.1.3 - Функция CountClipboardFormats

(ПосдчитатьФорматыБуфераОбмена)

Функция CountClipboardFormats возвращает обратно число различных форматов данных в текущем буфере обмена.

Синтаксис

int CountClipboardFormats(VOID)

Параметры
У этой функции нет параметров.

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

Смотри также
EnumClipboardFormats, RegisterClipboardFormat

Размещение и совместимость CountClipboardFormats

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		WNDENUMPROC


3.18.1.4 - Функция EmptyClipboard

(ОпорожнитьБуферОбмена)

Функция EmptyClipboard опорожняет буфер обмена и освобождает дескрипторы данных в буфере обмена. Затем функция назначает монопольное использование буфера обмена окну, которое в настоящее время имеет открытый буфер обмена.

Синтаксис

BOOL EmptyClipboard(VOID)

Параметры
У этой функции нет параметров.

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

Замечания
Перед вызовом EmptyClipboard, прикладная программа должна открыть буфер обмена, используя функцию OpenClipboard. Если приложение при открытии буфера обмена определяет дескриптор окна NULL, EmptyClipboard завершается успешно, но устанавливает владельца буфера обмена как НОЛЬ (NULL).

Смотри также
OpenClipboard, SetClipboardData, WM_DESTROYCLIPBOARD

Размещение и совместимость EmptyClipboard

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.1.5 - Функция EnumClipboardFormats

(ПеречислитьФорматыБуфераОбмена)

Функция EnumClipboardFormats позволяет Вам перечислять форматы данных, которые являются в настоящее время доступными в буфере обмена.

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

Синтаксис

UINT EnumClipboardFormats
(
    UINT format		// Определяет известный доступный формат буфера обмена
);

Параметры
format
Определяет формат буфера обмена, о котором известно, что он является доступным.
Чтобы начать перечисление форматов буфера обмена, установленный параметр formatformat устанавливается результат предыдущего обращения к EnumClipboardFormat.

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

Замечания
Перед перечислением форматов буфера обмена, Вы должны открыть его. Чтобы открыть буфер обмена, используйте функцию OpenClipboard. Если буфер обмена не открыт, функция EnumClipboardFormats завершается с ошибкой.
Функция EnumClipboardFormats перечисляет форматы по порядку, как они были помещены в буфер обмена. Если Вы копируете информацию в буфер обмена, добавляйте объекты буфера обмена в порядке от наиболее квалифицирующего формата буфера обмена к наименее квалифицирующему формату. Если Вы вставляете информацию из буфера обмена, извлекается первый формат буфера обмена, который Вы можете обрабатывать. Это будет наиболее квалифицирующий формат буфера обмена, который Вы можете обрабатывать.
Для некоторых форматов буфера обмена, операционная система обеспечивает автоматическое преобразование типов. В случае такого формата, эта функция перечисляет заданный формат, затем перечисляет форматы, в которые он может быть преобразован. Для получения дополнительной информации о форматах буфера обмена и автоматическом преобразований типов формата буфера обмена, см. функции GetClipboardData и SetClipboardData.

Смотри также
CountClipboardFormats, GetClipboardData, OpenClipboard, RegisterClipboardFormat, SetClipboardData

Размещение и совместимость EnumClipboardFormats

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.1.6 - Функция GetClipboardData

(ПолучитьДанныеИзБуфераОбмена)

Функция GetClipboardData извлекает данные из буфера обмена в заданном формате. Буфер обмена, должен быть предварительно открыт.

Синтаксис

HANDLE GetClipboardData
(
    UINT uFormat	// формат буфера обмена
);

Параметры
uFormat
Определяет формат буфера обмена. За описанием форматов буфера обмена, обратитесь к статье о функции SetClipboardData.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - дескриптор объекта буфера обмена в заданном формате.
Если функция завершается с ошибкой, возвращаемое значение - ПУСТО (NULL). Чтобы получить дополнительные данные об ошибке, вызовите функцию GetLastError.

Замечания
Прикладная программа может перечислять доступные форматы заранее, используя функцию EnumClipboardFormats.
Буфер обмена, а не прикладная программа, управляет дескриптором, значение которого возвращает функция GetClipboardData. Прикладная программа должна копировать данные немедленно. Программа не может надеятся на получение возможности сделать долгосрочным использование дескриптора. Прикладная программа не должна ни освобождать дескриптор, ни оставлять его заблокированным.

CF_BITMAP	CF_DIB				Windows NT, Windows 95
CF_DIB		CF_BITMAP			Windows NT, Windows 95
CF_DIB		CF_PALETTE		Windows NT, Windows 95
CF_ENHMETAFILE	CF_METAFILEPICT		Windows NT, Windows 95
CF_METAFILEPICT	CF_ENHMETAFILE		Windows NT, Windows 95
CF_OEMTEXT	CF_TEXT			Windows NT, Windows 95
CF_OEMTEXT	CF_UNICODETEXT		Windows NT
CF_TEXT		CF_OEMTEXT		Windows NT, Windows 95
CF_TEXT		CF_UNICODETEXT		Windows NT
CF_UNICODETEXT	CF_OEMTEXT		Windows NT
CF_UNICODETEXT	CF_TEXT			Windows	NT

Если операционная система обеспечивает автоматическое преобразование типа в собственный формат буфера обмена, не имеется какого-либо преимущества при размещении преобразованного формата(ов) в буфере обмена.

Если буфер обмена содержит данные в формате CF_PALETTE, прикладная программа должна использовать функции SelectPalette и RealizePalette, чтобы реализовать любые другие данные в буфере обмена в замен этой логической палитры.

За дальнейшей информацией о специфических форматах данных буфера обмена обратитесь к статье о функции SetClipboardData.

Смотри также
EnumClipboardFormats, SetClipboardData, RealizePalette, SelectPalette

Размещение и совместимость GetClipboardData

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.1.7 - Функция GetClipboardFormatName

(ПолучитьИмяФорматаБуфераОбмена)

Функция GetClipboardFormatName извлекает из буфера обмена имя заданного зарегистрированного формата. Функция копирует имя в заданный буфер.

Синтаксис

int GetClipboardFormatName(
    UINT format,		// восстанавливаемый формат буфера обмена
    LPTSTR lpszFormatName,	// адрес буфера для имени
    int cchMaxCount 		//длина строки имени в символах
);

Параметры
format
Определяет тип формата, который будет извлечен. Этот параметр не должен определять какой-либо из предопределенных форматов буфера обмена.
lpszFormatName
Указывает на буфер, который должен принять имя формата.
cchMaxCount
Определяет максимальную длину, в символах, строки, которая будет скопирована в буфер. Если имя превышает это ограничение, оно усекается.

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

Смотри также
EnumClipboardFormats, RegisterClipboardFormat

Размещение и совместимость GetClipboardFormatName

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


3.18.1.8 - Функция GetClipboardOwner

(ПолучитьВладельцаБуфераОбмена)

Функция GetClipboardOwner извлекает дескриптор окна текущего владельца буфера обмена.

Синтаксис

HWND GetClipboardOwner(VOID)

Параметры
У этой функции нет параметров.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - дескриптор окна, которое владеет буфером обмена.
Если у буфера обмена нет владелеца, возвращаемое значение ПУСТО (NULL). Чтобы получить дополнительные данные об ошибке, вызовите функцию GetLastError.

Замечания
Буфер обмена может все еще содержать данные, даже если у него в настоящее время нет владельца.
Вообще, владелец буфера обмена - окно, которое самое последнее поместило данные в буфере обмена. Функция EmptyClipboard назначает монопольное использование буфера обмена.

Смотри также
EmptyClipboard, GetClipboardViewer

Размещение и совместимость GetClipboardOwner

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.1.9 - Функция GetClipboardViewer

(ПолучитьОкноПросмотраБуферфОбмена)

Функция GetClipboardViewer извлекает дескриптор первого окна в цепочке окон просмотра буфера обмена.

Синтаксис

HWND GetClipboardViewer(VOID)

Параметры
У этой функции нет параметров.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - дескриптор первого окна в цепочке окон просмотра буфера обмена.
Если нет окна просмотра буфера обмена, возвращаемое значение - ПУСТО (NULL). Чтобы получать дополнительные данные об ошибке, вызовите функцию GetLastError.

Смотри также
GetClipboardOwner, SetClipboardViewer

Размещение и совместимость GetClipboardViewer

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.1.10 - Функция GetOpenClipboardWindow

(ПолучитьОкноОткрывшееБуферОбмена)

Функция GetOpenClipboardWindow извлекает дескриптор окна, которое в настоящее время имеет открытый буфер обмена.

Синтаксис

HWND GetOpenClipboardWindow(VOID)

Параметры
У этой функции нет параметров.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - дескриптор окна, которое имеет открытый буфер обмена. Если нет окна, которое открыло буфера обмена, возвращаемое значение ПУСТО (NULL). Чтобы получать дополнительные данные об ошибке, вызовите функцию GetLastError.

Замечания
Если прикладная программа или динамически компонуемая библиотека (DLL) определяют дескриптор окна NULL при вызове функции OpenClipboard, буфер обмена открыт, но не связан с окном. В таком случае, GetOpenClipboardWindow возвращает значение ПУСТО (NULL).

Смотри также
GetClipboardOwner, GetClipboardViewer, GetOpenClipboardWindow, OpenClipboard

Размещение и совместимость GetOpenClipboardWindow

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.1.11 - Функция GetPriorityClipboardFormat

(ПолучитьПриоритетныйФорматБуфераОбмена)

Функция GetPriorityClipboardFormat возвращает значение первого доступного формата буфера обмена в заданном списке.

Синтаксис

int GetPriorityClipboardFormat(
    UINT *paFormatPriorityList,	// адрес списка приоритетов
    int cFormats 		// число вводимых данных в списке
);

Параметры
paFormatPriorityList
Указывает на массив целых чисел без знака, идентифицирующих форматы буфера обмена, в приоритетном порядке. За описанием форматов буфера обмена обратитесь к статье о функции SetClipboardData.
cFormats
Устанавливает число введенных данных в массиве paFormatPriorityList. Это значение не должно быть больше, чем число вводимых данных в списке.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - первый формат буфера обмена в списке, для которого данные являются доступными. Если буфер обмена пуст, возвращаемое значение - ПУСТО (NULL). Если буфер обмена содержит данные, но не в каком-либо из заданных форматов, возвращаемое значение - - (минус)1. Чтобы получить дополнительные данные об ошибке, обратитесь к статье о функции GetLastError.

Смотри также
CountClipboardFormats, EnumClipboardFormats, GetClipboardFormatName, IsClipboardFormatAvailable, RegisterClipboardFormat, SetClipboardData

Размещение и совместимость GetPriorityClipboardFormat

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.1.12 - Функция IsClipboardFormatAvailable

(ЭтоДоступныеФорматыБуфераОбмена)

Функция IsClipboardFormatAvailable определяет, содержит ли буфер обмена данные в заданном формате.

Синтаксис

BOOL IsClipboardFormatAvailable
(
    UINT format		// формат буфера обмена
);

Параметры
format
Определяет стандартный или зарегистрированный формат буфера обмена. За описанием форматов буфера обмена обратитесь к статье о функции SetClipboardData.

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

Замечания
Как правило, прикладная программа, которая распознает только один формат буфера обмена, должна вызывать эту функцию при обработке сообщения WM_INITMENU или WM_INITMENUPOPUP. Затем прикладная программа включает или отключает пункт меню Вставить (Paste), в зависимости от возвращаемого значения. Прикладные программы, которые распознают больше чем один формат буфера обмена, должны для этой цели использовать функцию GetPriorityClipboardFormat.

Смотри также
CountClipboardFormats, EnumClipboardFormats, GetPriorityClipboardFormat, RegisterClipboardFormat, SetClipboardData, WM_INITMENU, WM_INITMENUPOPUP

Размещение и совместимость IsClipboardFormatAvailable

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.1.13 - Функция OpenClipboard

(ОткрытьБуферОбмена)

Функция OpenClipboard открывает буфер обмена для проверки содержимого и препятствует другим прикладным программам изменять содержание буфера обмена.

Синтаксис

BOOL OpenClipboard
(
    HWND hWndNewOwner		// дескриптор окна, открывшего буфер обмена
);

Параметры
hWndNewOwner
Идентифицирует окно, которое будет связано с открытым буфером обмена. Если этот параметр ПУСТО (NULL), открытый буфер обмена связан с текущей задачей.

Возвращаемые значения
Если функция завершилась успешно, возвращается значение отличное не нуль.
Если функция завершается с ошибкой, возвращаемое значение - ноль. Чтобы получить дополнительные данные об ошибках, обратитесь к функции GetLastError.

Замечания
Функция OpenClipboard завершается с ошибкой, если другое окно имеет открытый буфер обмена.
Прикладная программа должна вызвать функцию CloseClipboard после каждого успешного обращения к OpenClipboard.
Окно, идентифицированное параметром hWndNewOwner не станет владельцем буфера обмена, если не было обращения к функции EmptyClipboard.

Смотри также
CloseClipboard, EmptyClipboard

Размещение и совместимость OpenClipboard

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.1.14 - Функция RegisterClipboardFormat

(РегистрацияФорматаБуфераОбмена)

Функция RegisterClipboardFormat регистрирует новый формат буфера обмена. Этот формат может затем использоваться как допустимый формат буфера обмена.

Синтаксис

UINT RegisterClipboardFormat
(
    LPCTSTR lpszFormat		// адрес строки с именем
);

Параметры
lpszFormat
Указывает на строку с символом нуля в конце, которая именует новый формат.

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

Замечания
Если зарегистрированный формат с заданным именем уже существует, новый формат не регистрируется, а возвращаемое значение идентифицирует существующий формат. Это дает возможность больше чем одной прикладной программе копировать и вставлять данные, использующие тот же самый зарегистрированный формат буфера обмена. Обратите внимание, что сравнение названия формата осуществляется без учета регистра.
Зарегистрированные форматы буфера обмена идентифицируются значениями в диапазоне от 0xC000 до 0xFFFF.

Смотри также
CountClipboardFormats, EnumClipboardFormats, GetClipboardFormatName

Размещение и совместимость RegisterClipboardFormat.

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


3.18.1.15 - Функция SetClipboardData

(УстановкаДанныхВБуферОбмена)

Функция SetClipboardData помещает данные в буфер обмена в заданном формате. Окно должно быть текущим владельцем буфера обмена, а прикладная программа, должна вызвать функцию OpenClipboard. (При ответе на сообщения WM_RENDERFORMAT и WM_RENDERALLFORMATS, владелец буфера обмена не должен вызвать OpenClipboard перед вызовом SetClipboardData.)

Синтаксис

HANDLE SetClipboardData
(
    UINT uFormat,		// формат буфера обмена
    HANDLE hMem		// дескриптор данных
);

Параметры
uFormat
Определяет формат буфера обмена. Этот параметр может быть зарегистрированным форматом или любым из стандартных форматов буфера обмена, перечисленных в ниже следующем разделе Замечания. За информацией о зарегистрированных форматах буфера обмена обратитесь к статье о функции RegisterClipboardFormat.
hMem
Идентифицирует данные в заданном формате. Этот параметр может иметь значение ПУСТО (NULL), указывая, что окно предоставляет данные в заданном формате буфера обмена (представляет формат) после запроса. Если окно задерживает его представление, оно должно обработать сообщения WM_RENDERFORMAT и WM_RENDERALLFORMATS.
Как только вызывается функция SetClipboardData, система идентифицирует владельца объекта при помощи параметра hMem. Прикладная программа может считывать данные, но не должна освобождать или оставлять заблокированным дескриптор. Если параметр hMem идентифицирует объект в памяти, объект, должен быть помещен, используя функцию GlobalAlloc с флажками GMEM_DDESHARE и GMEM_MOVEABLE.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - дескриптор данных.
Если функция завершается с ошибкой, возвращаемое значение ПУСТО (NULL). Чтобы получить дополнительные данные об ошибке, вызовите функцию GetLastError.

Замечания
Параметр uFormat может идентифицировать зарегистрированный формат буфера обмена или он может быть одним из следующих значений:

  • CF_BITMAP - Дескриптор к точечному рисунку (HBITMAP).
  • CF_DIB - Объект в памяти содержит структуру BITMAPINFO, сопровождаемую растровыми битами.
  • CF_DIF - Формат обмена данными программы Arts'.
  • CF_DSPBITMAP - Растровый формат отображения данных на дисплее, связанный с собственным форматом. Параметр hMem должен быть дескриптором данных, которые могут отображаться в растровом формате вместо, частным образом форматируемых данных.
  • CF_DSPENHMETAFILE - Формат отображения улучшенного метафайла связанного с собственным форматом. Параметр hMem должен быть дескриптор данных, которые могут отображаться в улучшеннном формате метафайла вместо, частным образом форматируемых данных.
  • CF_DSPMETAFILEPICT - Формат отображения данных метафайла-картинки, связанного с собственным форматом. Параметр hMem должен быть дескриптором данных, которые могут отображаться в формате метафайла-картинки вместо частным образом форматируемых данных.
  • CF_DSPTEXT - Формат отображения текста, связанный с собственным форматом. Параметр hMem должен быть дескриптором данных, которые могут отображаться в текстовом формате вместо частным образом форматируемых данных.
  • CF_ENHMETAFILE - Дескриптор улучшенного метафайла (HENHMETAFILE).
  • От CF_GDIOBJFIRST до CF_GDIOBJLAST - Диапазон целочисленных значений для определяемых программой форматов буфера обмена объекта GDI. Дескрипторы, связанные с форматами буфера обмена в этом диапазоне автоматически не удаляются, при использовании функции GlobalFree, когда опорожняется буфер обмена. Также, при использовании значений в этом диапазоне, параметр hMem - не дескриптор к объекту GDI, а дескриптор, помещенный функцией GlobalAlloc с флажками GMEM_MOVEABLE и GMEM_DDESHARE.
  • CF_HDROP - Дескриптор типа HDROP - это тот, который идентифицирует список файлов. Прикладная программа может извлечь информацию о файлах, передавая дескриптор функции DragQueryFile.
  • CF_LOCALE - Данные являются дескриптором локального идентификатора, связанного с текстом в буфере обмена. Когда вы закрываете буфер обмена, если он содержит данные CF_TEXT, а не данные CF_LOCALE, система автоматически устанавливает формат CF_LOCALE в текущем месте ввода информации. Вы можете использовать формат CF_LOCALE, чтобы сопоставлять различные места действия с текстом буфера обмена. Прикладная программа, которая вставляет текст из буфера обмена, может извлечь этот формат, чтобы определить, какой набор символов использовался, чтобы создать текст. Обратите внимание, что буфер обмена не поддерживает обычный текст в многокомпонентных наборах символов. Чтобы добиться этого, взамен используйте форматированный текстовый тип данных такой как RTF. Windows NT: система использует кодовую страницу, связанную с CF_LOCALE, чтобы неявно преобразовать из CF_TEXT в CF_UNICODETEXT. Следовательно, правильная таблица кодовой страницы используется для преобразования.
  • CF_METAFILEPICT - Дескриптор метафайла изображает формат как определено структурой METAFILEPICT. При передаче дескриптора CF_METAFILEPICT посредством динамического обмена данными (прямой ввод данных (DDE)), прикладная программа, ответственная за удаление hMem должна также освободить метафайл, упоминаемый дескриптором CF_METAFILEPICT.
  • CF_OEMTEXT - Текстовый формат, содержащий символы в OEM наборе символов. Каждые строка заканчивается комбинацией возврат каретки / перевод строки (carriage return/linefeed)(CR-LF). Символ пробела сообщает о конце данных.
  • CF_OWNERDISPLAY - Собственный формат отображения данных. Владелец буфера обмена должен отображать, и модифицировать окна просмотра буфера обмена, и приннимать сообщения WM_ASKCBFORMATNAME, WM_HSCROLLCLIPBOARD, WM_PAINTCLIPBOARD, WM_SIZECLIPBOARD и WM_VSCROLLCLIPBOARD. Параметр hMem должен иметь значение ПУСТО (NULL).
  • CF_PALETTE - Дескриптор цветовой палитры. Всякий раз, когда прикладная программа помещает данные в буфер обмена, которые зависят от цветовой палитры или назначает цветовую палитру, она должна поместить в буфер обмена также и палитру. Если буфер обмена содержит данные в формате CF_PALETTE (логическая цветовая палитра), прикладная программа должна использовать функции SelectPalette и RealizePalette, чтобы реализовать ( сравнить) любые другие данные в буфере обмена в зависимости от этой логической палитры. При отображении данных буфера обмена, буфер обмена Windows всегда использует как свою текущую палитру любого объекта в буфере обмена, который находится в формате CF_PALETTE.
  • CF_PENDATA - Дополнительные данные для пера в Microsoft Windows для Pen Computing (Компьютерного пера).
  • От CF_PRIVATEFIRST до CF_PRIVATELAST - Диапазон целых значений для собственных форматов буфера обмена. Дескрипторы, связанные с собственными форматами буфера обмена автоматически не освобождаются; владелец буфера обмена должен освобождать такие дескрипторы, обычно в ответ на сообщение WM_DESTROYCLIPBOARD.
  • CF_RIFF - Представляет звуковые данные более сложные, чем они могут быть представлены в стандартном звуковом формате CF_WAVE.
  • CF_SYLK - Формат Символической Связи Microsoft (SYLK) (Microsoft Symbolic Link).
  • CF_TEXT - Текстовый формат. Каждая строка оканчивается комбинацией возврата каретки / перевода строки (CR-LF). Символ пробела сообщает о конце данных. Используйте этот формат для текста ANSI.
  • CF_WAVE - Представляет звуковые данные в одном из стандартных звуковых форматах, таких как импульсно-кодовой модуляции 11 кГц или 22 кГц (ИКМ) (PCM- pulse code modulation).
  • CF_TIFF - Формат Файла Тегированного Изображения (TIFF - Tagged-image file format).
  • CF_UNICODETEXT - Только Windows NT: Формат текста Уникода. Каждая строка оканчивается комбинацией возврата каретки / перевода строки (CR-LF). Символ пробела сообщает о конце данных.

Операционная система выполняет неявные преобразования формата данных между некоторыми форматами буфера обмена, когда прикладная программа вызывает функцию GetClipboardData. Например, если формат CF_OEMTEXT - в буфере обмена, окно может вернуть данные в формате CF_TEXT. Формат в буфере обмена преобразуется в запрошенный формат по требованию. Нижеследующая таблица показывает преобразования типов данных буфера обмена, которые являются доступными. Обратите внимание, что некоторые из этих автоматических преобразований типов не доступны на всех платформах.

Формат буфера обмена	Преобразованный формат	Поддерживающая платформа
CF_BITMAP			CF_DIB			Windows NT, Windows 95
CF_DIB			CF_BITMAP			Windows NT, Windows 95
CF_DIB			CF_PALETTE		Windows NT, Windows 95
CF_ENHMETAFILE		CF_METAFILEPICT		Windows NT, Windows 95
CF_METAFILEPICT		CF_ENHMETAFILE		Windows NT, Windows 95
CF_OEMTEXT		CF_TEXT			Windows NT, Windows 95
CF_OEMTEXT		CF_UNICODETEXT		Windows NT
CF_TEXT			CF_OEMTEXT		Windows NT, Windows 95
CF_TEXT			CF_UNICODETEXT		Windows NT
CF_UNICODETEXT		CF_OEMTEXT		Windows NT
CF_UNICODETEXT		CF_TEXT			Windows NT

Если операционная система обеспечивает автоматическое преобразование типов для собственного формата буфера обмена, не имеется никакого преимущества для размещения преобразованного формата(ов) в буфере обмена.
При копировании точечных рисунков, лучше всего в буфер обмена поместить только формат CF_DIB. Это делается так потому, что цвета в аппаратно-зависимом точечном рисунке (CF_BITMAP) - относятся к палитре системы, которая может измениться до того, как точечный рисунок будет вставлен. Если же в буфере обмена формат CF_DIB, а окно запрашивает формат CF_BITMAP, система представляет аппаратно-зависимый точечный рисунок, использующий текущую палитру на этот момент.
Если Вы помещаете формат CF_BITMAP в буфер обмена (а не CF_DIB), система переведет его в формат буфера обмена CF_DIB, как только буфер обмена будет закрыт. Это гарантия того, что используется правильная палитра, чтобы создать не зависящий от устройства точечный рисунок (DIB). Преобразования между другими форматами буфера обмена происходят после запроса.
Платформы Windows поддерживают два формата буфера обмена для метафайлов: CF_ENHMETAFILE и CF_METAFILEPICT. Устанавливайте CF_ENHMETAFILE для расширенных метафайлов и CF_METAFILEPICT для метафайлов Windows.

Смотри также
BITMAPINFO, GetClipboardData, GlobalAlloc, GlobalFree, METAFILEPICT, OpenClipboard, RealizePalette, RegisterClipboardFormat, SelectPalette, WM_ASKCBFORMATNAME, WM_DESTROYCLIPBOARD, WM_HSCROLLCLIPBOARD, WM_PAINTCLIPBOARD, WM_RENDERFORMAT, WM_RENDERALLFORMATS, WM_SIZECLIPBOARD, WM_VSCROLLCLIPBOARD

Размещение и совместимость SetClipboardData

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.1.16 - Функция SetClipboardViewer

(УстановитьОкноПросмотраБуфераОбмена)

Функция SetClipboardViewer добавляет определяемое окно к цепочке окон просмотра буфера обмена. Окна просмотра буфера обмена принимают сообщение WM_DRAWCLIPBOARD всякий раз, когда содержание буфера обмена изменяется.

Синтаксис

HWND SetClipboardViewer
(
    HWND hWndNewViewer		// дескриптор окна просмотра буфера обмена
);

Параметры
hWndNewViewer
Идентифицирует окно, которое будет добавлено к цепочке буферов обмена.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение идентифицирует следующее окно в цепочке окон просмотра буфера обмена. Если происходит ошибка или не имеется никаких других окон в цепочке окон просмотра буфера обмена, возвращаемое значение ПУСТО (NULL). Чтобы получать дополнительные данные об ошибке, вызовите функцию GetLastError.

Замечания
Окна, которые являются частью цепочки окон просмотра буфера обмена, называемые его окнами просмотра, должны обрабатывать сообщения WM_CHANGECBCHAIN и WM_DRAWCLIPBOARD. Каждое окно окна просмотра буфера обмена вызывает функцию SendMessage, чтобы передать эти сообщения следующему окну в цепочке окон просмотра.
Окно просмотра буфера обмена должно, в конечном счете, удаляться из цепочки окон просмотра, вызовом функции ChangeClipboardChain - например, в ответ на сообщение WM_DESTROY.

Смотри также
ChangeClipboardChain, GetClipboardViewer, SendMessage, WM_CHANGECBCHAIN, WM_DRAWCLIPBOARD

Размещение и совместимость SetClipboardViewer

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.2 - Структуры буфера обмена

С буфером обмена используется ниже следующая структура.
METAFILEPICT


3.18.2.1 - Структура METAFILEPICT

Структура METAFILEPICT определяет формат метафайла изображения, используемый для обмена данными метафайла через буфер обмена.

Синтаксис

typedef struct tagMETAFILEPICT { 	// mfp
    LONG mm;
    LONG xExt;
    LONG yExt;
    HMETAFILE hMF;
} METAFILEPICT;

Элементы
mm
Устанавливает режим отображения, в котором рисуется изображение.
xExt
Определяет размер изображения в метафайле для всех режимов за исключением режимов MM_ISOTROPIC и MM_ANISOTROPIC. (Для получения дополнительной информации об этих режимах, см. элемент yExt.) Величина x устанавливает ширину прямоугольника, внутри рисуется изображение. Координаты исчисляются в единицах, которые соответствуют режиму отображения.
yExt
Определяет размер изображения в метафайле для всех режимов за исключением режимов MM_ISOTROPIC и MM_ANISOTROPIC. Величина y устанавливает высоту прямоугольника, внутри которого рисуется изображение. Координаты исчисляются в единицах, которые соответствуют режиму отображения. Для режимов MM_ISOTROPIC и MM_ANISOTROPIC, которые могут масштабироваться, элементы xExt и yExt содержат необязательный рекомендуемый размер в единицах измерения MM_HIMETRIC. Для изображений MM_ANISOTROPIC, элементы xExt и yExt могут быть нулевыми, когда никакой предлагаемый размер не обеспечивается. Для изображений MM_ISOTROPIC, отношение сторон изображения должно быть обеспечено даже тогда, когда никакой рекомендованный размер не дан. (Если предложенный размер дан, отношение сторон изображения - величина вычисляемая из предполагаемых размеров.) Чтобы дать отношение сторон изображения без учета складывающихся обстоятельств для предложенного размера, установите элементы xExt и yExt с отрицательными значениями, отношение которых соответствует отношению сторон изображения. Отрицательные величины значений xExt и yExt игнорируются; используется только отношение.
hMF
Идентифицирует метафайл в памяти.

Смотри также
SetClipboardData

Размещение и совместимость METAFILEPICT

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека
Заголовочный файл			wingdi.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.3 - Сообщения Буфера Обмена

С буфером обмена используются ниже следующие сообщения: WM_ASKCBFORMATNAME
WM_CHANGECBCHAIN
WM_CLEAR
WM_COPY
WM_CUT
WM_DESTROYCLIPBOARD
WM_DRAWCLIPBOARD
WM_HSCROLLCLIPBOARD
WM_PAINTCLIPBOARD
WM_PASTE
WM_RENDERALLFORMATS
WM_RENDERFORMAT
WM_SIZECLIPBOARD
WM_VSCROLLCLIPBOARD


3.18.3.1 - Сообщение WM_ASKCBFORMATNAME

Сообщение WM_ASKCBFORMATNAME посылается владельцу буфера обмена окном просмотра буфера обмена, чтобы запросить имя формата CF_OWNERDISPLAY.

Синтаксис

WM_ASKCBFORMATNAME
cchName = (DWORD) wParam                	// размер буфера
lpszFormatName = (LPTSTR) lParam    		// буфер, который принимает название формата

Параметры
cchName
Значение wParam. Определяет размер, в символах, буфера, указанного параметром lpszFormatName.
lpszFormatName
Значение lParam. Указывает на буфер, который должен принять название формата буфера обмена.

Возвращаемые значения
Если приложение обрабатывает это сообщение, оно возвращает нуль.

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

Размещение и совместимость WM_ASKCBFORMATNAME

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.3.2 - Сообщение WM_CHANGECBCHAIN

Сообщение WM_CHANGECBCHAIN посылается к первому окну в цепочке окон просмотра буфера обмена, когда окно удаляется из цепочки.

Синтаксис

WM_CHANGECBCHAIN
hwndRemove = (HWND) wParam;	 		// дескриптор удаляемого окна
hwndNext = (HWND) lParam;             	// дескриптор следующего окна в цепочке

Параметры
hwndRemove
Значение wParam. Идентифицирует окно, удаляемое из цепочки окон просмотра буфера обмена. hwndNext
Значение lParam. Идентифицирует следующее окно в цепочке после удаляемого окна. Этот параметр имеет значение ПУСТО (NULL), если удаляемое окно - последнее окно в цепочке.

Возвращаемые значения
Если программа обрабатывает это сообщение, она должна возвратить ноль.

Замечания
Каждое окно просмотра буфера обмена сохраняет дескриптор следующего окна в цепочке окон просмотра. Первоначально, этот дескриптор - возвращаемое значение функции SetClipboardViewer.
Когда окно просмотра буфера обмена принимает сообщение WM_CHANGECBCHAIN, оно должно вызвать функцию SendMessage, чтобы передать сообщение следующему окну в цепочке, если следующее окно не удаляемое окно. В этом случае, окно просмотра буфера обмена должно сохранить дескриптор, заданный параметром hwndNext как следующее окно в цепочке.

Смотри также
SendMessage, SetClipboardViewer

Размещение и совместимость WM_CHANGECBCHAIN

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.3.3 - Сообщение WM_CLEAR

Прикладная программа передает сообщение WM_CLEAR средствам редактирования или комбинированному блоку, чтобы удалить (очистить) текущий выбор, если таковой вообще имеется, из окна редактирования.

Синтаксис

WM_CLEAR
wParam = 0; 	// не используется, должно быть ноль
lParam = 0;   	// не используется, должно быть ноль

Параметры
У этого сообщения нет параметров.

Возвращаемые значения
Это сообщение не возвращает значений.

Замечания
Удаление, выполняемое в соответствии с сообщением WM_CLEAR, может быть отменено путем передачи сообщения EM_UNDO окну редактирования.
Чтобы удалить текущий выбор и поместить удаляемое содержимое в буфер обмена, используют сообщение WM_CUT.
Когда сообщение WM_CLEAR посылается комбинированному блоку, оно обрабатывается его средствами редактирования. Это сообщение не оказывает никакого влияния, когда оно послано комбинированному блоку со стилем CBS_DROPDOWNLIST.

Смотри также
EM_UNDO, WM_COPY, WM_CUT, WM_PASTE

Размещение и совместимость WM_CLEAR

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.3.4 - Сообщение WM_COPY

Прикладная программа посылает сообщение WM_COPY окнам редактирования или комбинированному блоку, чтобы копировать текущий выбор в буфер обмена в формате CF_TEXT.

Синтаксис

WM_COPY
wParam = 0;  	// не используется, должно быть ноль
lParam = 0;    	// не используется, должно быть ноль

Параметры
У этого сообщения нет параметров.

Возвращаемые значения
Это сообщение не возвращает значений.

Замечания
Когда сообщение WM_COPY посылается комбинированному блоку, оно обрабатывается его средствами редактирования. Это сообщение не оказывает никакого влияния, когда послано комбинированному блоку со стилем CBS_DROPDOWNLIST.

Смотри также
WM_CLEAR, WM_CUT, WM_PASTE

Размещение и совместимость WM_COPY

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.3.5 - Сообщение WM_CUT

Прикладная программа передает сообщение WM_CUT средству редактирования или комбинированному блоку, чтобы удалить (вырезать) текущий выбор, если таковой имеется в средстве редактирования, а удаленный текст скопировать в буфер обмена в формате CF_TEXT.

Синтаксис

WM_CUT
wParam = 0; 	// не используется; должен быть ноль
lParam = 0;   	// не используется; должен быть ноль

Параметры
У этого сообщения нет параметров.

Возвращаемые значения
У этого сообщения нет возвращаемых значений

Замечания
Удаление, выполненное в соответствии с сообщением WM_CUT может быть отменено, при помощи передачи средству редактирования сообщение EM_UNDO.
Чтобы удалить текущий выбор без помещения удаленного текста в буфер обмена, используйте сообщение WM_CLEAR.
Когда сообщение WM_CUT передано комбинированному блоку, он обрабатывает его средствами редактирования. Это сообщение не оказывает никакого влияния, когда передается комбинированному блоку со стилем CBS_DROPDOWNLIST.

Смотри также
EM_UNDO, WM_CLEAR, WM_COPY, WM_PASTE

Размещение и совместимость WM_CUT

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.3.6 - Сообщение WM_DESTROYCLIPBOARD

Сообщение WM_DESTROYCLIPBOARD посылается владельцу буфера обмена, когда обращение к функции EmptyClipboard очищает буфер обмена.

Синтаксис
WM_DESTROYCLIPBOARD

Параметры
У этого сообщения нет параметров.

Возвращаемые значения
Если приложение обрабатывает это сообщение, оно должно возвратить ноль.

Смотри также
EmptyClipboard

Размещение и совместимость WM_DESTROYCLIPBOARD

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.3.7 - Сообщение WM_DRAWCLIPBOARD

Сообщение WM_DRAWCLIPBOARD посылается первому окну в цепочке окон просмотра буфера обмена, когда изменяется содержание буфера обмена. Это дает возможность окну просмотра буфера обмена отобразить его новое содержание.

Синтаксис

WM_DRAWCLIPBOARD

Параметры
У этого сообщения нет параметров.

Замечания
Только окна просмотра буфера обмена принимают это сообщение. Они - окна, которые были добавлены к цепочке окон просмотра буфера обмена, при помощи использования функции SetClipboardViewer.
Каждое окно, которое принимает сообщение WM_DRAWCLIPBOARD, должно вызвать функцию SendMessage, чтобы передать сообщение следующему окну в цепочке окон просмотра буфера обмена. Дескриптор следующего окна в цепочке возвращается в SetClipboardViewer и может изменяться в ответ на сообщение WM_CHANGECBCHAIN.

Смотри также
SendMessage, SetClipboardViewer, WM_CHANGECBCHAIN

Размещение и совместимость WM_DRAWCLIPBOARD

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.3.8 - Сообщение WM_HSCROLLCLIPBOARD

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

Синтаксис

WM_HSCROLLCLIPBOARD
hwndViewer = (HWND) wParam;			// дескриптор окна просмотра буфера обмена
nScrollCode = (int) LOWORD(lParam);		// код полосы прокрутки
nPos = (int) HIWORD(lParam);		// позиция бегунка

Параметры
hwndViewer
Значение wParam. Идентифицирует окно просмотра буфера обмена.
nScrollCode
Значение младшего байта слова lParam. Устанавливает событие полосы прокрутки. Этот параметр может быть одним из следующих значений:

  • SB_BOTTOM - Прокрутка вниз вправо.
  • SB_ENDSCROLL - Конец прокрутки.
  • SB_LINEDOWN - Прокрутка на одну строку вниз.
  • SB_LINEUP - Прокрутка на одну сроку вверх.
  • SB_PAGEDOWN - Прокрутка на одну страницу вниз.
  • SB_PAGEUP - Прокрутка на одну страницу вверх.
  • SB_THUMBPOSITION - Прокрутка в начальную позицию. Текущая позиция установлена параметром nPos.
  • SB_TOP - Прокрутка вверх влево.

nPos
Значение старшего слова lParam. Устанавливает текущую позицию бегунка, если параметр nScrollCode - SB_THUMBPOSITION; иначе, nPos параметр не используется.

Возвращаемые значения
Если приложение обрабатывает это сообщение, оно должно возвратить ноль.

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

Смотри также
ScrollWindow

Размещение и совместимость WM_HSCROLLCLIPBOARD

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.3.9 - Сообщение WM_PAINTCLIPBOARD

Сообщение WM_PAINTCLIPBOARD посылается владельцу буфера обмена окном просмотра, когда буфер обмена содержит данные в формате CF_OWNERDISPLAY и рабочая область окна просмотра буфера обмена нуждается в перерисовке.

Синтаксис

WM_PAINTCLIPBOARD
hwndViewer = (HWND) wParam;     	// дескриптор окна просмотра буфера обмена
hglbPs = (HGLOBAL) lParam;         	// дескриптор объекта PAINTSTRUCT

Параметры
hwndViewer
Значение wParam. Идентифицирует окно просмотра буфера обмена.
hglbPs
Значение lParam. Идентифицирует глобальный объект DDESHARE, который содержит структуру PAINTSTRUCT. Структура определяет часть рабочей области для прорисовки.

Возвращаемые значения
Если приложение обрабатывает это сообщение, оно возвращает нуль.

Замечания
Чтобы определить, нужно ли перерисовывать всю рабочую область или только ее часть, владелец буфера обмена сравнивает размеры области прорисовки, которые даны в элементе rcpaint структуры PAINTSTRUCT, с размерами, данным в самом свежем сообщении WM_SIZECLIPBOARD.
Владелец буфера обмена должен использовать функцию GlobalLock, чтобы блокировать память, которая содержит структуру PAINTSTRUCT. Перед возвратом из функции, владелец буфера обмена должен разблокировать эту память, используя функцию GlobalUnlock.

Смотри также
GlobalLock, GlobalUnlock, PAINTSTRUCT, WM_SIZECLIPBOARD

Размещение и совместимость WM_PAINTCLIPBOARD

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.3.10 - Сообщение WM_PASTE

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

Синтаксис

WM_PASTE
wParam = 0; 	// не используется, должно быть нуль
lParam = 0;   	// не используется, должно быть нуль

Параметры
У этого сообщения нет параметров.

Возвращаемые значения
Это сообщение не возвращает значение.

Замечания
Когда сообщение WM_PASTE посылается комбинированному блоку, оно обрабатывается его средствами редактирования. Это сообщение не имеет никакого влияния, когда послано комбинированному блоку со стилем CBS_DROPDOWNLIST.
Смотри также
WM_CLEAR, WM_COPY, WM_CUT

Размещение и совместимость WM_PASTE

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.3.11 - Сообщение WM_RENDERALLFORMATS

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

Синтаксис
WM_RENDERALLFORMATS

Параметры
У этого сообщения нет параметров.

Возвращаемые значения
Если приложение обрабатывает это сообщение, оно возвращает нуль.

Замечания
При ответе на сообщение WM_RENDERALLFORMATS, владелец буфера обмена перед вызовом функции SetClipboardData должен вызвать функции OpenClipboard и EmptyClipboard.
Когда прикладная программа возвращается из функции, система удаляет любые не представленные форматы из списка доступных форматов буфера обмена. За информацией об отложенной записи обратитесь к статье о функции SetClipboardData.

Смотри также
EmptyClipboard, OpenClipboard, SetClipboardData, WM_RENDERFORMAT

Размещение и совместимость WM_RENDERALLFORMATS

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.3.12 - Сообщение WM_RENDERFORMAT

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

Синтаксис

WM_RENDERFORMAT
uFormat = (UINT) wParam;    // формат буфера обмена

Параметры
uFormat
Устанавливает формат буфера обмена, который будет представлен.

Возвращаемые значения
Если приложение обрабатывает это сообщение, оно возвращает нуль.

Замечания
При ответе на сообщение WM_RENDERFORMAT, владелец буфера обмена не должен открывать буфер обмена перед вызовом функции SetClipboardData.

Смотри также
SetClipboardData, WM_RENDERALLFORMATS

Размещение и совместимость WM_RENDERFORMAT

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.3.13 - Сообщение WM_SIZECLIPBOARD

Сообщение WM_SIZECLIPBOARD посылается владельцу буфера обмена окном просмотра, когда буфер обмена содержит данные в формате CF_OWNERDISPLAY, а рабочая область окна просмотра буфера обмена изменила размеры.

Синтаксис

WM_SIZECLIPBOARD
hwndViewer = (HWND) wParam;  	// дескриптор окна просмотра буфера обмена
hglbRc = (HGLOBAL) lParam;      	// дескриптор объекта структуры RECT

Параметры
hwndViewer
Значение wParam. Идентифицирует окно окна просмотра буфера обмена.
hglbRc
Значение lParam. Идентифицирует глобальный объект в памяти, который содержит структуру RECT. Структура определяет новые габариты рабочей области окна просмотра буфера обмена.

Замечания
Когда окно просмотра буфера обмена собирается быть разрушенным или измененным, сообщение WM_SIZECLIPBOARD посылается с нулевым прямоугольником (0, 0, 0, 0) в качестве нового размера. Это позволяет владельцу буфера обмена освободить свои ресурсы дисплея.
Владелец буфера обмена должен использовать функцию GlobalLock, чтобы блокировать объект в памяти, который содержит RECT. Перед возвратом из функции, владелец буфера обмена должен разблокировать объект, используя функцию GlobalUnlock.

Смотри также
GlobalLock, GlobalUnlock, RECT

Размещение и совместимость WM_SIZECLIPBOARD

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


3.18.3.13 - Сообщение WM_VSCROLLCLIPBOARD

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

Синтаксис

WM_VSCROLLCLIPBOARD
hwndViewer = (HWND) wParam;                 	// дескриптор окна просмотра буфера обмена
nScrollCode = (int) LOWORD(lParam); 		// код полосы прокрутки
nPos = (int) HIWORD(lParam);                   	// позиция бегунка

Параметры
hwndViewer
Значение wParam. Идентифицирует окно просмотра буфера обмена.
nScrollCode
Значение младшего байта слова lParam. Определяет событие полосы прокрутки. Этот параметр может быть одним из следующих значений:

  • SB_BOTTOM - Прокрутка вниз вправо. (Речь идет о каретке)
  • SB_ENDSCROLL - Конец прокрутки.
  • SB_LINEDOWN - Прокрутка на одну строку вниз.
  • SB_LINEUP - Прокрутка на одну сроку вверх.
  • SB_PAGEDOWN - Прокрутка на одну страницу вниз.
  • SB_PAGEUP - Прокрутка на одну страницу вверх.
  • SB_THUMBPOSITION - Прокрутка в начальную позицию. Текущая позиция установлена параметром nPos.
  • SB_TOP - Прокрутка вверх влево.

nPos
Значение старшего слова lParam. Определяет текущую позицию бегунка, если nScrollCode параметр SB_THUMBPOSITION; иначе, параметр nPos не используется.

Возвращаемые значения
Если приложение обрабатывает это сообщение, оно возвращает нуль.

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

Смотри также
ScrollWindow

Размещение и совместимость WM_VSCROLLCLIPBOARD

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется
Предыдущий Шаг


Глава 6 - Диалоговые окна

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

Следующий Шаг


6.1 - О диалоговых окнах

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

Windows предоставляет также много предопределенных, или "стандартных" диалоговых окон, которые поддерживают команды, типа Открыть файл (File Open)и Печатать файл (File Print). Прикладные программы, которые используют эти команды, должны использовать эти стандартные диалоговые окна, чтобы запрашивать от пользователя ввода тех же самых данных, независимо от типа прикладной программы, команды которой исполняются. Для получения дополнительной информации о использовании стандартных блоков диалога в ваших прикладных программах, см. главу Библиотека стандартных диалоговых окон.


6.2 - Когда используется диалоговое окно

Большинство прикладных программ использует диалоговые окна, чтобы запросить дополнительную информацию для команд, которые требуют ввода данных от пользователя. Использование диалогового окна - единственное рекомендованное средство для прикладной программы, чтобы получить ввод данных. Например, команда Открыть файл (File Open) требует для открытия название файла, так что прикладная программа должна использовать блок диалога, чтобы запросить у пользователя его имя. В таких случаях, прикладная программа создает диалоговое окно, где пользователь выбирает команду и немедленно уничтожает его окно после того, как пользователь дает информацию.

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

Чтобы поддерживать использование диалоговых окон различными прикладными программами, Windows предоставляет два типа блока диалога: модальное и немодальное. Модальное диалоговое окно (modal dialog box) требует, чтобы пользователь предоставил информацию или отменил диалоговое окно перед разрешением продолжения работы прикладной программе. Приложения используют модальные блоки диалога вместе с командами, которые требуют дополнительной информации прежде, чем они могут продолжать действовать. Немодальное диалоговое окно (modeless dialog box) позволяет пользователю предоставлять информацию и возвращаться к предыдущей задаче без закрытия блока диалога. Модальные диалоговые окна более простые для управления, чем немодальные блоки диалога, потому что они создаются, исполняют свою задачу и разрушаются вызовом единственной функции.

Чтобы создать или модальное или немодальное диалоговое окно, прикладная программа должна снабдить блок диалога шаблоном, чтобы описать стиль и содержание диалогового окна; приложение должно также снабдить блок диалога процедурой, чтобы выполнять задачи. Шаблон диалогового окна (dialog box template) - бинарное описание блока диалога и элементов управления, которое оно содержит. Разработчик может создать этот шаблон как ресурс, который будет загружен из исполняемого файла прикладной программы, или создать его в памяти, пока выполняется прикладная программа. Процедура диалогового окна (dialog box procedure) - определяемая программой функция повторного вызова, которую Windows вызывает, когда операционная система получает ввод данных для диалогового окна или задачу для выполнения в блоке диалога. Хотя процедура диалогового окна подобна оконной процедуре, у неё не те же самые обязанности.

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

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


6.3 - Окно владелец

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

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

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

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


6.4 - Окна сообщений

Окно сообщения (message box) - специальное диалоговое окно, которое прикладная программа может использовать, чтобы показывать сообщения и приглашение для обычного ввода данных. Окно сообщения обычно содержит текстовое сообщение и одну или большее количество кнопок. Прикладная программа создает окно сообщения, используя функцию MessageBox или MessageBoxEx, определяя текст, число и типы кнопок для показа. Функция MessageBoxEx позволяет Вам также установить язык, который надо использовать для текста любых предопределенных командных кнопок в окне сообщения.

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

Окно сообщения - модальное диалоговое окно и Windows создает его, используя те же самые внутренние функции, что и DialogBox. Если прикладная программа определяет окно владельца при вызове функции MessageBox или MessageBoxEx, Windows отключает владельца. Когда диалоговое окно создается, при помощи определения значение MB_TASKMODAL, приложение может также дать указание Windows, чтобы отключить все окна верхнего уровня, принадлежащие к текущей задаче.

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


6.5 - Модальные диалоговые окна

Модальное диалоговое окно должно быть выскакивающим окном, имеющим Системное меню, строку заголовка, и жирную рамку; то есть, шаблон блока диалога должен установить стили WS_POPUP, WS_SYSMENU, WS_CAPTION и DS_MODALFRAME. Хотя прикладная программа может определять и стиль WS_VISIBLE, Windows всегда показывает модальное диалоговое окно независимо от того, устанавливает ли шаблон диалогового окна стиль WS_VISIBLE. Приложение не должно создавать модальное диалоговое окно, имеющее стиль WS_CHILD. Модальный блок диалога с этим стилем отключает сам себя, не допуская какого-либо последующего ввода данных из связанной с ним прикладной программы.

Прикладная программа создает модальное диалоговое окно, используя или функцию DialogBox или DialogBoxIndirect. DialogBox требует названия или идентификатора ресурса, содержащего шаблон блока диалога; DialogBoxIndirect требует дескриптора объекта памяти, содержащего шаблон диалогового окна. Функции DialogBoxParam и DialogBoxIndirectParam также создают модальные блоки диалога; они идентичны выше упомянутым функциям, но, когда диалоговое окно создается, передают заданный параметр для процедуры блока диалога.

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

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

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

Чтобы обрабатывать сообщения для модального диалогового окна, Windows запускает его собственный цикл сообщений, принимая временное управление очередью сообщений для всей прикладной программы. Когда Windows извлекает сообщение, которое явно не для блока диалога, она (ОС) посылает сообщение соответствующему окну. Если оперативная система извлекает сообщение WM_QUIT, то она передает сообщение назад в очередь сообщения прикладной программы так, чтобы главный цикл сообщений прикладной программы мог, в конечном счете, отыскать это сообщение.

Примечание: здесь и далее ОС – оперативная система.

Windows передает сообщение WM_ENTERIDLE владельцу окна всякий раз, когда пустеет очередь сообщений прикладной программы. Приложение может использовать это сообщение, чтобы выполнить фоновую задачу, пока диалоговое окно остается на экране. Когда прикладная программа использует это сообщение таким способом, она должна часто уступать управление (например, когда используется функция PeekMessage) таким образом, чтобы модальное диалоговое окно могло принять любой ввод данных от пользователя. Чтобы не допустить передачу модальным диалоговым окном сообщения WM_ENTERIDLE, прикладная программа, когда создается диалоговое окно, может определить стиль DS_NOIDLEMSG.

Прикладная программа разрушает модальное диалоговое окно, используя функцию EndDialog. В большинстве случаев, процедура диалогового окна вызывает EndDialog тогда, когда пользователь выбирает из системного меню блака диалога команду Закрыть (Close), или выбирает в диалоговом окне кнопку ОК или Отменить (Cancel). Блок диалога может возвратить значение через функцию DialogBox (или другие создающие функции), определяя значение при вызове функции EndDialog. Windows возвращает это значение после разрушения диалогового окна. Большинство прикладных программ использует это возвращаемое значение, чтобы определить, успешно ли завершил блок диалога свою задачу или она была отменена пользователем. Windows не возвращает управление из функции, которая создает блок диалога до тех пор, пока процедура диалогового окна не вызовет функцию EndDialog.


6.6 - Немодальные диалоговые окна

Немодальные диалоговые окна должны быть выскакивающими окнами, у которых есть Системное меню, строка заголовка и тонкая рамка; то есть, шаблон блока диалога должен установить стили WS_POPUP, WS_CAPTION, WS_BORDER и WS_SYSMENU. Windows автоматически не показывает диалоговое окно, если в шаблоне не установлен стиль WS_VISIBLE.

Прикладная программа создает немодальное диалоговое окно, используя функции или CreateDialog, или CreateDialogIndirect. CreateDialog требует названия или идентификатора ресурса, содержащего шаблон блока диалога; CreateDialogIndirect требует дескриптора объекта памяти, содержащего шаблон диалогового окна. Две другие функции, CreateDialogParam и CreateDialogIndirectParam, тоже создают немодальное диалоговое окно; функции, когда окно создается, посылают заданный параметр в процедуру блока диалога.

CreateDialog и другие создающие функции возвращают значение дескриптора родительского окна диалоговому окну. Прикладная программа и процедура блока диалога могут использовать этот дескриптор для управления диалоговым окном. Например, если в шаблоне блока диалога не определен стиль WS_VISIBLE, то приложение может показать диалоговое окно путем передачи дескриптора родительского окна в функцию ShowWindow.

Немодальное диалоговое окно не блокирует окно владельца, не передает какие-либо сообщения для него. Когда создается блок диалога, Windows делает его активным окном, однако пользователь или прикладная программа могут в любое время заменить активное окно. Если диалоговое окно становиться неактивным, оно остается в Z-последовательности выше окна владельца, даже если окно владелец активное.

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

Немодальное диалоговое окно не может возвратить значение в прикладную программу, как это делает модальное диалоговое окно, однако процедура блока диалога может передать информацию в окно владельца, используя функцию SendMessage.

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

DestroyWindow аннулирует дескриптор родительского окна для диалогового окна, так что любой более поздний вызов функции, которая использует этот дескриптор, возвратит значение ошибки. Чтобы не допустить ошибки, процедура диалогового окна должна оповестить владельца, что блок диалога был разрушен. Многие прикладные программы сохраняют глобальную переменную, которая содержит дескриптор для диалогового окна. Когда процедура блока диалога разрушает диалоговое окно, она также и глобальную переменную устанавливает в значение ПУСТО (NULL), показывая, что диалоговое окно больше не действует.

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


6.7 - Шаблон диалогового окна

Шаблон диалогового окна (dialog box template) - двоичные данные, которые описываю блок диалога, определяя высоту, ширину, стиль и содержащиеся в нем элементы управления. Чтобы создать диалоговое окно, Windows или загружает шаблон блока диалога из ресурса исполняемого файла приложения или использует шаблон, передав его в глобальную память прикладной программы. И в том и в другом случае, прикладная программа должна получить шаблон, когда создается диалоговое окно.

Разработчик, создавая ресурсы шаблонов, использует компилятор ресурсов или редактор диалогового окна. Компилятор ресурсов преобразует текстовое описание в ресурс в двоичном коде, а редактор диалогового окна сохраняет в интерактивном режиме диалоговое окно, как ресурс в двоичном коде.

Примечание: Объяснение, как создать ресурс шаблона и добавить его в исполняемый файл прикладной программы, за пределами зоны внимания этого краткого обзора. За большей информацией о создании ресурсов шаблонов и дополнение ими исполняемого файла, обратитесь к документации, предоставленной вам вместе с инструментами разработки программ.

Чтобы создать диалоговое окно без использования ресурсов шаблонов, вы должны создать шаблон в в памяти и переслать его в функцию CreateDialogIndirectParam или DialogBoxIndirectParam или в макрокоманду CreateDialogIndirect или DialogBoxIndirect.

Шаблон диалогового окна в памяти состоит из заголовка, который описывает блок диалога, сопровождаемого одним или большим количеством дополнительных блоков данных, которые описывают каждый элемент управления в диалоговом окне. Шаблон может использовать или стандартный или расширенный формат. В стандартном шаблоне заголовок - структура DLGTEMPLATE, сопровождаемая дополнительными массивами переменной длины; а данные для каждого элемента управления состоят из структуры DLGITEMTEMPLATE, сопровождаемой дополнительными массивами переменной длины. В шаблоне расширенного диалогового окна, заголовок использует формат DLGTEMPLATEEX, а для определений элементов управлений используется формат DLGITEMTEMPLATEEX.

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

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


6.8 - Стили шаблона диалогового окна

Каждый шаблон диалогового окна определяет комбинацию стилей, значения которых задают внешний вид и свойства блока диалога. Значениями стиля могут быть стили окна, такие как WS_POPUP и WS_SYSMENU и стили диалогового окна, такие как DS_MODALFRAME. Число и типы стилей зависят от типа и предназначения блока диалога.

Когда создается диалоговое окно, Windows передает все стили окна, полученные из шаблона, в функцию CreateWindowEx. Windows может передать один или большее количество стилей, которые зависимы от стилей, данных в диалоговом окне. Например, когда, при создании блока диалога, шаблон определяет стиль DS_MODALFRAME, Windows использует WS_EX_DLGMODALFRAME. Когда шаблон устанавливает стиль DS_SYSMODAL, Windows использует WS_EX_TOPMOST. Все другие стили блока диалога находятся под влиянием того, как Windows управляет диалоговым окном.

Большинство диалоговых окон, выскакивающие окна, в которых есть системное меню и строка заголовка. Поэтому, в обычном шаблоне определяют стили WS_POPUP, WS_SYSMENU и WS_CAPTION. Шаблон также определяет стиль рамки: WS_BORDER для не модальных диалоговых окон и DS_MODALFRAME для модальных блоков диалога. Шаблон может определить тип окна, отличающийся от выскакивающего (например, такой как WS_OVERLAPPED), если он создает пользовательское окно взамен диалогового окна.

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

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

Когда используется стиль DS_ABSALIGN, Windows трактует размеры диалогового окна, как экранные координаты; при использовании стиля DS_SETFONT, Windows, вместо системного шрифта, использует установленный шрифт, чтобы прописывать текст в рабочей области и в элементах управления диалогового окна; стильDS_NOIDLEMSG препятствует модальному блоку диалога передавать сообщения WM_ENTERIDLE в окно владельца. Эти стили описаны более детально в разделах и статьях ниже.

Стиль DS_LOCALEDIT для прикладных программ, базирующихся на Win32, не применяется.

Диалоговые окна со стилем DS_SYSMODAL, принимают стиль окна WS_EX_TOPMOST, но никаких других специальных свойств или стилей; это означает, что пользователь все еще имеет доступ к другим окнам на рабочем столе даже притом, что блок диалога DS_SYSMODAL может быть показано.


6.9 - Размеры диалогового окна

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

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

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

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


6.10 - Элементы управления диалогового окна

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

Для каждого элемента управления шаблон устанавливает значения стиля, которые определяют внешний вид и действие элемента управления. Каждый элемент управления - это дочернее окно, и поэтому должно иметь стиль WS_CHILD. Чтобы гарантировать, что элемент управления видимый, когда отображается диалоговое окно, каждый элемент управления должен иметь также стиль WS_VISIBLE. Другие, обычно используемые стили окна, - это WS_BORDER для элементов управления, которые не обязательно имеют рамки, WS_DISABLED для элементов управления, которые должны быть отключены, когда создается первоначальное диалоговое окно и WS_TABSTOP и WS_GROUP для элементов управления, к которым можно обращаться, используя клавиатуру. Стили WS_TABSTOP и WS_GROUP используются совместно с диалоговым интерфейсом клавиатуры, описанном позже в этом разделе.

Шаблон может также установить стили элементов управления, специфические для класса элементов управления окна. Например, шаблон, который определяет кнопку управления, должен дать кнопке управления стиль, такой как BS_PUSHBUTTON или BS_CHECKBOX. Windows передает стиль элемента управления в управляющую окном процедуру через посредство сообщения WM_CREATE, разрешая процедуре приспосабливать внешний вид и работу элемента управления.

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

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

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

Чтобы разрешить пользователю закрыть диалоговое окно, шаблон должен установить, по крайней мере, одну командную кнопку и присвоить ей идентификатор управления IDCANCEL. Чтобы разрешить пользователю выбор между завершающей и отменяющей командами, связанными с диалоговым окном, шаблон должен установить две командные кнопки с надписями ОК и Отменить (Cancel) и управляющими идентификаторами IDOK и IDCANCEL, соответственно.

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


6.11 - Системное меню

Windows снабжает диалоговое окно Системным меню, в том случае, если шаблон определяет стиль WS_SYSMENU. Чтобы не допустить ввода несоответствующей команды, Windows автоматически блокирует работу всех команд в меню, исключая команды Переместить (Move) и Закрыть (Close). Пользователь может использовать команду Переместить (Move) для перемещения диалогового окна. Если пользователь выбирает команду Закрыть (Close), Windows в процедуру диалогового окна передает сообщение WM_COMMAND с параметром wParam, установленным в IDCANCEL. Это то же самое сообщение, которое посылается кнопкой Отменить (Cancel), когда пользователь выбирает её. Рекомендуемым действием для этого сообщения является закрыть окно диалога и отменить запрошенную команду или задачу.

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


6.12 - Диалоговое окно Шрифты (Fonts)

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

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

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


6.13 - Шаблоны в памяти

Шаблон диалогового окна в памяти состоит из заголовка, описывающего диалоговое окно, который сопровождается одним или большим числом дополнительных блоков данных, которые описывают каждый из элементов управления в блоке диалога. Шаблон может использовать или стандартный или расширенный формат. В стандартном шаблоне, заголовочный файл – это структура DLGTEMPLATE, сопровождаемая дополнительными массивами переменной длины. Данные для каждого элемента управления состоят из структуры DLGITEMTEMPLATE, сопровождаемой дополнительными массивами переменной длины. В расширенном шаблоне диалогового окна, заголовочный файл использует формат DLGTEMPLATEEX и определения элементов управления, использующие формат DLGITEMTEMPLATEEX.

Чтобы отличить стандартный шаблон от расширенного, проверьте первые 16 битов шаблона диалогового окна. В расширенном шаблоне первое слово(WORD). – 0хFFFF; любое другое значение показывает, что это стандартный шаблон.

Если вы создаете шаблон блока диалога в памяти, вы должны гарантировать, что каждый элемент управления DLGITEMTEMPLATE или DLGITEMTEMPLATEEX выровнен по границе ДВОЙНОГО СЛОВА (DWORD). Кроме того, любые данные создания, которые следует за определением элемента управления, должны быть выровнены по границе ДВОЙНОГО СЛОВА (DWORD). Все другие массивы переменной длины в шаблоне диалогового окна должны быть выровнены по границам СЛОВА (WORD).

Заголовок шаблона.

В обоих шаблонах диалогового окна, стандартном и расширенном, заголовок включает в себя следующую общую информацию:

  1. Размещение и габариты диалогового окна.
  2. Стили окна и блока диалога для диалогового окна.
  3. Число элементов управления диалогового окна. Это значение обуславливается числом элементов управления DLGITEMTEMPLATE или DLGITEMTEMPLATEEX, которые определены в шаблоне.
  4. Необязательный ресурс меню для диалогового окна. Шаблон может указывать, что блок диалога не имеет меню, или он может установить значения по порядку, или строку Unicode с нуль-терминатором в конце, которые идентифицируют ресурс меню в исполняемом файле.
  5. Класс окна диалогового окна. Это может быть или предопределенный класс диалогового окна, или значения по порядку, или строка Unicode с нуль-терминатором в конце, которые идентифицируют зарегистрированный класс окна.
  6. Строка Unicode с нуль-терминатором в конце, которая определяет заголовок окна блока диалога. Если строка пустая, то поле заголовка диалогового окна не заполняется. Если в блоке диалога не определен стиль WS_CAPTION, система устанавливает заголовок, определенный в строке, но не показывает его.
  7. Если диалоговое окно имеет стиль DS_SETFONT, заголовок устанавливает размер в пунктах и название шрифта, который используется для текста в рабочей области и элементах управления блока диалога.

В расширенном шаблоне заголовок DLGTEMPLATEEX определяет к тому же следующую дополнительную информацию:

  1. Идентификатор контекста справки, который идентифицирует окно блока диалога, когда система посылает сообщение WM_HELP.
  2. Если в диалоговом окне определен стиль DS_SETFONT, заголовок устанавливает толщину шрифта и является ли шрифт курсивным (italic).

Определения элементов управления

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

И в стандартном, и в расширенном шаблонах, определение элемента управления включает в себя следующую информацию:

  1. Размещение и габариты элемента управления.
  2. Стили окна и элемента управления для средств управления.
  3. Идентификатор элемента управления.
  4. Класс окна элемента управления. Это может быть или порядковые значения предопределенного класса системы, или строка Unicode с нуль-терминатором на конце, которая определяет имя зарегистрированного класса окна.
  5. Cтрока Unicode с нуль-терминатором на конце, которая определяет начальный текст элемента управления, или перечисление значений, которые идентифицируют ресурс, типа пиктограммы, в исполняемом файле.
  6. Необязательный переменной длины блок данных создания. Когда система создает элемент управления, она передает указатель на эти данные в параметре lParam сообщения WM_CREATE, которое передается в элемент управления.

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


6.14 - Процедура диалогового окна

Процедура диалогового окна подобна оконной процедуре, в которую Windows посылает сообщения, чтобы процедура, когда она имеет информацию, задала или завершила задачи. В отличие от оконной процедуры, процедура диалогового окна никогда не вызывает функцию DefWindowProc. Вместо этого, она возвращает Булево значение ИСТИНА (TRUE), если она обрабатывает сообщение или ЛОЖЬ(FALSE), если она этого не делает.

Каждая процедура диалогового окна имеет следующую форму:

BOOL APIENTRY DlgProc(hwndDlg, message, wParam, lParam)
HWND hwndDlg;
UINT message;
WPARAM wParam;
LPARAM lParam;
{
    switch (message) {

         // Здесь располагаются case-операторы по обработке сообщений.

         default:
             return FALSE;
    }
}

Параметры процедуры служат тем же самым целям, что и в оконной процедуре, при помощи параметра hwndDlg, принимают дескриптор окна блока диалога.

Большинство процедур диалогового окна обрабатывает сообщение WM_INITDIALOG и сообщения WM_COMMAND, передаваемые элементом управления, но обрабатывает немногие, если имеются какие-либо другие сообщения. Если процедура диалогового окна не обрабатывает сообщение, она должна возвратить значение ЛОЖЬ(FALSE), чтобы заставить Windows обработать сообщения внутри себя. Единственное исключение из этого правила - сообщение WM_INITDIALOG. Процедура диалогового окна должна возвратить значение ИСТИНА (TRUE), чтобы направить в Windows сообщениеWM_INITDIALOG для дальнейшей обработки. В любом случае, процедура не должна вызвать DefWindowProc.


6.15 - Сообщение WM_INITDIALOG

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

Процедура может инициализировать элементы управления при помощи использования функций, таких как SetDlgItemText и CheckDlgButton. Поскольку элементы управления тоже окна, процедура может также манипулировать ими при помощи использования функций управления окном, такими как EnableWindow и SetFocus. Процедура может извлечь информацию о дескрипторе окна элемента управления, используя функцию GetDlgItem.

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

Если прикладная программа создает диалоговое окно при помощи одной из функций DialogBoxParam, DialogBoxIndirectParam, CreateDialogParam или CreateDialogIndirectParam, параметр lParam сообщения WM_INITDIALOG содержит дополнительный параметр, передаваемый в функцию. Прикладные программы обычно и wParam. Если элемент управления не предназначен для принятия по умолчанию фокуса, он может установить фокус в элемент управления, который предназначен для этого, используя функцию SetFocus. Если процедура устанавливает фокус ввода данных, она должна возвратить значение ЛОЖЬ FALSE), чтобы не допустить установку фокуса Windows по умолчанию. По умолчанию, фокус ввода данных получает тот элемент управления, который всегда дается первым в шаблоне, он видимый, его работа не заблокирована и он имеет стиль WS_TABSTOP. Если такого элемента управления не существует, Windows устанавливает по умолчанию фокус ввода данных в первый элемент управления шаблона.


6.16 - Сообщение WM_COMMAND

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

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

Процедура диалогового окна должна отслеживать и обрабатывать уведомительные сообщения. В частности, процедура должна обрабатывать сообщения, имеющие идентификаторы IDOK или IDCANCEL; эти сообщения представляют запрос пользователя на закрытие диалогового окна. Процедура должна закрыть блок диалога при помощи функции EndDialog для модального блока диалога и функцию DestroyWindow для не модального диалогового окна.

Windows также передает сообщение WM_COMMAND процедуре диалогового окна, если блок диалога имеет меню, такое как Системное меню, а пользователь выбирает команду. В частности, Windows передает сообщение WM_COMMAND с параметром wParam, установленным в IDCANCEL всякий раз, когда пользователь выбирает в Системном меню диалогового окна команду Закрыть (Close). Сообщение почти идентично уведомительному сообщению, посылаемому кнопкой Cancel и должно быть обработано точно таким же самым способом.


6.17 - Сообщение WM_PARENTNOTIFY

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

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


6.18 - Сообщения управляющие цветом

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

WM_CTLCOLORBTN
WM_CTLCOLORDLG
WM_CTLCOLOREDIT
WM_CTLCOLORLISTBOX
WM_CTLCOLORMSGBOX
WM_CTLCOLORSCROLLBAR
WM_CTLCOLORSTATIC

Элемент управления передает управляющее цветом сообщение в процедуру диалогового окна непосредственно перед тем, как он начнет рисовать свой собственный фон. Сообщение позволяет процедуре определить, какая используется кисть, и установить цвета фона и переднего плана. Процедура определяет кисть, путем возврата дескриптора кисти. Чтобы установить цвета фона и переднего плана, процедура использует функции SetBkColor и SetTextColor с контекстом устройства управления дисплеем. Управляющее цветом сообщение передает дескриптор контекста устройства дисплея в процедуру в параметре сообщения wParam.

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

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


6.19 - Обработка сообщения диалогового окна по умолчанию

Оконная процедура для предопределенного класса диалогового окна выполняет обработку по умолчанию для всех сообщений, которые не обрабатывает процедура блока диалога. Когда процедура диалогового окна возвращает значение ЛОЖЬ(FALSE) для какого-либо сообщения, предопределенная оконная процедура проверяет сообщения и выполняет по умолчанию следующие действия:

  • DM_GETDEFID - Вы можете передать это сообщение в диалоговое окно. Блок диалога возвращает идентификатор заданной по умолчанию командной кнопки элемента управления, если таковая имеется; в противном случае он возвращает нуль.
  • DM_REPOSITION - Вы можете передать это сообщение в диалоговое окно верхнего уровня. Блок диалога переустанавливается самостоятельно, так как он подгоняет себя в пределах области самого главного окна (рабочего стола программы).
  • DM_SETDEFID - Вы можете передать это сообщение диалоговое окно. Блок диалога устанавливает заданную по умолчанию командную кнопку в элементе управления, определенном идентификатором элемента управления в параметре wParam.
  • WM_ACTIVATE - Восстанавливает фокус ввода данных в элементе управления, идентифицированном предварительно сохраненным дескриптором, если диалоговое окно активизировано. Иначе, процедура сохраняет дескриптор элемента управления, имеющего фокус ввода данных.
  • WM_CHARTOITEM - Возвращает нуль.
  • WM_CLOSE - Посылает уведомительное сообщение BN_CLICKED в диалоговое окно, устанавливающее IDCANCEL как идентификатор элемента управления. Если блок диалога имеет идентификатор управления IDCANCEL и элемент управления в настоящее время заблокирован, процедура выдает предупреждение и не передает сообщение.
  • WM_COMPAREITEM - Возвращает нуль.
  • WM_ERASEBKGND - Заполняет рабочую область диалогового окна, используя или кисть, возвращенную сообщением WM_CTLCOLORDLG или цветом окна, который по умолчанию.
  • WM_GETFONT - Возвращает дескриптор определенного программой шрифта диалогового окна.
  • WM_INITDIALOG - Возвращает нуль.
  • WM_LBUTTONDOWN - Посылает комбинированному блоку, имеющему фокус ввода данных, сообщение CB_SHOWDROPDOWN, предписывая элементу управления скрыть его раскрывающийся список. Процедура вызывает DefWindowProc, чтобы завершить действие по умолчанию.
  • WM_NCDESTROY - Освобождает глобальную память, назначенную для средств редактирования в диалоговом окне (применяется в блоках диалога прикладных программах, базирующихся на Windows, в которых установлен стиль DS_LOCALEDIT) и освобождает любой определяемый программой шрифт (применяется в диалоговых окнах, в которых установлен стиль DS_SETFONT). Процедура вызывает функцию DefWindowProc, чтобы завершить действие по умолчанию.
  • WM_NCLBUTTONDOWN - Посылает комбинированному блоку, имеющему фокус ввода, сообщение CB_SHOWDROPDOWN предписывая элементу управления скрыть его раскрывающийся список. Процедура вызывает DefWindowProc, чтобы завершить действие по умолчанию.
  • WM_NEXTDLGCTL - Устанавливает фокус ввода данных в следующем или предыдущем элементе управления в диалоговом окне, в элементе управления, идентифицированном дескриптором в параметре wParam или в первом элементе управления в диалоговом окне, которое является видимым, не заблокированным и имеет стиль WS_TABSTOP. Процедура игнорирует это сообщение, если текущее окно с фокусом ввода данных - не элемент управления.
  • WM_SETFOCUS - Устанавливает фокус ввода данных в элемент управления, идентифицированным предварительно сохраненным дескриптором окна элемента управления. Если такого дескриптора не существует, процедура устанавливает фокус ввода данных в первый элемент управления в шаблоне диалогового окна, который является видимым, не заблокированным и имеет стиль WS_TABSTOP. Если такого элемента управления не существует, процедура устанавливает фокус ввода данных в первый элемент управления в шаблоне.
  • WM_SHOWWINDOW - Если диалоговое окно скрыто, сохраняет дескриптор элемента управления, имеющего фокус ввода данных, затем вызывает DefWindowProc, чтобы завершить действие по умолчанию.
  • WM_SYSCOMMAND - Если диалоговое окно свернуто, сохраняет дескриптор элемента управления, имеющего фокус ввода данных, затем вызывает DefWindowProc, чтобы завершить действие по умолчанию.
  • WM_VKEYTOITEM - Возвращает нуль.

Предопределенная оконная процедура все другие сообщения передает в DefWindowProc для их обработки по умолчанию.


6.20 - Интерфейса клавиатуры диалогового окна

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

  • ALT+mnemonic - Перемещает фокус ввода данных в первый элемент управления (имеющий стиль WS_TABSTOP) после статического элемента управления, содержащего данный символ.
  • DOWN - Перемещает фокус ввода данных в следующий элемент управления в группе.
  • ENTER - Посылает сообщение WM_COMMAND процедуре диалогового окна. В параметре wParam установлен IDOK или идентификатор элемента управления командной кнопки заданной по умолчанию.
  • ESC - Посылает сообщение WM_COMMAND процедуре диалогового окна. В параметре wParam установлен флажок IDCANCEL.
  • LEFT - Перемещает фокус ввода данных в предыдущий элемент управления в группе.
  • mnemonic - Перемещает фокус ввода данных в первый элемент управления (имеющий стиль WS_TABSTOP) после статического элемента управления, содержащего данный символ.
  • RIGHT - Перемещает фокус ввода данных в следующий элемент управления в группе.
  • SHIFT+TAB - Перемещает фокус ввода в предыдущий элемент управления, который имеет стиль WS_TABSTOP.
  • TAB - Перемещает фокус ввода в следующий элемент управления, который имеет стиль WS_TABSTOP.
  • UP - Перемещает фокус ввода данных в предыдущий элемент управления в группе.

Win32 API автоматически предоставляет интерфейс клавиатуры для всех модальных диалоговых окон. Она не дает этот интерфейс для немодальных блоков диалога, если прикладная программа не вызвала функцию IsDialogMessage, чтобы фильтровать сообщения в ее главном цикле сообщений. Это означает, что прикладная программа должна передать сообщение в IsDialogMessage немедленно после извлечения сообщения из очереди сообщений. Функция обрабатывает сообщения, если они для диалогового окна и возвращает значение отличное от нуля, чтобы указать, что сообщение было обработано и его невозможно было передать в функции TranslateMessage или DispatchMessage.

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


6.21 - Стиль WS_TABSTOP

Клавиша TAB и сочетание клавиш SHIFT+TAB не действуют, если в элементах управления диалогового окна не определен стиль WS_TABSTOP. Windows разыскивает этот стиль тогда, когда он ищет следующий элемент управления в диалоговом окне, который примет фокус ввода данных.

Когда пользователь нажимает на TAB или SHIFT+TAB, Windows сначала определяет, обрабатывает ли эти клавиши элемент управления, имеющий фокус ввода данных. Он передает элементу управления сообщение WM_GETDLGCODE и, если элемент управления возвращает DLGC_WANTTAB, Windows передает эти клавиши под управление. В противном случае, Windows использует функцию GetNextDlgTabItem, чтобы определить следующий элемент управления, который видимый, не блокирован и у которого определен стиль WS_TABSTOP. Windows начинает поиск элемента управления, в настоящее время имеющего фокус ввода данных, и продолжает по порядку, в котором элементы управления были созданы, то есть по порядку, в котором они определены в шаблоне диалогового окна. Когда система определяет элемент управления с требуемыми характеристиками, Windows перемещает фокус ввода данных в него.

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


6.22 - Стиль WS_GROUP

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

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

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

Функция GetNextDlgGroupItem ищет элементы управления по порядку (или в обратном порядке), как они были созданы. Если пользователь нажимает кнопку ВПРАВО (RIGHT) или ВНИЗ (DOWN), GetNextDlgGroupItem возвращает следующий элемент управления, если этот элемент не имеет стиля WS_GROUP. В противном случае, функция меняет на противоположный порядок поиска и возвращает первый найденный элемент управления, который обладает стилем WS_GROUP. Если пользователь нажимает кнопки ВЛЕВО (LEFT) или ВВЕРХ (UP), функция возвращает значение предыдущего элемента управления, если текущий элемент управления уже имеет стиль WS_GROUP. Если текущий элемент управления имеет этот стиль, функция меняет порядок поиска на противоположный, определяет первый элемент управления, имеющий стиль WS_GROUP, и возвращает значение элемента управления, который непосредственно предшествовал найденному элементу управления.

Как только Windows получает следующий или предыдущий элемент управления, он передает в этот элемент сообщение WM_GETDLGCODE, которое определяет тип элемента управления. Затем Windows перемещает фокус ввода данных в элемент управления, если он не статический элемент управления. Если элемент управления - автоматическая "радио-кнопка", Windows передает для неё сообщение BM_CLICK. Прикладная программа также может использовать GetNextDlgGroupItem для определения элементов управления в группе.

Обычно, первый элемент управления в группе - это комбинация стилей WS_GROUP и WS_TABSTOP, так что пользователь может перемещаться из группы в группу при помощи кнопки TAB. Если группа содержит "радио-кнопки", прикладная программа должна применять стиль WS_TABSTOP только для первого элемента в группе. Windows автоматически перемещает стиль, когда пользователь перемещается между элементами управления в группе. Это гарантия того, что фокус ввода данных будет всегда у самого последнего выбранного элемента управления, когда пользователь перемещается в группе, используя кнопку TAB.


6.23 - Мнемоника

(Замечание переводчика: Мнемоника - это совокупность приемов, облегчающих запоминание какой-либо информации.)

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

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

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

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


6.24 - Параметры настройки диалогового окна

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


6.25 - "Радио"-кнопки и окошки для отметки "галочкой"

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

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

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


6.26 - Элементы управления диалогового окна Редактирование(Edit)

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

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

Некоторые диалоговые окна используют поля редактирования, которые позволяют пользователю вводить числа. Процедура блока диалога может извлечь число из поля редактирования, используя функцию GetDlgItemInt, которая извлекает текст из элемента редактирования и преобразует текст в десятичные значения. Пользователь вводит число десятичными цифрами. Оно может быть или знаковое или без знака. Процедура диалогового окна может отображать целое число, используя функцию SetDlgItemInt. Эта функция преобразует знаковое или беззнаковое целое число в строку десятичных цифр.


6.27 - Окна со списком, комбинированные окна и списки каталогов

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

Диалоговое окно может также использовать комбинированный блок, чтобы отобразить список имен файлов. Функция DlgDirListComboBox автоматически заполняет часть окна со списком комбинированного блока с именами файлами в текущем каталоге. Функция DlgDirSelectComboBoxEx извлекает информацию о выбранном имени файла в части окна со списком.


6.28 - Управляющие сообщения диалогового окна

Многие элементы управления опознают предопределенные сообщения, которые, когда они получены элементом управления, заставляет их выполнять некоторое действие. Например, сообщение BM_SETCHECK устанавливает "галочку" в окошке для отметки "галочкой", а сообщение EM_GETSEL извлекает информацию о части текста элемента управления, который в настоящее время выбран. Управляющие сообщения дают процедуре диалога больший и более гибкий доступ к элементам управления, чем стандартные функции, так что они часто используются тогда, когда диалоговое окно требует комплексного взаимодействия с пользователем.

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

За более подробной информацией об управляющих сообщениях обратитесь к статье Элементы управления.


6.29 - Пользовательские диалоговые окна

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

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

Много прикладных программ создают новый класс диалогового окна сначала извлекая информацию о классе для предопределенного класса блока диалога и передавая ее в функцию GetClassInfo, которая заполняет структуру WNDCLASS информацией. Прикладная программа модифицирует отдельные элементы структуры, такие как имена класса, кисти и пиктограммы, а затем регистрирует новый класс, используя функцию RegisterClass. Если прикладная программа самой себе заполняет структуру WNDCLASS, она должна установить элемент cbWndExtra в DLGWINDOWEXTRA, который является числом дополнительных байтов, котороеWindows требует для каждого блока диалога. Если прикладная программа к тому же использует дополнительные байты для каждого блока диалога, они должны быть вне дополнительных байтов, требуемых Windows.

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

Прикладная программа может также создавать пользовательские диалоговые окна при помощи деления на подклассы оконной процедуры предопределенного блока диалога. Функция SetWindowLong позволяет прикладной программе установить адрес оконной процедуры для данного диалогового окна. Прикладная программа может также сделать попытку, используя функцию SetClassLong, поделить на подклассы, но сделав так, вы воздействуйте на все диалоговые окна в системе, принадлежащие не только этой прикладной программе.

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


6.30 - Использование диалоговых окон

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

Отображение окна сообщений
Создание модального диалогового окна
Создание немодального диалогового окна
Инициализация диалогового окна
Создание шаблона в памяти


6.30.1 - Отображение окна сообщений

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

В примере ниже прикладная программа показывает окно сообщений, если переменная fError имеет значение ИСТИНА (TRUE). Это окно сообщений показывает описывающее ошибку сообщение. Стиль MB_OKCANCEL заставляет MessageBox снабдить окно двумя кнопками, которыми пользователь может выбирать, как ему поступить:

if (fError) {
    if (MessageBox(hwndDlg, SZNOTFOUND, SZDELETEITEM,
        MB_OKCANCEL)==IDOK)
        .
        . // подсказывает имя нового элемента и повторяет команду.
        .
    else
        .
        . // прекращение действия команды.
        .
}

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


6.30.2 - Создание модального диалогового окна

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

В примере ниже, прикладная программа показывает модальное диалоговое окно, когда пользователь в меню приложения выбирает команду Удалить элемент (Delete Item). Диалоговое окно содержит поле редактирования (в которое пользователь вводит имя элемента) и кнопки ОК и Отменить (Cancel). Управляющие идентификаторы для этих элементов управления, соответственно, ID_ITEMNAME, IDOK и IDCANCEL.

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

Операторы ниже создают модальное диалоговое окно. Шаблон блока диалога - ресурс исполняемого файла прикладной программы и имеет идентификатором ресурса DLG_DELETEITEM:

case WM_COMMAND:
    switch (LOWORD(wParam))
    {
        case IDM_DELETEITEM:
            if (DialogBox(hinst,
                MAKEINTRESOURCE(DLG_DELETEITEM),
                hwnd, (DLGPROC)DeleteItemProc)==IDOK)

                .
                . // завершение работы команды; szItemName
                . // содержит имя элемента
                . // для удаления.
                .
            else
                .
                . // прерывание работы команды.
                .
                break;
    }
    return 0L;

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

char szItemName[80]; // принимает имя элемента, чтобы удалить.

BOOL CALLBACK DeleteItemProc(hwndDlg, message, wParam, lParam)
HWND hwndDlg;
UINT message;
WPARAM wParam;
LPARAM lParam;
{
    switch (message)
    {
    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
            case IDOK:
                if (!GetDlgItemText(hwndDlg, ID_ITEMNAME,
                    szItemName, 80))
                    *szItemName=0;
                    // потерпел неудачу.

            case IDCANCEL:
                    EndDialog(hwndDlg, wParam);
                    return TRUE;
        }
    }
    return FALSE;
}

В этом примере процедура использует GetDlgItemText, чтобы извлечь информацию о текущем тексте из поля редактирования, идентифицированном как ID_ITEMNAME. Затем процедура вызывает функцию EndDialog, чтобы установить возвращаемое значение диалогового окна, или IDOK или IDCANCEL, которое зависит от принятого сообщения и начинает работу по закрытию диалогового окна. Идентификаторы IDOK и IDCANCEL соответствуют кнопкам OK и Отменить (Cancel). После вызова процедурой EndDialog, Windows передает дополнительные сообщения для процедуры, чтобы разрушить блок диалога и возвращает значение диалогового окна назад в функцию, которая создавала блок диалога.


6.30.3 - Создание немодального диалогового окна

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

В следующем примере прикладная программа отображает немодальное диалоговое окно, если оно еще не отображено, когда пользователь выбирает команду Перейти к (Go To) из меню прикладной программы. Диалоговое окно содержит поле редактирования, окошко для отметки "галочкой" и кнопки OK и CANCEL. Шаблон блока диалога - ресурс в исполняемом файле прикладной программы и имеет идентификатор ресурса DLG_GOTO. Пользователь вводит номер строки в поле редактирования и проставляет в окошке для отметки "галочку", чтобы определить, что номер строки - относится к текущей строке. Идентификаторы элементов управления - ID_LINE, ID_ABSREL, IDOK и IDCANCEL.

Операторы в первой части примера создают немодальное диалоговое окно. Эти операторы, в оконной процедуре для главного окна прикладной программы, создают блок диалога, когда оконная процедура принимает сообщение WM_COMMAND, имеющее идентификатор команды IDM_GOTO, но только тогда, если глобальная переменная hwndGoto еще не содержит правильного дескриптора. Вторая часть примера - главный цикл сообщения прикладной программы. Цикл включает в себя функцию IsDialogMessage, чтобы гарантировать, что пользователь может использовать интерфейс клавиатуры блока диалога в этом немодальном диалоговом окне. Третья часть примера - процедура диалогового окна. Процедура извлекает информацию о содержимом поля редактирования и окошка для отметки "галочкой", когда пользователь выбирает кнопку OK. Процедура уничтожает диалоговое окно, когда пользователь выбирает кнопку Отменить (Cancel).

HWND hwndGoto = NULL;  // дескриптор окна блока диалога

    .
    .
    .

    case WM_COMMAND:
    switch (LOWORD(wParam))
    {
        case IDM_GOTO:
            if (!IsWindow(hwndGoto)) {
                hwndGoto = CreateDialog(hinst,
                MAKEINTRESOURCE(DLG_GOTO),
                hwnd, (DLGPROC) GoToProc);
                ShowWindow(hwndGoto, SW_SHOW);
            }
            break;
    }
    return 0L;

В предшествующих операторах, CreateDialog вызывается только тогда, если hwndGoto, не содержит правильный дескриптор окна. Это гарантирует, что прикладная программа одновременно не отобразит два диалоговых окна. Чтобы поддержать этот метод проверки, процедура блока диалога должна установить hwndGoto в значение ПУСТО (NULL), когда она уничтожает диалоговое окно.

Цикл сообщений для прикладной программы состоит из следующих операторов:

while (GetMessage(&msg, NULL, NULL, NULL))
{
    if (!IsWindow(hwndGoto) || !IsDialogMessage(hwndGoto, &msg))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

Цикл проверяет правильность дескриптора окна для блока диалога и только тогда вызывает функцию IsDialogMessage, если дескриптор правилен. Функция IsDialogMessage только тогда обрабатывает сообщение, если оно принадлежит диалоговому окну. Иначе, функция возвращает значение ЛОЖЬ(FALSE), а цикл посылает сообщение в соответствующее окно.

Следующие операторы определяют процедуру диалогового окна:

int iLine;		// принимает номер строки
BOOL fRelative;	// принимает состояние окошка для отметки "галочкой"

    .
    .
    .

BOOL CALLBACK GoToProc(hwndDlg, message, wParam, lParam)
HWND hwndDlg;
UINT message;
WPARAM wParam;
LPARAM lParam;
{
    BOOL fError;

    switch (message) {
        case WM_INITDIALOG:
            CheckDlgButton(hwndDlg, ID_ABSREL, fRelative);
            return TRUE;

        case WM_COMMAND:
        switch (LOWORD(wParam))
        {
            case IDOK:
                fRelative = IsDlgButtonChecked(hwndDlg,
                    ID_ABSREL);
                iLine = GetDlgItemInt(hwndDlg, ID_LINE,
                    &fError, fRelative);
                if (fError) {
                    MessageBox(hwndDlg, SZINVALIDNUMBER,
                        SZGOTOERR, MB_OK);
                    SendDlgItemMessage(hwndDlg, ID_LINE,
                        EM_SETSEL, 0, -1L);
                } else
                    .
                    . // Уведомляет окно владельца, что команда выполнена.
                    .
                return TRUE;

            case IDCANCEL:
                DestroyWindow(hwndDlg);
                hwndGoto = NULL;
                return TRUE;
        }
    }
    return FALSE;
}

В предшествующих операторах процедура обрабатывает сообщения WM_COMMAND и WM_INITDIALOG. В ходе обработки WM_INITDIALOG, процедура инициализирует окошко для отметки "галочкой", передавая текущее значение глобальной переменной fRelative в CheckDlgButton. Затем процедура возвращает значение ИСТИНА (TRUE), чтобы заставить Windows установить фокус ввода данных по умолчанию.

В ходе обработки WM_COMMAND, процедура закрывает диалоговое окно только тогда, если пользователь выбирает кнопку Отменить (Cancel) - то есть кнопку, имеющую идентификатор IDCANCEL. Процедура должна вызвать DestroyWindow, чтобы закрыть немодальное диалоговое окно. Обратите внимание, что процедура также устанавливает переменную hwndGoto в значение ПУСТО (NULL), чтобы гарантировать, что другие операторы, которые зависят от этой переменной, действуют правильно.

Если пользователь выбирает кнопку OK, процедура извлекает информацию о текущем состоянии окошка для отметки "галочкой" и присваивает ее переменной fRelative. Затем она использует эту переменную, чтобы извлечь данные о числе строк в поле редактирования. Функция GetDlgItemInt переводит текст в поле редактирования в целое число. Значение fRelative определяет, правильно ли понимает функция число как знаковое или беззнаковое значение. Если текст поля редактирования - не правильное число, GetDlgItemInt устанавливает в переменной fError значение отличное от нуля. Процедура проверяет это значение, чтобы определить, или показать сообщение об ошибке или завершить команду. В случае ошибки, процедура диалогового окна передает сообщение полю редактирования, предписывая ему выбрать текст в элементе управления так, чтобы пользователь мог его легко заменять. Если GetDlgItemInt не возвращает ошибку, процедура может или завершить затребованную команду самостоятельно или передать сообщение окну владельцу, предписывая ему завершить команду.


6.30.4 - Инициализация диалогового окна

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

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

HWND hwndOwner;
RECT rc, rcDlg, rcOwner;

case WM_INITDIALOG:

    // Получим сведения о прямоугольниках окна владельца и окна диалога.

    if ((hwndOwner = GetParent(hwndDlg)) == NULL)
        hwndOwner = GetDesktopWindow();
        GetWindowRect(hwndOwner, &rcOwner);
        GetWindowRect(hwndDlg, &rcDlg);
        CopyRect(&rc, &rcOwner);

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

        OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
        OffsetRect(&rc, -rc.left, -rc.top);
        OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);

        // Новая позиция, это - сумма половины оставшейся
        // площади и исходной позиции окна владельца.

        SetWindowPos(hwndDlg,HWND_TOP,rcOwner.left + (rc.right / 2),
            rcOwner.top + (rc.bottom / 2),
            0, 0,	// игнорирует параметры размера
            SWP_NOSIZE);

        if (GetDlgCtrlID((HWND) wParam) != ID_ITEMNAME)
        {
            SetFocus(GetDlgItem(hwndDlg, ID_ITEMNAME));
            return FALSE;
        }
        return TRUE;

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

Перед установкой фокуса ввода данных, процедура проверяет идентификатор элемента управления, в котором фокус ввода данных по умолчанию. Windows передает дескриптор окна, в котором фокус ввода данных по умолчанию, в параметр wParam. Функция GetDlgCtrlID возвращает идентификатор для элемента управления , который идентифицирован дескриптором окна. Если идентификатор не соответствует правильному идентификатору, процедура использует функцию SetFocus, чтобы установить фокус ввода данных. Функция GetDlgItem требует поиска данных о дескрипторе окна желаемого элемента управления.


6.30.5 - Создание шаблона в памяти

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

В примере ниже прикладная программа создает шаблон в памяти для модального диалогового окна, которое содержит сообщение и кнопки ОК и Справка (Help).

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

Структуры DLGITEMTEMPLATE в шаблоне диалогового окна должны быть выровнены по границам ДВОЙНОГО СЛОВА (DWORD). Чтобы выровнять эти структуры, этот пример использует подпрограмму - помощника, которая получает введенный указатель, а возвращает самый близкий указатель, который выравнен по границе ДВОЙНОГО СЛОВА - DWORD (4 байта).

#define ID_HELP   150
#define ID_TEXT   200

LPWORD lpwAlign ( LPWORD lpIn)
{
    ULONG ul;
    ul = (ULONG) lpIn;
    ul +=3;
    ul >>=2;
    ul <<=2;
    return (LPWORD) ul;
}

LRESULT DisplayMyMessage(HINSTANCE hinst, HWND hwndOwner,
    LPSTR lpszMessage)
{
    HGLOBAL hgbl;
    LPDLGTEMPLATE lpdt;
    LPDLGITEMTEMPLATE lpdit;
    LPWORD lpw;
    LPWSTR lpwsz;
    LRESULT ret;
    int nchar;

    hgbl = GlobalAlloc(GMEM_ZEROINIT, 1024);
    if (!hgbl)

    return -1;

    lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl);

    // Определение диалогового окна.

    lpdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU
        | DS_MODALFRAME | WS_CAPTION;
    lpdt->cdit = 3;	// число элементов управления
    lpdt->x  = 10;  lpdt->y  = 10;
    lpdt->cx = 100; lpdt->cy = 100;

    lpw = (LPWORD) (lpdt + 1);
    *lpw++ = 0;	// меню нет
    *lpw++ = 0;	// класс предопределенного диалогового окна (по умолчанию)

    lpwsz = (LPWSTR) lpw;

    nchar = 1+ MultiByteToWideChar (CP_ACP, 0, "My Dialog",  -1, lpwsz, 50);
    lpw   += nchar;

    //-----------------------
    // Определение кнопки OK.
    //-----------------------
    lpw = lpwAlign (lpw); 	// выравнивание DLGITEMTEMPLATE по границе DWORD
    lpdit = (LPDLGITEMTEMPLATE) lpw;
    lpdit->x  = 10; lpdit->y  = 70;
    lpdit->cx = 80; lpdit->cy = 20;
    lpdit->id = IDOK;  	// идентификатор кнопки OK
    lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;

    lpw = (LPWORD) (lpdit + 1);
    *lpw++ = 0xFFFF;
    *lpw++ = 0x0080;	// класс кнопки

    lpwsz = (LPWSTR) lpw;
    nchar = 1+MultiByteToWideChar (CP_ACP, 0, "OK", -1, lpwsz, 50);
    lpw   += nchar;
    lpw = lpwAlign (lpw);	// выравнивание созданных данных по границе DWORD
    *lpw++ = 0;		// созданных данных нет

    //-----------------------
    // Определение кнопки Help.
    //-----------------------
    lpw = lpwAlign (lpw); 	// выравнивание DLGITEMTEMPLATE по границе DWORD

    lpdit = (LPDLGITEMTEMPLATE) lpw;
    lpdit->x  = 55; lpdit->y  = 10;
    lpdit->cx = 40; lpdit->cy = 20;
    lpdit->id = ID_HELP;    // идентификатор кнопки Help
    lpdit->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON;

    lpw = (LPWORD) (lpdit + 1);
    *lpw++ = 0xFFFF;
    *lpw++ = 0x0080;	// атом класса кнопки
    lpwsz = (LPWSTR) lpw;
    nchar = 1+MultiByteToWideChar (CP_ACP, 0, "Help", -1, lpwsz, 50);
    lpw += nchar;
    lpw = lpwAlign (lpw); 	// выравнивание созданных данных по границе DWORD

    *lpw++ = 0;		// созданных данных нет

    //-----------------------
    // Определение статического текста в элементе управления.
    //-----------------------
    lpw = lpwAlign (lpw); 		// выравнивание DLGITEMTEMPLATE по границе DWORD
    lpdit = (LPDLGITEMTEMPLATE) lpw;
    lpdit->x  = 10; lpdit->y  = 10;
    lpdit->cx = 40; lpdit->cy = 20;
    lpdit->id = ID_TEXT;  // идентификатор текста
    lpdit->style = WS_CHILD | WS_VISIBLE | SS_LEFT;

    lpw = (LPWORD) (lpdit + 1);
    *lpw++ = 0xFFFF;
    *lpw++ = 0x0082;	// класс статического элемента

    for (lpwsz = (LPWSTR)lpw;
        *lpwsz++ = (WCHAR) *lpszMessage++;
    );
    lpw = (LPWORD)lpwsz;
    lpw = lpwAlign (lpw);	// выравнивание созданных данных по границе DWORD
    *lpw++ = 0;		// созданных данных нет

    GlobalUnlock(hgbl);
    ret = DialogBoxIndirect(hinst, (LPDLGTEMPLATE) hgbl,
        hwndOwner, (DLGPROC) DialogProc);
    GlobalFree(hgbl);
    return ret;
}


6.31 - Справочник по диалоговому окну

Следующие функции, структуры и сообщения связаны с диалоговым окном.


6.31.1 - Функции диалогового окна

Ниже перечислены функции, используемые для создания и управления диалоговыми окнами и органами управления внутри диалоговых окон.
CreateDialog
CreateDialogIndirect
CreateDialogIndirectParam
CreateDialogParam
DefDlgProc
DialogBox
DialogBoxIndirect
DialogBoxIndirectParam
DialogBoxParam
DialogProc
EndDialog
GetDialogBaseUnits
GetDlgCtrlID
GetDlgItem
GetDlgItemInt
GetDlgItemText
GetNextDlgGroupItem
GetNextDlgTabItem
IsDialogMessage
MapDialogRect
MessageBox
MessageBoxEx
SendDlgItemMessage
SetDlgItemInt
SetDlgItemText
MessageBoxIndirect


6.31.1.1 - Функция CreateDialog

(СоздатьДиалог)

Макрокоманда CreateDialog создает немодальное диалоговое окно из ресурса шаблона блока диалога. Макрокоманда CreateDialog использует функцию CreateDialogParam.

Синтаксис

HWND CreateDialog
(
    HINSTANCE hInstance,		// дескриптор экземпляра прикладной программы
    LPCTSTR lpTemplate,		// идентифицирует название шаблона блока диалога
    HWND hWndParent,		// дескриптор окна владельца
    DLGPROC lpDialogFunc 		// указатель на процедуру диалогового окна
);

Параметры
hInstance
Идентифицирует экземпляр модуля, исполняемый файл которого содержит шаблон диалогового окна.
lpTemplate
Идентифицирует шаблон диалогового окна. Этот параметр является или указателем на строку символов с нуль-терминатором в конце, которая определяет название шаблона блока диалога или на целочисленное значение, которое определяет идентификатор ресурса шаблона диалогового окна. Если параметр устанавливает идентификатор ресурса, его старшее слово должно быть нулевое, а его младшее слово должно содержать идентификатор. Вы можете использовать макрокоманду MAKEINTRESOURCE, чтобы создать это значение.
hWndParent
Идентифицирует окно, которому принадлежит блок диалога.
lpDialogFunc
Указывает на процедуру диалогового окна. Для получения дополнительной информации о процедуре диалогового окна, см. статью DialogProc.

Возвращаемые значения
Если функция завершает работу успешно, возвращаемое значение - дескриптор диалогового окна.
Если функция терпит неудачу, возвращаемое значение -ПУСТО (NULL).

Замечания
Функция CreateDialog использует для создания диалогового окна функцию CreateWindowEx. Затем CreateDialog отправляет сообщение WM_INITDIALOG (и сообщение WM_SETFONT, если шаблон определяет стиль DS_SETFONT) в процедуру диалогового окна. Функция показывает блок диалога, если шаблон определяет стиль WS_VISIBLE. В заключение, CreateDialog возвращает дескриптор окна блока диалога.
После того как CreateDialog возвращает значение, прикладная программа показывает диалоговое окно (если оно еще не отображено на экране) при помощи использования функции ShowWindow. Приложение разрушает диалоговое окно, используя функцию DestroyWindow.

Windows 95: Система может поддерживать максимум 16 364 дескриптора окна.

Смотри также
CreateDialogIndirect, CreateDialogIndirectParam, CreateDialogParam, CreateWindowEx, DestroyWindow, DialogBox, DialogProc, ShowWindow, WM_INITDIALOG, WM_SETFONT

Размещение и совместимость CreateDialog

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					WinNT
Замечания по платформе			Не имеется


6.31.1.2 - Функция CreateDialogIndirect

(СозданиеДиалогаКосвенно)

Макрокоманда CreateDialogIndirect создает немодальное диалоговое окно из шаблона блока диалога в памяти. Макрокоманда CreateDialogIndirect использует функцию CreateDialogIndirectParam.

Синтаксис

HWND CreateDialogIndirect
(
    HINSTANCE hInstance,			// дескриптор экземпляра прикладной программы
    LPCDLGTEMPLATE lpTemplate,		// указатель на шаблон блока диалога
    HWND hWndParent,			// дескриптор окна владельца
    DLGPROC lpDialogFunc 			// указатель на процедуру диалогового окна
);

Параметры
hInstance
Идентифицирует экземпляр модуля, который создает диалоговое окно.
lpTemplate
Указатель на объект глобальной памяти, содержащий шаблон, который CreateDialogIndirect использует для создания диалогового окна. Шаблон диалогового окна состоит из заголовка, который описывает блок диалога, сопровождаемый одним или несколькими дополнительными блоками данных, которые описывают каждый орган управления в диалоговом окне. Шаблон можно использовать или в стандартном или в расширенном формате.
В стандартном шаблоне заголовок - структура DLGTEMPLATE, сопровождаемая дополнительными массивами переменной длины. Данные для каждого органа управления состоят из структуры DLGITEMTEMPLATE, сопровождаемой дополнительными массивами переменной длины.
В расширенном шаблоне диалогового окна, заголовок использует формат DLGTEMPLATEEX, а определения органа управления используют формат DLGITEMTEMPLATEEX.
hWndParent
Идентифицирует окно, которое владеет блоком диалога.
lpDialogFunc
Указывает на процедуру диалогового окна. За более подробной информацией о процедуре диалогового окна обратитесь к статье DialogProc.

Возвращаемые значения
Если функция завершает работу успешно, возвращаемое значение - дескриптор окна блока диалога.
Если функция терпит неудачу, возвращаемое значение ПУСТО (NULL)

Замечания
Макрокоманда CreateDialogIndirect использует функцию CreateWindowEx, чтобы создать диалоговое окно. Затем CreateDialogIndirect отправляет сообщение WM_INITDIALOG в процедуру диалогового окна. Если шаблон определяет стиль DS_SETFONT, то функция к тому же в процедуру диалогового окна отправляет сообщение WM_SETFONT. Функция отображает на экране диалоговое окно в том случае, если шаблон определяет стиль WS_VISIBLE. В конце концов, CreateDialogIndirect возвращает значение дескриптора окна блока диалога.
После того как CreateDialogIndirect возвратит значение, вы можете использовать функцию ShowWindow, чтобы отобразить на экране диалоговое окно (если оно еще не видимое). Чтобы разрушить диалоговое окно, используйте функцию DestroyWindow.
В шаблоне стандартного диалогового окна, в структуре DLGTEMPLATE и в каждой из структур DLGITEMTEMPLATE должно быть сделано выравнивание по границам ДВОЙНОГО СЛОВА (DWORD). Массив данных создания, который следует за структурой DLGITEMTEMPLATE, должен также быть выровнен по границе ДВОЙНОГО СЛОВА (DWORD). Все другие массивы переменной длины в шаблоне должны быть выровненными по границам СЛОВА (WORD).
В расширенном шаблоне диалогового окна заголовок DLGTEMPLATEEX и каждое определение DLGITEMTEMPLATEEX органа управления должны быть выровнены по границам ДВОЙНОГО СЛОВА (DWORD). Массив данных создания, если имеется, который сопровождает структуру DLGITEMTEMPLATEEX, должен также быть выровнен по границам ДВОЙНОГО СЛОВА (DWORD). Все другие массивы переменной длины в шаблоне должны быть выровнены по границам СЛОВА (WORD).
Все символьные строки в шаблоне блока диалога, такие как заголовки диалоговых окон и названия кнопок, должны быть строками Уникода. Чтобы создать код, который работает и в Windows NT и Windows 95, для создания этих строк Уникода используйте функцию MultiByteToWideChar.

Windows 95: система может поддерживать максимум 16,364 дескрипторов окна.

Смотри также
CreateDialog, CreateDialogIndirectParam, CreateDialogParam, CreateWindowEx, DestroyWindow, DialogProc, DLGITEMTEMPLATE, DLGITEMTEMPLATEEX, DLGTEMPLATE, DLGTEMPLATEEX, MultiByteToWideChar, ShowWindow, WM_INITDIALOG, WM_SETFONT

Размещение и совместимость CreateDialogIndirect

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					WinNT
Замечания по платформе			Не имеется


6.31.1.3 - Функция CreateDialogIndirectParam

(СоздатьДиалогКосвенноПараметрами)

Функция CreateDialogIndirectParam создает немодальный блок диалога из шаблона диалогового окна в памяти. Перед отображением диалогового окна на экране, функция передает определяемое программой значение в процедуру диалогового окна в качестве параметра lParam сообщения WM_INITDIALOG. Прикладная программа может использовать это значение, чтобы инициализировать элементы управления диалогового окна.

Синтаксис

HWND CreateDialogIndirectParam
(
    HINSTANCE hInstance,			// дескриптор экземпляра прикладной программы
    LPCDLGTEMPLATE lpTemplate,		// указатель на шаблон блока диалога
    HWND hWndParent,			// дескриптор окна владельца
    DLGPROC lpDialogFunc,			// указатель на процедуру диалогового окна
    LPARAM lParamInit 			// инициализационное значение
);

Параметры
hInstance
Идентифицирует экземпляр модуля, который должен создать диалоговое окно.
lpTemplate
Указатель на объект глобальной памяти содержащий шаблон, который использует CreateDialogIndirectParam, чтобы создать диалоговое окно. Шаблон блока диалога состоит из заголовка, который описывает блок диалога, сопровождаемого одним или несколькими дополнительными блоками данных, которые описывают каждый из органов управления в диалоговом окне. Шаблон может использовать или стандартный или расширенный формат.
В стандартном шаблоне заголовок является структурой DLGTEMPLATE, сопровождаемой дополнительными массивами переменной длины. Данные для каждого органа управления состоят из структуры DLGITEMTEMPLATE, сопровождаемой дополнительными массивами переменной длины.
В расширенном шаблоне диалогового окна заголовок использует формат DLGTEMPLATEEX, а определения элемента управления используют формат DLGITEMTEMPLATEEX.
hWndParent
Идентифицирует окно, которое владеет диалоговым окном.
lpDialogFunc
Указывает на процедуру диалогового окна. За подробной информацией о процедуре диалогового окна обратись к статье DialogProc.
lParamInit
Определяет значение, которое передается диалоговому окну в параметре lParam сообщения WM_INITDIALOG.

Возвращаемые значения
Если функция завершила работу успешно, возвращаемое значение - дескриптор окна блока диалога.
Если функция потерпела неудачу, возвращаемое значение ПУСТО (NULL).

Замечания
Функция CreateDialogIndirectParam, чтобы создать диалоговое окно, использует функцию CreateWindowEx. Затем CreateDialogIndirectParam отправляет в процедуру диалогового окна сообщение WM_INITDIALOG. Если шаблон определяет стиль DS_SETFONT, функция к тому же в процедуру диалогового окна отправляет сообщение WM_SETFONT. Функция отображает на экране диалоговое окно в том случае, если шаблон устанавливает стиль WS_VISIBLE. В конце концов, CreateDialogIndirectParam возвращает значение дескриптора окна блока диалога.
После возвращения значения CreateDialogIndirectParam, вы можете использовать функцию ShowWindow, чтобы показать на экране диалоговое окно (если оно ещё не видимое). Чтобы разрушить диалоговое окно, используйте функцию DestroyWindow.
В шаблоне стандартного диалогового окна структура DLGTEMPLATE и каждая из структур DLGITEMTEMPLATE должны быть выровнены по границам ДВОЙНОГО СЛОВА (DWORD). Массив данных создания, который сопровождает структуру DLGITEMTEMPLATE, должен быть также выровнен по границе ДВОЙНОГО СЛОВА (DWORD). Все другие массивы переменной длины в шаблоне должны быть выровнены по границам СЛОВА (WORD).
В шаблоне расширенного диалогового окна заголовок DLGTEMPLATEEX и каждое определение элемента управления DLGITEMTEMPLATEEX должны быть выровнены по границам ДВОЙНОГО СЛОВА (DWORD). Массив данных создания, если он есть, который сопровождает структуру DLGITEMTEMPLATEEX, должен быть также выровнен по границам ДВОЙНОГО СЛОВА (DWORD). Все другие массивы переменной длины в шаблоне должны быть выровнены по границам СЛОВА (WORD).
Все символьные строки шаблона диалогового окна, такие как заголовок блока диалога и надписи кнопок, должны быть строками Уникода. Чтобы создать код, который работает и Windows NT и Windows 95, используйте функцию MultiByteToWideChar для генерации этих строк Уникода.

Windows 95: Система может поддерживать максимум 16,364 дескрипторов окна.

Смотри также
CreateDialog, CreateDialogIndirect, CreateDialogParam, CreateWindowEx, DestroyWindow, DialogProc, DLGITEMTEMPLATE, DLGITEMTEMPLATEEX, DLGTEMPLATE, DLGTEMPLATEEX, MultiByteToWideChar, ShowWindow, WM_INITDIALOG, WM_SETFONT

Размещение и совместимость CreateDialogIndirectParam

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					WinNT
Замечания по платформе			Не имеется


6.31.1.4 - Функция CreateDialogParam

(СоздатьДиалогПоПараметрам)

Функция CreateDialogParam создает немодальное диалоговое окно из шаблона ресурса блока диалога. Перед показом диалогового окна на экране, функция отправляет в процедуру блока диалога определяемое программой значение сообщения WM_INITDIALOG, как параметр lParam. Прикладная программа может использовать это значение, чтобы инициализировать элементы управления диалогового окна.

Синтаксис

HWND CreateDialogParam
(
    HINSTANCE hInstance,		// дескриптор экземпляра программы
    LPCTSTR lpTemplateName,		// идентификация шаблона блока диалога
    HWND hWndParent,		// дескриптор окна владельца
    DLGPROC lpDialogFunc,		// указатель на процедуру диалогового окна
    LPARAM dwInitParam 		// инициализационное значение
);

Параметры
hInstance
Идентифицирует экземпляр модуля, исполняемый файл которого содержит шаблон диалогового окна.
lpTemplateName
Идентифицирует шаблон диалогового окна. Этот параметр - или указатель на строку символов с нуль-терминатором в конце, которая определяет имя шаблона диалогового окна, или целочисленное значение, которое определяет идентификатор ресурса шаблона блока диалога. Если параметр определяет идентификатор ресурса, его старшее слово должно быть нулевым, а младшее слово должно содержать идентификатор. Вы можете использовать макрокоманду MAKEINTRESOURCE, чтобы создать это значение.
hWndParent
Идентифицирует окно, которое владеет блоком диалога.
lpDialogFunc
Указывает на процедуру диалогового окна. За большей информацией о процедуре диалогового окна обратитесь к статье DialogProc
dwInitParam
Устанавливает значение, передаваемое процедуре диалогового окна в параметре lParam сообщения WM_INITDIALOG.

Возвращаемые значения
Если функция завершилась успешно, возвращается значение дескриптор окна блока диалога.
Если функция потерпела неудачу, возвращается значение ПУСТО (NULL).

Замечания
Чтобы создать диалоговое окно, функция CreateDialogParam использует функцию CreateWindowEx. Затем CreateDialogParam отправляет сообщение WM_INITDIALOG (и сообщение WM_SETFONT, если шаблон определяет стиль DS_SETFONT) процедуре диалогового окна. Функция показывает диалоговое окно, если шаблон определяет стиль WS_VISIBLE. В конце концов, CreateDialogParam возвращает дескриптор окна блока диалога.
После того как CreateDialogParam возвращает значение, прикладная программа отображает на экране диалоговое окно (если оно ещё не отображено) используя функцию ShowWindow. Прикладная программа разрушает диалоговое окно, используя функцию DestroyWindow.

Windows 95: Система может поддерживать максимум 16,364 дескрипторов окна

Смотри также
CreateDialog, CreateDialogIndirect, CreateDialogIndirectParam, CreateWindowEx, DestroyWindow, DialogProc, MAKEINTRESOURCE, ShowWindow, WM_INITDIALOG, WM_SETFONT

Размещение и совместимость CreateDialogParam

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					WinNT
Замечания по платформе			Не имеется


6.31.1.5 - Функция DefDlgProc

(ПроцедураДиалоговогоОкнаПоУмолчанию)

Функция DefDlgProc выполняет обработку сообщения по умолчанию вместо оконной процедуры принадлежащей определяемому программой классу диалогового окна.

Синтаксис

LRESULT DefDlgProc
(
    HWND hDlg,	// дескриптор диалогового окна
    UINT Msg,	// сообщение
    WPARAM wParam,	// первый параметр сообщения
    LPARAM lParam	// второй параметр сообщения
);

Параметры
hDlg
Идентифицирует диалоговое окно.
Msg
Устанавливает номер сообщения
wParam
Устанавливает дополнительную конкретизирующую сообщение информацию.
lParam
Устанавливает дополнительную конкретизирующую сообщение информацию.

Возвращаемые значения
Возвращаемое значение определяет результат обработки сообщения и зависит от отправленного сообщения.

Замечания
Функция DefDlgProc - оконная процедура для предопределенного класса блока диалога. Эта процедура обеспечивает внутреннюю обработку для диалогового окна, отправляя сообщения в процедуру диалогового окна, и выполняя обработку по умолчанию любых сообщений, для которых процедура диалогового окна возвращает значение такое, как ЛОЖЬ (FALSE). Прикладные программы, которые создают пользовательские оконные процедуры для своих пользовательских блоков диалога, часто используют DefDlgProc вместо функции DefWindowProc, чтобы выполнить заданную по умолчанию обработку сообщения.
Прикладные программы создают пользовательские классы диалогового окна, заполняя структуру WNDCLASS соответствующей информацией и регистрируя класс при помощи функции RegisterClass. Некоторые прикладные программы заполняют структуру, используя функцию GetClassInfo, определяя название предопределенного диалогового окна. В таких случаях, прикладные программы изменяют, по крайней мере, член структуры lpszClassName перед регистрацией. Во всех случаях, член cbWndExtra структуры WNDCLASS для пользовательского класса диалогового окна должен быть установлен по крайней мере в DLGWINDOWEXTRA.
Функция DefDlgProc не должна вызваться процедурой диалогового окна; поступив так, вы приведете ее к рекурсивному выполнению. (Примечание переводчика: то есть «подвесите» систему.)

Смотри также
DefWindowProc, GetClassInfo, RegisterClass, WNDCLASS

Размещение и совместимость DefDlgProc

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					WinNT
Замечания по платформе			Не имеется


6.31.1.6 - Функция DialogBox

(БлокДиалога)

Макрокоманда DialogBox создает модальное диалоговое окно из ресурса шаблона блока диалога. DialogBox не возвращает управления до тех пор, пока заданная функция обратного вызова не прекратит работу модального диалогового окна путем вызова функции EndDialog. Макрокоманда DialogBox использует функцию DialogBoxParam.

Синтаксис

int DialogBox
(
    HINSTANCE hInstance,		// дескриптор экземпляра программы
    LPCTSTR lpTemplate,		// идентифицирует шаблон диалогового окна
    HWND hWndParent,		// дескриптор окна владельца
    DLGPROC lpDialogFunc 		// указатель на процедуру блока диалога
);

Параметры
hInstance
Идентифицирует экземпляр модуля, исполняемый файл которого содержит шаблон диалогового окна.
lpTemplate
Идентифицирует шаблон диалогового окна. Этот параметр является или указателем на строку символов с нулевым символом в конце, определяющую название шаблона диалогового окна, или целочисленным значением, которое определяет идентификатор ресурса шаблона блока диалога. Если параметр определяет идентификатор ресурса, его старшее слово должно быть нулевое, а его младшее слово должно содержать идентификатор. Вы можете использовать макрокоманду MAKEINTRESOURCE, чтобы создать это значение.
hWndParent
Идентифицирует окно, которое владеет блоком диалога.
lpDialogFunc
Указывает на процедуру диалогового окна. За более детальной информацией о процедуре диалогового окна обратись к статье о функции повторного вызова DialogProc.

Возвращаемые значения
Если функция завершает свою работу успешно, возвращаемое значение является параметром nResult при вызове функции EndDialog, используемой для завершения работы блока диалога.
Если функция потерпела неудачу, возвращаемое значение – (минус) 1.

Замечания
Макрокоманда DialogBox использует функцию CreateWindowEx, чтобы создать диалоговое окно. Затем DialogBox отправляет сообщение WM_INITDIALOG(и сообщение WM_SETFONT, если шаблон определяет стиль DS_SETFONT) в процедуру диалогового окна. Функция показывает на экране диалоговое окно (независимо от того, определяет ли шаблон стиль WS_VISIBLE), отключает окно владельца, и начинает свой собственный цикл сообщений, чтобы извлекать и распределять сообщения для диалогового окна.
Когда процедура диалогового окна вызывает функцию EndDialog, DialogBox разрушает диалоговое окно, заканчивает цикл сообщений, включает окно владельца (если прежде это было разрешено) и возвращает параметр nResult, заданный процедурой диалогового окна, когда она вызвала EndDialog.

Windows 95: Система может поддерживать максимум 16,364 дескрипторов окна.

Смотри также
CreateDialog, CreateWindowEx, DialogBoxIndirect, DialogBoxIndirectParam, DialogBoxParam, DialogProc, EndDialog, MAKEINTRESOURCE, WM_INITDIALOG, WM_SETFONT

Размещение и совместимость DialogBox

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					WinNT
Замечания по платформе			Не имеется


6.31.1.7 - Функция DialogBoxIndirect

(КосвенныйБлокДиалога)

Макрокоманда DialogBoxIndirect создает модальное диалоговое окно из шаблона блока диалога в памяти. Функция DialogBoxIndirect не возвращает управление до тех пор, пока заданная функция повторного вызова не закончит работу модального диалогового окна путем вызова функции EndDialog. Макрокоманда DialogBoxIndirect использует функцию DialogBoxIndirectParam.

Синтаксис

int DialogBoxIndirect
(
    HINSTANCE hInstance,			// дескриптор экземпляра программы
    LPDLGTEMPLATE lpTemplate,		// идентифицирует шаблон блока диалога
    HWND hWndParent,			// дескриптор окна владельца
    DLGPROC lpDialogFunc 			// указатель на процедуру диалогового окна
);

Параметры
hInstance
Идентифицирует экземпляр модуля, который создает блок диалога.
lpTemplate
Указатель на объект глобальной памяти, содержащий шаблон, который DialogBoxIndirect использует, чтобы создать диалоговое окно. Шаблон диалогового окна состоит из заголовка, который описывает блок диалога, сопровождаемого одним или несколькими дополнительными блоками данных, которые описывают каждый элемент управления в диалоговом окне. Шаблон может использовать или стандартный или расширенный формат.
В стандартном шаблоне диалогового окна, заголовок является структурой DLGTEMPLATE, сопровождаемой дополнительными массивами переменной длины. Данные для каждого элемента управления состоят из структуры DLGITEMTEMPLATE, сопровождаемой дополнительным массивом переменой длины.
В расширенном шаблоне диалогового окна заголовок использует формат DLGTEMPLATEEX, а определения элемента управления используют формат DLGITEMTEMPLATEEX.
hWndParent
Идентифицирует окно, которое владеет блоком диалога.
lpDialogFunc
Указатель на процедуру диалогового окна. За большей информацией о процедуре блока диалога обратитесь к статье DialogProc

Возвращаемые значения
Если функция завершает свою работу успешно, возвращаемым значением является параметр nResult, определяемый при вызове функции EndDialog, которая использовалась для завершения работы диалогового окна.
Если функция потерпела неудачу, возвращаемым значением является – (минус) 1.

Замечания
Макрокоманда DialogBoxIndirect для создания диалогового окна использует функцию CreateWindowEx. Затем DialogBoxIndirect отправляет сообщение WM_INITDIALOG в процедуру диалогового окна. Если шаблон определяет стиль DS_SETFONT, функция, к тому же, в процедуру диалогового окна передает и сообщение WM_SETFON. Функция показывает на экране диалоговое окно (независимо от того, определяет ли шаблон стиль WS_VISIBLE), блокирует окно владельца и запускает свой собственный цикл сообщений для извлечения и распределения сообщений для диалогового окна.
Когда процедура диалогового окна вызывает функцию EndDialog, DialogBoxIndirect разрушает блок диалога, заканчивает цикл сообщений, разрешает работу окну владельцу (если прежде это было разрешено) и возвращает параметр nResult, определяемый при помощи процедуры диалогового окна, когда она вызвала EndDialog.
В стандартном шаблоне диалогового окна структура DLGTEMPLATE и каждая из структур DLGITEMTEMPLATE, должны быть выровнены по границам ДВОЙНОГО СЛОВА (DWORD). Массив данных создания, который следует за структурой DLGITEMTEMPLATE, должен также быть выровнен по границе ДВОЙНОГО СЛОВА (DWORD).Все другие массивы переменной длины в шаблоне должны быть выровнены по границам СЛОВА (WORD).
В расширенном шаблоне диалогового окна, заголовок DLGTEMPLATEEX и каждое определение DLGITEMTEMPLATEEX органа управления должны быть выровнены по границам ДВОЙНОГО СЛОВА (DWORD). Все другие массивы переменной длины в шаблоне должны быть выровнены по границам СЛОВА (WORD).
Все символьные строки в шаблоне диалогового окна, такие как названия блока диалога и кнопок, должны быть строками Unicode. Чтобы создать код, который работает и в Windows NT и Windows 95, используйте функцию MultiByteToWideChar, чтобы создать эти строки Unicode.

Windows 95: Система может поддерживать максимум 16,364 дескрипторов окна.

Смотри также
CreateWindowEx, DialogBox, DialogBoxIndirectParam, DialogBoxParam, DialogProc, DLGITEMTEMPLATE, DLGITEMTEMPLATEEX, DLGTEMPLATE, DLGTEMPLATEEX, EndDialog, MultiByteToWideChar, WM_INITDIALOG, WM_SETFONT

Размещение и совместимость DialogBoxIndirect

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					WinNT
Замечания по платформе			Не имеется


6.31.1.8 - Функция DialogBoxIndirectParam

(КосвенныйБлокДиалогаСПараметром)

Функция DialogBoxIndirectParam создает модальное диалоговое окно из шаблона блока диалога в памяти. Перед показом диалогового окна на экране, функция передает определяемое программой значение в процедуру диалогового окна как параметр lParam сообщения WM_INITDIALOG. Прикладная программа может использовать это значение для инициализации органов управления диалогового окна.

Синтаксис

int DialogBoxIndirectParam
(
    HINSTANCE hInstance,		// дескриптор экземпляра программы
    LPCDLGTEMPLATE hDialogTemplate,	// идентифицирует шаблон блока диалога
    HWND hWndParent,			// дескриптор окна владельца
    DLGPROC lpDialogFunc,		// указатель на процедуру блока диалога
    LPARAM dwInitParam			// значение инициализации
);

Параметры
hInstance
Идентифицирует экземпляр модуля, который создает диалоговое окно.
hDialogTemplate
Указатель на объект глобальной памяти, содержащий шаблон, который DialogBoxIndirectParam использует, чтобы создать диалоговое окно. Шаблон блока диалога состоит из заголовка, который описывает диалоговое окно, сопровождаемое одним или несколькими дополнительными блоками данных, которые описывают каждый из органов управления в диалоговом окне. Шаблон может использовать или стандартный или расширенный формат.
В стандартном шаблоне для диалогового окна, заголовком является структура DLGTEMPLATE, сопровождаемая дополнительными массивами переменной длины. Данные для каждого элемента управления состоят из структуры DLGITEMTEMPLATE, сопровождаемой дополнительными массивами переменной длины.
В расширенном шаблоне диалогового окна, заголовок использует формат DLGTEMPLATEEX, а определения органов управления используют формат DLGITEMTEMPLATEEX.
hWndParent
Идентифицирует окно, которое владеет блоком диалога.
lpDialogFunc
Указатель на процедуру диалогового окна. Для получения дополнительной информации о процедуре диалогового окна, см. статью DialogProc.
dwInitParam
Определяет значение, которое передается в диалоговое окно в параметре lParam сообщением WM_INITDIALOG.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - параметр nResult, заданный при вызове функции EndDialog, которая используется, чтобы завершить работу диалогового окна.
Если функция не выполняет задачу, возвращаемое значение – (минус)1.

Замечания
Функция DialogBoxIndirectParam использует функцию CreateWindowEx, чтобы создать диалоговое окно. Затем DialogBoxIndirectParam отправляет сообщение WM_INITDIALOG процедуре диалогового окна. Если шаблон определяет стиль DS_SETFONT, функция к тому же отправляет и сообщение WM_SETFONT процедуре диалогового окна. Функция отображает диалоговое окно на экране (независимо от того, определяет ли шаблон стиль WS_VISIBLE), блокирует окно владельца и запускает свой собственный цикл сообщений, чтобы извлекать и распределять сообщения диалоговому окну.

Размещение и совместимость DialogBoxIndirectParam

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					WinNT
Замечания по платформе			Не имеется


6.31.1.9 - Функция DialogBoxParam

(ПараметрыБлокаДиалога)

Функция DialogBoxParam создает модальный блок диалога из ресурса шаблона диалогового окна. Перед отображением на экране диалогового окна, функция передает определяемое программой значение в процедуру диалогового окна как параметр lParam сообщения WM_INITDIALOG. Прикладная программа может использовать это значение, чтобы инициализировать элементы управления блока диалога.

Синтаксис

int DialogBoxParam
(
    HINSTANCE hInstance,	// дескриптор экземпляра программы
    LPCTSTR lpTemplateName,	// идентифицирует шаблон блока диалога
    HWND hWndParent,		// дескриптор окна владельца
    DLGPROC lpDialogFunc,	// указатель на процедуру диалогового окна
    LPARAM dwInitParam 	// инициализационное значение
);

Параметры
hInstance
Идентифицирует экземпляр модуля, исполняемый файл, которого содержит шаблон диалогового окна.
lpTemplateName
Идентифицирует шаблон диалогового окна. Этот параметр является, или указателем на строку символов с нулем в конце, который определяет название шаблона блока диалога, или целочисленного значения, которое устанавливает идентификатор ресурса шаблона диалогового окна. Если параметр устанавливает идентификатор ресурса, его старшее слово должно быть нулевое, а младшее слово должно содержать этот идентификатор. Вы можете использовать макрокоманду MAKEINTRESOURCE, чтобы создать это значение.
hWndParent
Идентифицирует диалоговое окно, которое владеет блоком диалога.
lpDialogFunc
Указывает на процедуру диалогового окна. Для получения дополнительной информации о процедуре диалогового окна, см. статью функция повторного вызова DialogProc.
dwInitParam
Устанавливает значение, которое пересылает диалоговому окну сообщение WM_INITDIALOG в параметре lParam.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - значение параметра nResult, заданного при вызове функции EndDialog, которая завершает работу диалогового окна.
Если функция не выполняет задачу, возвращаемое значение – (минус)1.

Замечания
Функция DialogBoxParam использует функцию CreateWindowEx, чтобы создать диалоговое окно. Затем DialogBoxParam отправляет сообщение WM_INITDIALOG (и сообщение WM_SETFONT, если шаблон устанавливает стиль DS_SETFONT) в процедуру диалогового окна. Функция отображает на экране диалоговое окно (независимо от того, определяет ли шаблон стиль WS_VISIBLE), отключает окно владельца, и запускает свой собственный цикл сообщений, чтобы извлекать и распределять сообщения для блока диалога.
Когда процедура диалогового окна вызывает функцию EndDialog, DialogBoxParam разрушает диалоговое окно, заканчивает цикл сообщений, включает окно владельца (если оно ранее было включено) и возвращает параметр nResult, заданный процедурой диалогового окна, когда она вызвала EndDialog.
Windows 95: Система может поддерживать максимум 16,364 дескрипторов окна.

Смотри также
CreateWindowEx, DialogBox, DialogBoxIndirect, DialogBoxIndirectParam, DialogProc, EndDialog, MAKEINTRESOURCE, WM_INITDIALOG, WM_SETFONT

Размещение и совместимость DialogBoxParam

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					WinNT
Замечания по платформе			Не имеется


6.31.1.10 - Функция DialogProc

(ДиалоговаяПроцедура)

Функция DialogProc - определяемая программой функция повторного вызова, которая обрабатывает сообщения, отправленные модальному или немодальному диалоговому окну.

Синтаксис

BOOL CALLBACK DialogProc
(
    HWND hwndDlg,	// дескриптор диалогового окна
    UINT uMsg,	// сообщение
    WPARAM wParam,	// первый параметр сообщения
    LPARAM lParam	// второй параметр сообщения
);

Параметры
hwndDlg
Идентифицирует диалоговое окно.
uMsg
Определяет сообщение.
wParam
Определяет дополнительную конкретизирующую сообщение информацию.
lParam
Определяет дополнительную конкретизирующую сообщение информацию.

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

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

Смотри также
CreateDialog, CreateDialogIndirect, CreateDialogIndirectParam, CreateDialogParam, DefWindowProc, DialogBox, DialogBoxIndirect, DialogBoxIndirectParam, DialogBoxParam, SetFocus, WM_INITDIALOG

Размещение и совместимость DialogProc

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		Определяется пользователем
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		DLGPROC


6.31.1.11 - Функция EndDialog

(ЗакончитьДиалог)

Функция EndDialog разрушает модальное диалоговое окно, вынуждая систему закончить любую обработку для блока диалога.

Синтаксис

BOOL EndDialog
(
    HWND hDlg,	// дескриптор диалогового окна
    int nResult	// возвращаемое значение
);

Параметры
hDlg
Идентифицирует диалоговое окно, которое будет разрушено.
nResult
Устанавливает значение, которое будет возвращено прикладной программе от функции, которая создавала диалоговое окно.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение отлично от нуля.
Если функция не выполняет задачу, возвращаемое значение нулевое.

Замечания
Диалоговые окна, созданные функциями DialogBox, DialogBoxParam, DialogBoxIndirect и DialogBoxIndirectParam должны быть разрушены, при помощи использования функции EndDialog. Прикладная программа вызывает EndDialog изнутри процедуры диалогового окна; функция не должна использоваться для какой-либо другой цели.
Процедура диалогового окна может вызывать EndDialog в любое время, даже в ходе обработки сообщения WM_INITDIALOG. Если ваша прикладная программа вызывает функцию, в то время, когда обрабатывается WM_INITDIALOG, диалоговое окно разрушается до того, как оно покажется и прежде установки в нем фокуса ввода.
EndDialog не разрушает немедленно диалоговое окно. Вместо этого, она устанавливает флажок и позволяет процедуре диалогового окна возвратить управление системе. Система проверяет наличие флажка перед попыткой извлечь следующее сообщение из очереди прикладной программы. Если флажок установлен, система заканчивает цикл сообщений, уничтожает диалоговое окно и использует значение в nResult как возвращаемое значение от функции, которая создавала блок диалога.

Смотри также
DialogBox, DialogBoxIndirect, DialogBoxIndirectParam, DialogBoxParam, WM_INITDIALOG

Размещение и совместимость EndDialog

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


6.31.1.12 - Функция GetDialogBaseUnits

(ПолучитьОсновныеЕдиницыИзмеренияБлокаДиалога)

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

Синтаксис

LONG GetDialogBaseUnits(VOID)

Параметры
У этой функции нет параметров.

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

Замечания
Базовая единица измерения по горизонтали равна средней ширине, в пикселях, символов в системном шрифте; базовая единица измерения по вертикали равна высоте, в пикселях, шрифта. Кроме того, каждая базовая единица измерения по горизонтали равна 4 единицам измерения по горизонтали блока диалога; каждая базовая единица измерения по вертикали равна 8 единицам измерения по вертикали блока диалога. Поэтому, чтобы преобразовывать единицы измерения блока диалога в пиксели, прикладная программа применяет следующие формулы:

пиксельX = (единица диалогаХ * базовая единицаХ) / 4
пиксельY = (единица диалогаY * базовая единицаY) / 4

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

единица диалогаX = (пиксельХ * 4) / базовая единицаХ
единица диалогаY = (пиксельY * 4) / базовая единицаY

Умножение выполнено перед делением, чтобы избежать проблемы округления значения, если базовые единицы измерения не делятся на 4 или 8.

Смотри также
MapDialogRect

Размещение и совместимость GetDialogBaseUnits

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


6.31.1.13 - Функция GetDlgCtrlID

(ПлучитьИдентификаторЭлементаУправленияДиалога)

Функция GetDlgCtrlID возвращает значение идентификатора заданного органа управления.

Синтаксис

int GetDlgCtrlID
(
    HWND hwndCtl 	// дескриптор элемента управления
);

Параметры
hwndCtl
Идентифицирует орган управления.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - идентификатор элемента управления.
Если функция не выполняет задачу, возвращаемое значение ПУСТО (NULL). Недопустимое значение параметра hwndCtl, например, заставит функцию потерпеть неудачу.

Замечания
Функция GetDlgCtrlID принимает дескрипторы дочерних окон, а также дескрипторы органов управления в блоках диалога. Прикладная программа устанавливает идентификатор для дочернего окна, когда она создает окно, присваивая значение идентификатора параметру hmenu при вызове функции CreateWindow или CreateWindowEx.
Несмотря на то, что GetDlgCtrlID может возвратить значение, если hwndCtl идентифицирует окно верхнего уровня, окна верхнего уровня не могут иметь идентификаторы, и такое возвращаемое значение никогда не правильно.

Смотри также
CreateWindow, CreateWindowEx, GetDlgItem

Размещение и совместимость GetDlgCtrlID

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


6.31.1.14 - Функция GetDlgItem

(ПолучитьЭлементДиалога)

Функция GetDlgItem извлекает дескриптор органа управления в заданном диалоговом окне.

Синтаксис

HWND GetDlgItem
(
    HWND hDlg,	// дескриптор диалогового окна
    int nIDDlgItem	// идентификатор элемента управления
);

Параметры
hDlg
Идентифицирует диалоговое окно, которое содержит орган управления.
nIDDlgItem
Определяет идентификатор элемента управления, который будет возвращен обратно.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - дескриптор окна данного органа управления.
Если функция не выполняет задачу, возвращаемое значение ПУСТО (NULL), который указывает на недопустимый дескриптор диалогового окна или на несуществующий элемент управления.

Замечания
Вы можете использовать функцию GetDlgItem с любой парой окон родитель - дочь, а не только с блоками диалога. Пока параметр hDlg определяет родительское окно, а дочернее окно имеет уникальный идентификатор (определяемый параметром hMenu в функции CreateWindow или CreateWindowEx, которая создавала дочернее окно), GetDlgItem возвращает правильный дескриптор дочернему окну.

Смотри также
CreateWindow, CreateWindowEx, GetDlgItemInt, GetDlgItemText

Размещение и совместимость GetDlgItem

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


6.31.1.15 - Функция GetDlgItemInt

(ПолучитьЦелочисленноеЗначениеЭлементаДиалога)

Функция GetDlgItemInt переводит текст заданного органа управления в блоке диалога в целочисленное значение.

Синтаксис

UINT GetDlgItemInt
(
    HWND hDlg,		// дескриптор диалогового окна
    int nIDDlgItem,		// идентификатор элемента управления
    BOOL *lpTranslated,	// указывает на переменную, которая принимает
                // индикатор успешного завершения/неудачи
    BOOL bSigned		// определяет со знаком ли значение или без знака
);

Параметры
hDlg
Дескриптор диалогового окна, которое содержит представляющий интерес орган управления.
nIDDlgItem
Идентификатор элемента блока диалога, который определяет орган управления, текст которого должен быть преобразован.
lpTranslated
Указывает на Булеву переменную, которая принимает значение функции успешного завершения / неудачи. Значение ИСТИНА (TRUE) указывает на успешное завершение, значение ЛОЖЬ(FALSE) указывает на неудачу.
Этот параметр необязательный: он может быть значением ПУСТО (NULL). В этом случае, функция не возвращает информации об успехе или неудаче.
bSigned
Определяет, должна ли функция сначала проверять текст на знак "минус" и возвращать значение целого числа со знаком, если она находит его. Значение ИСТИНА (TRUE) устанавливает, что это должно быть сделано, ЛОЖЬ (FALSE), что этого делать не надо.

Возвращаемые значения
Если функция завершается успешно, переменная, указанная в lpTranslated устанавливается в значение ИСТИНА (TRUE), а возвращаемое значение – в преобразованное значение текста органа управления.
Если функция не выполняет задачу, переменная, указанная в lpTranslated устанавливается в значение ЛОЖЬ(FALSE), а возвращаемое значение нулевое. Обратите внимание, что, так как нуль - возможное значение после преобразования, возвращаемое значение нуль сам по себе не указывает на неудачу.
Если lpTranslated значение ПУСТО (NULL), функция не возвращает никакой информации относительно успеха или неудачи.
Если параметр bSigned имеет значение ИСТИНА (TRUE), то определяет, что значение, которое будет возвращено обратно, является значением целого числа со знаком и приводит возвращаемое значение к типу int.

Замечания
Функция GetDlgItemInt извлекает текст данного органа управления, отправляя элементу управления сообщение WM_GETTEXT. Функция преобразует извлеченный текст, очищая его от любых дополнительных пробелов в начале текста, а затем преобразует в десятичные цифры. Функция останавливает преобразование тогда, когда она достигает конца текста или сталкивается с нечисловым символом.
Если параметр bSigned имеет значение ИСТИНА (TRUE), функция GetDlgItemInt проверяет знак "минус" (-) в начале текста и преобразует текст в значение целого числа со знаком. Иначе, функция создает значение целого числа без знака.
Функция GetDlgItemInt возвращает значение нуль, если преобразованное значение большее, чем INT_MAX (для знаковых чисел) или UINT_MAX (для чисел без знака).

Смотри также
GetDlgCtrlID, GetDlgItem, GetDlgItemText, SetDlgItemInt

Размещение и совместимость GetDlgItemInt

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


6.31.1.16 - Функция GetDlgItemText

(ПолучитьТекстЭлементаДиалога)

Функция GetDlgItemText извлекает заголовок или текст, связанный с органом управления в диалоговом окне.

Синтаксис

UINT GetDlgItemText
(
    HWND hDlg,	// дескриптор диалогового окна
    int nIDDlgItem,	// идентификатор элемента управления
    LPTSTR lpString,	// адрес буфера для текста
    int nMaxCount	// максимальная длина строки
);

Параметры
hDlg
Идентифицирует диалоговое окно, которое содержит орган управления.
nIDDlgItem
Определяет идентификатор элемента управления, заголовок или текст которого должен быть извлечен.
lpString
Указывает на буфер, куда надо передать заголовок или текст.
nMaxCount
Определяет максимальную длину, в символах, строки, которая будет скопирована в буфер, указанный параметром lpString. Если длина строки превышает установленное ограничение, строка обрезается.

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

Замечания
Функция GetDlgItemText отправляет в орган управления сообщение WM_GETTEXT

Смотри также
GetDlgItemInt, SetDlgItemInt, SetDlgItemText, WM_GETTEXT

Размещение и совместимость GetDlgItemText

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


6.31.1.17 - Функция GetNextDlgGroupItem

(ПолучитьЭлементСледующейГруппыДиалога)

Функция GetNextDlgGroupItem извлекает дескриптор первого органа управления в группе элементов управления, которая предшествует (или следует за) заданному органу управления в диалоговом окне.

Синтаксис

HWND GetNextDlgGroupItem
(
    HWND hDlg,	// дескриптор диалогового окна
    HWND hCtl,	// дескриптор элемента управления
    BOOL bPrevious 	// флажок направления
);

Параметры
hDlg
Идентифицирует диалоговое окно, где производится поиск.
hCtl
Идентифицирует орган управления, который будет использован как начальная точка для поиска. Если этот параметр является значением ПУСТО (NULL), функция использует последний (или первый) элемент управления диалогового окна как отправной пункт для поиска.
bPrevious
Определяет, как функция должна искать группу органов управления в диалоговом окне. Если этот параметр - ИСТИНА (TRUE), функция осуществляет поиск от предыдущего элемента управления в группе. Если он - ЛОЖЬ(FALSE), функция осуществляет поиск от следующего органа управления в группе.

Возвращаемые значения
Если GetNextDlgGroupItem завершается успешно, возвращаемое значение - дескриптор предыдущего (или следующего) элемента управления в группе органов управления.

Замечания
Функция GetNextDlgGroupItem ищет органы управления по порядку (или в обратном порядке), как они были созданы в шаблоне диалогового окна. Первый элемент управления в группе должен иметь стиль WS_GROUP; все другие органы управления в группе, должны быть созданы последовательно за ним и не должны иметь стиля WS_GROUP.
Когда найден предыдущий элемент управления, функция возвращает значение первого, обнаруженного ею органа управления, который является видимым и не заблокированным. Если элемент управления, заданный параметром hCtl имеет стиль WS_GROUP, функция временно изменяет направление поиска, чтобы обнаружить первый орган управления, имеющий WS_GROUP стиль, затем продолжает поиск в первоначальном направлении, возвращая значение обнаруженного ею первого элемента управления, который является видимым и не заблокированным, или возвращает значение hwndCtrl если такой элемент управления не найден.
Когда найден следующий элемент управления, функция возвращает значение первого обнаруженного ею органа управления, который является видимым и не заблокированным, но не имеет стиля WS_GROUP. Если она обнаруживает элементом управления, имеющий стиль WS_GROUP, функция изменяет направление поиска, обнаруживает первый орган управления, имеющий стиль WS_GROUP и возвращает значение этого элемента управления, если он видим и не заблокирован. Иначе, функция возобновляет поиск в первоначальном направлении и возвращает значение обнаруженного ею первого элемента управления, который является видимым и не заблокированным, или возвращает значение hCtl, если такой орган управления не найден.

Смотри также
GetNextDlgTabItem

Размещение и совместимость GetNextDlgGroupItem

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


6.31.1.18 - Функция GetNextDlgTabItem

(ПолучитьСледующийЭлементДиалогаТабуляцией)

Функция GetNextDlgTabItem извлекает дескриптор первого органа управления, который имеет стиль WS_TABSTOP и предшествует (или следует) заданному элементу управления.

Синтаксис

HWND GetNextDlgTabItem
(
    HWND hDlg,	// дескриптор блока диалога
    HWND hCtl,	// дескриптор известного элемента управления
    BOOL bPrevious 	// флажок направления
);

Параметры
hDlg
Идентифицирует диалоговое окно, в котором будет производиться поиск.
hCtl
Идентифицирует орган управления, который будет использован как исходная точка для поиска. Если этот параметр имеет значение ПУСТО (NULL), функция использует последний (или первый) элемент управления в диалоговом окне как исходную точку для поиска.
bPrevious
Определяет, как функция должна искать в диалоговом окне. Если этот параметр - ИСТИНА (TRUE), функция ищет предыдущий элемент управления в блоке диалога. Если этот параметр - ЛОЖЬ(FALSE), функция ищет следующий орган управления в диалоговом окне.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - дескриптор предыдущего (или следующего) органа управления в окне, который имеет стиль WS_TABSTOP

Замечания
Функция GetNextDlgTabItem ищет элементы управления по порядку (или в обратном порядке), в котором они были созданы в шаблоне диалогового окна. Функция возвращает значение расположенного в нем первого органа управления, который является видимым, не заблокированным и имеет стиль WS_TABSTOP. Если такого элемент управления не существует, функция возвращает значение hCtl.

Смотри также
GetDlgItem, GetNextDlgGroupItem

Размещение и совместимость GetNextDlgTabItem

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


6.31.1.19 - Функция IsDialogMessage

(СообщениеДиалога)

Функция IsDialogMessage определяет, не предназначено ли сообщение для заданного блока диалога и, если это так, обрабатывает сообщение.

Синтаксис

BOOL IsDialogMessage
(
    HWND hDlg,		// дескриптор диалогового окна
    LPMSG lpMsg		// адрес структуры с сообщением
);

Параметры
hDlg
Идентифицирует диалоговое окно.
lpMsg
Указывает на структуру MSG, которая содержит сообщение, которое будет проверено.

Возвращаемые значения
Если сообщение было обработано, возвращаемое значение отлично от нуля.
Если сообщение не было обработано, возвращаемое значение нулевое.

Замечания
Несмотря на то, что функция IsDialogMessage предназначена для немодальных блоков диалога, Вы можете использовать ее с любым окном, которое содержит органы управления, дающие возможность окнам предусматривать тот же самый расклад клавиатуры, который используется в диалоговом окне.
Когда IsDialogMessage обрабатывает сообщение, она проверяет сообщения для клавиатуры и преобразовывает их в команды выбора для соответствующего диалогового окна. Например, когда нажата клавиша табуляции TAB, происходит выбор следующего органа управления или группы элементов управления, а когда нажата клавиша стрелка "вниз" DOWN ARROW, происходит выбор следующего элемента управления в группе.
Поскольку функция IsDialogMessage исполняет все необходимые преобразования и диспетчеризацию сообщений, сообщение, обработанное IsDialogMessage, нельзя передавать в функции TranslateMessage или DispatchMessage.
IsDialogMessage отправляет сообщения WM_GETDLGCODE процедуре диалогового окна, чтобы определить, какие клавиши должны быть обработаны.
IsDialogMessage может отправлять в окно сообщения DM_GETDEFID и DM_SETDEFID. Эти сообщения определены в заголовочном файле WINUSER.H как WM_USER и WM_USER + 1, так что возможны конфликты с определяемыми программой сообщениями, имеющими те же самые значения.

Смотри также
DispatchMessage, DM_GETDEFID, DM_SETDEFID, MSG, TranslateMessage, WM_GETDLGCODE, WM_USER

Размещение и совместимость IsDialogMessage

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


6.31.1.20 - Функция MapDialogRect

(ПреобразоватьПрямоугольникДиалога)

Функция MapDialogRect конвертирует (преобразует) заданные единицы измерения диалогового окна в экранные единицы (пиксели). Функция заменяет координаты в заданной структуре RECT преобразованными координатами, которые позволяют структуре быть использованной, чтобы создать диалоговое окно или установить орган управления в пределах блока диалога.

Синтаксис

BOOL MapDialogRect
(
    HWND hDlg,	// дескриптор диалогового окна
    LPRECT lpRect	// адрес структуры с прямоугольником
);

Параметры
hDlg
Идентифицирует диалоговое окно. Эта функция реагирует только на дескрипторы для блоков диалога, созданные одной из функций создания диалогового окна; дескрипторы для других окон не допустимы.
lpRect
Указывает на структуру RECT содержащую координаты диалогового окна, которые будут преобразованы.

Возвращаемые значения
Если функция завершилась успешно, возвращается значение отличное от нуля.
Если функция потерпела неудачу, возвращаемое значение - ноль.

Замечания
Функция MapDialogRect предполагает, что начальные координаты в структуре RECT представляют единицы измерения диалогового окна. Чтобы преобразовать эти координаты из единиц измерения блока диалога в пиксели, функция извлекает данные о текущих базовых единицах по горизонтали и вертикали для диалогового окна, а затем применяет следующие формулы:

левая     = (левая   * базовая единица X) / 4
правая    = (правая  * базовая единица X) / 4
верхняя   = (верхняя * базовая единица Y) / 8
нижняя    = (нижняя  * базовая единица Y) / 8

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

Смотри также
CreateDialog, CreateDialogIndirect, CreateDialogIndirectParam, CreateDialogParam, DialogBox, DialogBoxIndirect, DialogBoxIndirectParam, DialogBoxParam, GetDialogBaseUnits, RECT

Размещение и совместимость MapDialogRect

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


6.31.1.21 - Функция MessageBox

(ОкноСообщения)

Функция MessageBox создает, отображает на экране и оперирует окном сообщений. Окно сообщений содержит определяемое программой сообщение и заголовок, плюс любую комбинацию предопределенных пиктограмм и командных кнопок.

Синтаксис

int MessageBox
(
    HWND hWnd,		// дескриптор окна владельца
    LPCTSTR lpText,	// адрес текста в окне сообщений
    LPCTSTR lpCaption,	// адрес заголовка в окне сообщений
    UINT uType 		// стиль окна сообщений
);

Параметры
hWnd
Идентифицирует окно владельца блока сообщений, которым оно было создано. Если этот параметр имеет значение ПУСТО (NULL), у блока сообщения нет окна владельца.
lpText
Указывает на строку с символом нуля в конце, содержащую сообщение, которое должно быть отражено на экране.
lpCaption
Указывает на строку с символом нуля в конце, используемую для заголовка диалогового окна. Если этот параметр значение ПУСТО (NULL), то по умолчанию используется заголовок Ошибка (Error).
uType
Определяет установку битов флажков, которые обуславливают содержание и поведение диалогового окна. Этот параметр может быть комбинацией флажков из ниже следующих групп флажков.
Определите один из следующих флажков, чтобы указать кнопки, содержащиеся в окне сообщений:

  • MB_ABORTRETRYIGNORE - Окно сообщение содержит три командных кнопки: Прервать (Abort), Повторить (Retry) и Проигнорировать (Ignore).
  • MB_OK - Окно сообщение содержит одну командную кнопку: OK. Это по умолчанию.
  • MB_OKCANCEL - Окно сообщение содержит две командных кнопки: OK и Отменить (Cancel).
  • MB_RETRYCANCEL - Окно сообщение содержит две командных кнопки: Повторить (Retry) и Отменить (Cancel).
  • MB_YESNO - Окно сообщение содержит две командных кнопки: Да (Yes) и Нет (No).
  • MB_YESNOCANCEL - Окно сообщение содержит три командных кнопки: Да (Yes), Нет (No) и Отменить (Cancel).

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

  • MB_ICONEXCLAMATION, MB_ICONWARNING - В окне сообщений появляется пиктограмма восклицательного знака.
  • MB_ICONINFORMATION, MB_ICONASTERISK - В окне сообщений появляется пиктограмма, состоящая из символа i нижнего регистра в круге.
  • MB_ICONQUESTION - В окне сообщений появляется пиктограмма в виде знака вопроса.
  • MB_ICONSTOP,MB_ICONERROR,MB_ICONHAND - В окне сообщений появляется пиктограмма в виде стоп-сигнала.

Определите один из следующих флажков, чтобы указать заданную по умолчанию кнопку:

  • MB_DEFBUTTON1 - Первая кнопка - основная кнопка. MB_DEFBUTTON1 - значение по умолчанию, если не определена кнопка MB_DEFBUTTON2, MB_DEFBUTTON3 или MB_DEFBUTTON4.
  • MB_DEFBUTTON2 - Вторая кнопка - основная кнопка.
  • MB_DEFBUTTON3 - Третья кнопка - основная кнопка.
  • MB_DEFBUTTON4 - Четвертая кнопка - основная кнопка.

Определите один из следующих флажков, чтобы указать модальность диалогового окна:

  • MB_APPLMODAL - Пользователь должен ответить окну сообщений перед продолжением работы в окне, которое идентифицировано параметром hWnd. Однако, пользователь может перемещаться в окнах других прикладных программ и работать в этих окнах.В зависимости от иерархии окон в прикладной программе, пользователь может получить возможность, чтобы перемещаться в другие окна в пределах прикладной программы. Все дочерние окна родителя окна сообщений автоматически блокируются, однако выскакивающие окна - нет.MB_APPLMODAL - значение по умолчанию, если не определен флажок, ни MB_SYSTEMMODAL, ни MB_TASKMODAL.
  • MB_SYSTEMMODAL - То же самое, что и MB_APPLMODAL за исключением того, что окно сообщений имеет стиль WS_EX_TOPMOST. Используйте системно - модальные окна сообщений, чтобы уведомлять пользователя о серьезных, потенциально опасных ошибках, которые требуют немедленного внимания (например, запуск программы при нехватке памяти). Этот флажок не имеет никакого влияния на способность пользователя взаимодействовать с другими окнами, а не те, которые связаны с hWnd.
  • MB_TASKMODAL - То же самое, что и MB_APPLMODAL за исключением того, что все окна верхнего уровня, принадлежащие текущей задаче, заблокированы, если параметр hWnd имеет значение ПУСТО (NULL). Используйте этот флажок, когда вызывающая прикладная программа или библиотека не имеют доступного дескриптора окна, но все еще должны сохранять вводимые данные для других окон в текущей прикладной программе без приостановки работы других прикладных программ.

В дополнение, вы можете устанавливать ниже перечисленные флажки:
MB_DEFAULT_DESKTOP_ONLY
Рабочий стол, в настоящее время принимающий ввод, должен быть заданным по умолчанию рабочим столом; иначе, функция не выполняет задачу. Заданный по умолчанию рабочий стол - первая запущенная прикладная программа, после того, как пользователь вошел в систему.
MB_HELP
Прибавляет кнопку Справка (Help) в окно сообщений. Выбор кнопки Help или нажатие F1 генерирует событие появления Справки.
MB_RIGHT
Выравнивание текста справа.
MB_RTLREADING
Отображает на экране сообщение и текст заголовка с использованием порядка зеркального отображения для Еврейских и Арабских систем письменности.
MB_SETFOREGROUND
Окно сообщений становится приоритетным окном. Внутри Windows для окна сообщений вызывает функцию SetForegroundWindow.
MB_TOPMOST
Окно сообщений создается со стилем окна WS_EX_TOPMOST.
MB_SERVICE_NOTIFICATION
Только для Windows NT: вызывающая программа является обслуживающей по уведомлению пользователя о событии. Функция отображает окно сообщений на текущем активном рабочем столе, даже если никто из пользователей не вошел в систему компьютера.
Если этот флажок установлен, параметр hWnd должен иметь значение ПУСТО (NULL). Это такое окно сообщений, которое может появляться на другом рабочем столе, а не только на том, которое соответствует Wnd.
Для Windows NT версии 4.0, значение MB_SERVICE_NOTIFICATION изменилось. См. WINUSER.H для старых и новых значений. Windows NT 4.0 обеспечивает совместимость вниз для существующих ранее услуг, при помощи преобразования данных старых значений в новых значениях при реализации MessageBox и MessageBoxEx. Это преобразование данных делается только для исполнимых программ (.exe), которые имеют номер версии, как установлено компоновщиком, меньше чем 4.0.

Чтобы сформировать обслуживание, которое использует MB_SERVICE_NOTIFICATION и возможность запускать, и Windows NT 3.x и Windows NT 4.0, Вы имеете два пути:

  1. Во время компоновки, определите номер версии меньше чем 4.0; или
  2. Во время компоновки, определите версию 4.0.
Во время запуска, используйте функцию GetVersionEx, чтобы проверить системную версию. Тогда при продолжении запуска Windows NT 3.x, используйте MB_SERVICE_NOTIFICATION_NT3X; а для Windows NT 4.0, используйте MB_SERVICE_NOTIFICATION.
MB_SERVICE_NOTIFICATION_NT3X
Только для Windows NT: Это значение соответствует значению, определенному для MB_SERVICE_NOTIFICATION для версии 3.51 Windows NT.

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

  • IDABORT - Была выбрана кнопка Прервать (Abort).
  • IDCANCEL - Была выбрана кнопка Отменить (Cancel).
  • IDIGNORE - Была выбрана кнопка Игнорировать (Ignore).
  • IDNO - Была выбрана кнопка Нет (No).
  • IDOK - Была выбрана кнопка OK.
  • IDRETRY - Была выбрана кнопка Повторить (Retry).
  • IDYES - Была выбрана кнопка Да (Ye).

Если окно сообщений имеет кнопку Отменить (Cancel), функция возвращает значение IDCANCEL тогда, если или нажата клавиша ESC, или выбрана кнопка Cancel. Если у окна сообщений нет кнопки Cancel, нажатие на ESC не имеет никакого эффекта.

Смотри также
FlashWindow, MessageBeep, MessageBoxEx, MessageBoxIndirect, SetForegroundWindow

Размещение и совместимость MessageBox

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode	WinNT; 				Win95
Замечания по платформе			Не имеется


6.31.1.22 - Функция MessageBoxEx

(ОкноСообщенийРасширенное)

Функция MessageBoxEx создает, отображает на экране и оперирует окном сообщений. Окно сообщений содержит определяемое программой сообщение и заголовок, плюс любую комбинацию предопределенных пиктограмм и командных кнопок. Параметр wLanguageId определяет, какой устанавливается ресурс языка, который используется для предопределенных командных кнопок. Полное описание других параметров MessageBoxEx, см. MessageBox.

Синтаксис

int MessageBoxEx
(
    HWND hWnd,		// дескриптор окна владельца
    LPCTSTR lpText,	// адрес текста в окне сообщений
    LPCTSTR lpCaption,	// адрес заголовка в окне сообщений
    UINT uType 		// стиль окна сообщений
    WORD wLanguageId	// идентификатор языка
);

Параметры
hWnd
Идентифицирует окно владельца блока сообщений, которым оно было создано. Если этот параметр имеет значение ПУСТО (NULL), у блока сообщения нет окна владельца.
lpText
Указывает на строку с символом нуля в конце, содержащую сообщение, которое должно быть отражено на экране.
lpCaption
Указывает на строку с символом нуля в конце, используемую для заголовка диалогового окна. Если этот параметр значение ПУСТО (NULL), то по умолчанию используется заголовок Ошибка (Error).
uType
Определяет установку битов флажков, которые обуславливают содержание и поведение диалогового окна. Этот параметр может быть комбинацией флажков из ниже следующих групп флажков.
Определите один из следующих флажков, чтобы указать кнопки, содержащиеся в окне сообщений:

  • MB_ABORTRETRYIGNORE - Окно сообщение содержит три командных кнопки: Прервать (Abort), Повторить (Retry) и Проигнорировать (Ignore).
  • MB_OK - Окно сообщение содержит одну командную кнопку: OK. Это по умолчанию.
  • MB_OKCANCEL - Окно сообщение содержит две командных кнопки: OK и Отменить (Cancel).
  • MB_RETRYCANCEL - Окно сообщение содержит две командных кнопки: Повторить (Retry) и Отменить (Cancel).
  • MB_YESNO - Окно сообщение содержит две командных кнопки: Да (Yes) и Нет (No).
  • MB_YESNOCANCEL - Окно сообщение содержит три командных кнопки: Да (Yes), Нет (No) и Отменить (Cancel).

Определите один из следующих флажков, чтобы отобразить иконку в окне сообщений:

  • MB_ICONEXCLAMATION, MB_ICONWARNING - В окне сообщений появляется пиктограмма восклицательного знака.
  • MB_ICONINFORMATION, MB_ICONASTERISK - В окне сообщений появляется пиктограмма, состоящая из символа i нижнего регистра я в круге.
  • MB_ICONQUESTION - В окне сообщений появляется пиктограмма в виде знака вопроса.
  • MB_ICONSTOP,MB_ICONERROR,MB_ICONHAND - В окне сообщений появляется пиктограмма в виде стоп-сигнала.

Определите один из следующих флажков, чтобы указать заданную по умолчанию кнопку:

  • MB_DEFBUTTON1 - Первая кнопка - основная кнопка. MB_DEFBUTTON1 - значение по умолчанию, если не определена кнопка MB_DEFBUTTON2, MB_DEFBUTTON3 или MB_DEFBUTTON4.
  • MB_DEFBUTTON2 - Вторая кнопка - основная кнопка.
  • MB_DEFBUTTON3 - Третья кнопка - основная кнопка.
  • MB_DEFBUTTON4 - Четвертая кнопка - основная кнопка.

Определите один из следующих флажков, чтобы указать модальность диалогового окна:

  • MB_APPLMODAL - Пользователь должен ответить окну сообщений до продолжения работы в окне, которое идентифицировано параметром hWnd. Однако, пользователь может перемещаться в окнах других прикладных программ и работать в этих окнах. В зависимости от иерархии окон в прикладной программе, пользователь может получить возможность, чтобы перемещаться в другие окна в пределах прикладной программы. Все дочерние окна родителя окна сообщений автоматически блокируются, но всплывающие окна - нет. MB_APPLMODAL - значение по умолчанию, если не определен флажок ни MB_SYSTEMMODAL ни MB_TASKMODAL.
  • MB_SYSTEMMODAL - То же самое, что и MB_APPLMODAL за исключением того, что окно сообщений имеет стиль WS_EX_TOPMOST. Используйте системно - модальные окна сообщений, чтобы уведомить пользователя о серьезных, потенциально опасных ошибках, которые требуют немедленного внимания (например, запуск программы при нехватке памяти). Этот флажок не имеет никакого влияния на способность пользователя взаимодействовать с другими окнами, чем те, которые связаны с hWnd.
  • MB_TASKMODAL - То же самое, что и MB_APPLMODAL за исключением того, что все окна верхнего уровня, принадлежащие текущей задаче, заблокированы, если параметр hWnd имеет значение ПУСТО (NULL). Используйте этот флажок, когда вызывающая прикладная программа или библиотека не имеют доступного дескриптора окна, но все еще должно сохранять вводимые данные для других окон в текущей прикладной программе без приостановки работы других прикладных программ.

В дополнение, вы можете устанавливать ниже перечисленные флажки:
MB_DEFAULT_DESKTOP_ONLY
Рабочий стол, в настоящее время принимающий ввод должен быть заданным по умолчанию рабочим столом; иначе, функция не выполняет задачу. Заданный по умолчанию рабочий стол - первая запущенная прикладная программа, после того, как пользователь вошел в систему.
MB_HELP
Прибавляет кнопку Справка (Help) в окно сообщений. Выбор кнопки Help или нажатие F1 генерирует событие появления Справки.
MB_RIGHT
Выравнивание текста справа.
MB_RTLREADING
Отображает на экране сообщение и текст заголовка с использованием порядка зеркального отображения для Еврейских и Арабских систем письменности.
MB_SETFOREGROUND
Окно сообщений становится приоритетным окном. Внутри, Windows для окна сообщений вызывает функцию SetForegroundWindow.
MB_TOPMOST
Окно сообщений создается со стилем окна WS_EX_TOPMOST.
MB_SERVICE_NOTIFICATION
Только для Windows NT: вызывающая программа является обслуживающей по уведомлению пользователя о событии. Функция отображает окно сообщений на текущем активном рабочем столе, даже если никто из пользователей не вошел в систему компьютера.
Если этот флажок установлен, параметр hWnd должен иметь значение ПУСТО (NULL). Это такое окно сообщений, которое может появляться на другом рабочем столе, а не только на том, которое соответствует hWnd.
Для Windows NT версии 4.0, значение MB_SERVICE_NOTIFICATION изменилось. См. WINUSER.H для старых и новых значений. Windows NT 4.0 обеспечивает совместимость вниз для существующих ранее услуг, при помощи отображения старых значений в новых значениях при реализации MessageBox и MessageBoxEx. Это отображение сделано только для исполнимых программ (.exe), которые имеют номер версии, как установлено компоновщиком, меньше чем 4.0.
Чтобы сформировать обслуживание, которое использует MB_SERVICE_NOTIFICATION и возможность запускать, и Windows NT 3.x и Windows NT 4.0, Вы имеете два пути.
1. Во время компоновки, определите номер версии меньше чем 4.0; или
2. Во время компоновки, определите версию 4.0. В во время запуска, используйте функцию GetVersionEx, чтобы проверить системную версию. Тогда при продолжении запуска Windows NT 3.x, используйте MB_SERVICE_NOTIFICATION_NT3X; а для Windows NT 4.0, используйте MB_SERVICE_NOTIFICATION.
MB_SERVICE_NOTIFICATION_NT3X
Только для Windows NT: Это значение соответствует значению, определенному для MB_SERVICE_NOTIFICATION для версии 3.51 Windows NT.

wLanguageId
Определяет язык, на котором будет отображаться текст, содержащийся в предопределенных командных кнопках. Это значение должно быть в форме, возвращающей макрокомандой MAKELANGID.
За перечнем идентификаторов языка, поддерживаемых Win32, см. Идентификаторы Языка. Обратите внимание, что каждый привязанный к конкретной стране выпуск Windows обычно содержит ресурсы только для ограниченного набора языков. Таким образом, например, американская версия предлагает LANG_ENGLISH, французская версия предлагает LANG_FRENCH, немецкая версия предлагает LANG_GERMAN и японская версия предлагает LANG_JAPANESE. Каждая версия предлагает LANG_NEUTRAL. Это ограничивает установку значений, которые могут использоваться с параметром wLanguageId. Перед определением идентификатора языка, Вы должны перечислить территории, которые установлены на системе.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - значение элемента меню отличное от нуля, возвращенное диалоговым окном:

  • IDABORT - Была выбрана кнопка Прервать (Abort).
  • IDCANCEL - Была выбрана кнопка Отменить (Cancel).
  • IDIGNORE - Была выбрана кнопка Игнорировать (Ignore).
  • IDNO - Была выбрана кнопка Нет (No).
  • IDOK - Была выбрана кнопка OK.
  • IDRETRY - Была выбрана кнопка Повторить (Retry).
  • IDYES - Была выбрана кнопка Да (Ye).

Если окно сообщений имеет кнопку Отменить (Cancel), функция возвращает значение IDCANCEL тогда, когда или нажата клавиша ESC, или выбрана кнопка Cancel. Если у окна сообщений нет кнопки Cancel, нажатие на ESC не имеет никакого эффекта.

Замечания
Когда Вы используете системно - модальное окно сообщений, чтобы указать, что система имеет мало памяти, строки, переданные как параметры lpText и lpCaption не должны быть приняты из файла ресурса, так как попытка загрузить ресурс может потерпеть неудачу.
Когда прикладная программа вызывает MessageBoxEx и устанавливает флажки MB_ICONHAND и MB_SYSTEMMODAL в параметре uType, Win32 API отображает на экране законченное окно сообщений независимо от доступной памяти. Когда эти флажки установлены, Windows ограничивает длину текста окна сообщений до одной строки.
Если Вы создаете окно сообщений, в то время когда присутствует диалоговое окно, дескриптор блока диалога используется как параметр hWnd. Параметр hWnd не должен идентифицировать дочернее окно, типа диалогового окна.
Windows 95: Система может поддерживать максимум 16,364 дескрипторов окна.

Смотри также
MAKELANGID, MessageBeep, MessageBox, MessageBoxIndirect, SetForegroundWindow

Размещение и совместимость MessageBoxEx

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					WinNT; Win95
Замечания по платформе			Не имеется


6.31.1.23 - Функция SendDlgItemMessage

(ПередатьСообщениеЭлементуДиалоговогоОкна)

Функция SendDlgItemMessage отправляет сообщение заданному элементу управления в диалоговом окне.

Синтаксис

LONG SendDlgItemMessage
(
    HWND hDlg,		// дескриптор диалогового окна
    int nIDDlgItem,	// идентификатор элемента управления
    UINT Msg,		// сообщение для передачи
    WPARAM wParam,		// первый параметр сообщения
    LPARAM lParam 		// второй параметр сообщения
);

Параметры
hDlg
Идентифицирует диалоговое окно, которое содержит орган управления.
nIDDlgItem
Определяет идентификатор органа управления, который принимает сообщение.
Msg
Определяет сообщение, которое будет отправлено.
wParam
Определяет дополнительную конкретизирующую сообщение информацию.
lParam
Определяет дополнительную конкретизирующую сообщение информацию.

Возвращаемые значения
Возвращаемое значение определяет результат обработки сообщения и зависит от переданного сообщения.

Замечания
Функция SendDlgItemMessage не возвращает значение до тех пор, пока сообщение не будет обработано.
Использование SendDlgItemMessage идентично извлечению дескриптора заданного элемента управления и вызова функции SendMessage.

Смотри также
SendMessage

Размещение и совместимость SendDlgItemMessage

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					WinNT
Замечания по платформе			Не имеется


6.31.1.24 - Функция SetDlgItemInt

(УстановитьЦелочисленныеЗначенияЭлементаДиалоговогоОкна)

Функция SetDlgItemInt устанавливает текст органа управления в диалоговом окне, которое представлено строкой определенных целочисленных значений.

Синтаксис

BOOL SetDlgItemInt
(
    HWND hDlg,			// дескриптор диалогового окна
    int nIDDlgItem,		// идентификатор элемента управления
    UINT uValue,			// значения для установки
    BOOL bSigned 			// индикатор знакового и без знакового значения
);

Параметры
hDlg
Идентифицирует диалоговое окно, который содержит орган управления.
nIDDlgItem
Определяет элемент управления, который должен быть изменен.
uValue
Устанавливает целочисленное значение, использующееся для создания элемента текста.
bSigned
Определяет, со знаком или без знака параметр uValue. Если этот параметр - ИСТИНА (TRUE), uValue со знаком. Если этот параметр - ИСТИНА (TRUE) и uValue - меньше чем нуль, знак "минус" помещается перед первой цифрой в строке. Если этот параметр - ЛОЖЬ(FALSE), uValue без знака.

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

Замечания
Чтобы установить новый текст, эта функция отправляет сообщение WM_SETTEXT заданному органу управления.

Смотри также
GetDlgItemInt, SetDlgItemText, WM_SETTEXT

Размещение и совместимость SetDlgItemInt

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


6.31.1.25 - Функция SetDlgItemText

(УстановитьТекстЭлементаДиалоговогоОкна)

Функция SetDlgItemText устанавливает заголовок или текст органа управления в диалоговом окне.

Синтаксис

BOOL SetDlgItemText
(
    HWND hDlg,		// дескриптор диалогового окна
    int nIDDlgItem,	// идентификатор элемента управления
    LPCTSTR lpString 	// текст для установки
);

Параметры
hDlg
Идентифицирует диалоговое окно, которое содержит элемент управления.
nIDDlgItem
Идентифицирует орган управления с заголовком или текстом, который должен быть установлен.
lpString
Указывает на строку с символом нуля в конце, которая содержит текст для копирования в орган управления.

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

Замечания
Функция SetDlgItemText отправляет сообщение WM_SETTEXT заданному органу управления.

Смотри также
GetDlgItemInt, GetDlgItemText, SetDlgItemInt, WM_SETTEXT

Размещение и совместимость SetDlgItemText

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					WinNT
Замечания по платформе			Не имеется


6.31.1.26 - Функция MessageBoxIndirect

(КосвенноеОкноСообщений)

[Теперь поддерживается в Windows NT]

Функция MessageBoxIndirect создает, отображает и оперирует окном сообщений. Окно сообщений содержит определяемый программой текст сообщения и заголовок, любую пиктограмму, и любую комбинацию предопределенных командных кнопок.

Синтаксис

int MessageBoxIndirect
(
    LPMSGBOXPARAMS lpMsgBoxParams	// адрес структуры для параметров
            // окна сообщений
);

Параметры
lpMsgBoxParams
Указатель на структуру MSGBOXPARAMS, которая содержит информацию, используемую для показа на экране окна сообщений.

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

  • IDABORT - Была выбрана аварийная кнопка (Abort).
  • IDCANCEL - Была выбрана кнопка Прервать (Cancel).
  • IDIGNORE - Была выбрана кнопка Игнорировать (Ignore).
  • IDNO - Была выбрана кнопка Нет (No).
  • IDOK - Была выбрана кнопка Согласен (OK).
  • IDRETRY - Была выбрана кнопка Повторить (Retry).
  • IDYES - Была выбрана кнопка Да (Yes).

Если окно сообщений имеет кнопку Отменить (Cancel), функция возвращает значение IDCANCEL, если или нажата клавиша ESC, или кнопка выбрана Cancel. Если окно сообщений не имеет кнопки Cancel, нажатие на ESC не оказывает никакого влияния.

Замечания
Когда Вы используете системно - модальное окно сообщений, чтобы указать, что у системы мало памяти, строки, указанные элементами lpszText и lpszCaption структуры MSGBOXPARAMS не должны быть приняты из файла ресурса, потому что попытка загрузить ресурс может потерпеть неудачу.
Когда прикладная программа вызывает MessageBoxIndirect и устанавливает флажки MB_ICONHAND и MB_SYSTEMMODAL в элементе dwStyle структуры MSGBOXPARAMS, Windows показывает на экране законченное окно сообщений независимо от доступной памяти. Когда эти флажки установлены, Windows ограничивает длину текста в окне сообщений до трех строк. Windows автоматически не разрывает строки, чтобы подстроить их под окно сообщений, такая строка сообщения должна содержать символы перевода каретки, чтобы разрывать строки в соответствующих местах.
Если Вы создаете окно сообщений, в то время, когда присутствует диалоговое окно, используйте дескриптор блока диалога как параметр hWnd. Параметр hWnd не должен идентифицировать дочернее окно, типа органа управления в диалоговом окне.
Windows 95: Система может поддерживать максимум 16,364 дескрипторов окна.

Смотри также
MessageBox, MessageBoxEx, MSGBOXPARAMS

Размещение и совместимость MessageBoxIndirect

Windows NT				Да
Win95					Да
Win32s					Нет
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					WinNT
Замечания по платформе			Не имеется


6.31.2 - Структуры диалогового окна

Ниже перечисленные структуры используются для создания и управления диалоговым окном и органами управления в составе блоков диалога.

DLGITEMTEMPLATE
DLGTEMPLATE
MSGBOXPARAMS

Ниже следующие разделы описывают псевдоструктуры, которые не определены в каком-либо стандартном заголовочном файле. Эти разделы представлены здесь, чтобы объяснить формат расширенного шаблона для диалогового окна.
DLGITEMTEMPLATEEX
DLGTEMPLATEEX


6.31.2 1 - Структура DLGITEMTEMPLATE

Структура DLGITEMTEMPLATE определяет габариты и стиль органа управления в диалоговом окне. Одна или несколько этих структур объединяются со структурой DLGTEMPLATE, чтобы сформировать стандартный шаблон для блока диалога.

Синтаксис

typedef struct
{				// dlit
    DWORD style;
    DWORD dwExtendedStyle;
    short x;
    short y;
    short cx;
    short cy;
    WORD  id;
} DLGITEMTEMPLATE;

Члены структуры
style
Определяет стиль органа управления. Этот элемент структуры может быть комбинацией значений стиля окна (типа WS_BORDER) и одного или нескольких значений стиля органов управления (типа BS_PUSHBUTTON и ES_LEFT).
dwExtendedStyle
Определяет расширенные стили для окна. Этот член структуры не используется, чтобы создавать органы управления в блоках диалога, однако прикладные программы, которые используют шаблоны диалогового окна, могут использовать его, чтобы создать другие типы окон.
x
Устанавливает x-координату, в единицах измерения диалогового окна, левого верхнего угла органа управления. Эта координата - всегда относительно левого верхнего угла рабочей области блока диалога.
y
Устанавливает y-координату, в единицах измерения диалогового окна, левого верхнего угла органа управления. Эта координата - всегда относительно левого верхнего угла рабочей области блока диалога.
cx
Устанавливает ширину, в единицах измерения диалогового окна, органа управления.
cy
Устанавливает высоту, в единицах измерения диалогового окна, органа управления.
id
Определяет идентификатор элемента управления.

Замечания
В стандартном шаблоне для диалогового окна, структура DLGITEMTEMPLATE всегда непосредственно сопровождается тремя массивами переменной длины, определяющими класс, заголовок и данные для создания органа управления. Каждый массив состоит из одного или большего количества 16-разрядных элементов.
Каждая структура DLGITEMTEMPLATE в шаблоне должна быть выровнена на по границе двойного слова (DWORD). Массивы класса и заголовка должны быть выровнены по границе слова (WORD). Массив данных создания должен быть выровнен по границе двойного слова (DWORD).
Непосредственно после каждой структуры DLGITEMTEMPLATE идет массив класса, который идентифицирует орган управления класса окна. Если первый элемент этого массива - какое-либо значение, отличающееся от 0xFFFF, система обрабатывает массив как строку Уникода с нулевым символом в конце, которая определяет название зарегистрированного класса окна. Если первый элемент - 0xFFFF, массив имеет один дополнительный элемент, который устанавливает порядковое значение предопределенного системой класса. Порядковое значение может быть одно из следующих значений атома:

  • 0x0080 - Кнопка (Button)
  • 0x0081 - Редактируемое окно (Edit)
  • 0x0082 - Статическое окно (Static)
  • 0x0083 - Окно со списком (List box)
  • 0x0084 - Линейка прокрутки (Scroll bar)
  • 0x0085 - Кобинированное окно (Combo box)

После массива класса идет массив заголовка, который содержит начальный текст или идентификатор ресурса органа управления. Если первый элемент этого массива - 0xFFFF, массив имеет один дополнительный элемент, который определяет порядковое число ресурса, типа пиктограммы, в исполняемом файле. Вы можете использовать идентификатор ресурса для органов управления, таких как пиктограмма статического органа управления, который загружает и показывает на экране пиктограмму или другой ресурс, а не текст. Если первый элемент - какое-либо значение, отличающееся от 0xFFFF, система обрабатывает массив как строку Уникода с нулевым символом в конце, которая определяет начальный текст.
Массив данных для создания начинается со следующей границы ДВОЙНОГО СЛОВА (DWORD) после массива заголовка. Эти данные для создания могут иметь любой размер и формат. Если первый байт массива данных создания - не нуль, он указывает размер, в байтах, данных для создания (включая байт размера). Оконная процедура органа управления должна получить возможность, чтобы интерпретировать данные. Когда система создает орган управления, она передает указатель на эти данные в параметре lParam сообщения WM_CREATE, которые она отправляет органу управления.
Если Вы определяете строки символов в массивах класса и заголовка, Вы должны использовать строки Уникода. Чтобы создать код, который работает, и в Windows NT и в Windows 95, используйте функцию MultiByteToWideChar для генерации этих строк Уникода.
Члены структуры x, y, cx, и cy устанавливают значения в единицах измерения диалогового окна. Вы можете преобразовывать эти значения в растровые элементы (пиксели), используя функцию MapDialogRect.

Смотри также
CreateDialogIndirect, CreateDialogIndirectParam, CreateWindowEx, DialogBoxIndirect, DialogBoxIndirectParam, DLGITEMTEMPLATEEX, DLGTEMPLATE, DLGTEMPLATEEX, MapDialogRect, MultiByteToWideChar, WM_CREATE

Размещение и совместимость DLGITEMTEMPLATE

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека		-
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


6.31.2 2 - Структура DLGTEMPLATE

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

Синтаксис

typedef struct
{
    DWORD style;
    DWORD dwExtendedStyle;
    WORD cdit;
    short x;
    short y;
    short cx;
    short cy;
} DLGTEMPLATE;

Члены структуры
style
Определяет стиль диалогового окна. Этот член структуры может быть комбинацией значений стиля окна (таких как WS_CAPTION и WS_SYSMENU) и одного или большего количества следующих значений стиля блока диалога:

  • DS_3DLOOK - Дает диалоговому окну не полужирный шрифт и выводит трехмерные рамки вокруг окон органа управления в блоке диалога. Стиль DS_3DLOOK требуется только прикладным программам, базирующимся на Win32, откомпилированным для версий Windows более ранних, чем Windows 95 или Windows NT 4.0. Система автоматически применяет трехмерный вид к диалоговым окнам, созданным прикладными программами, откомпилированными для текущих версий Windows.
  • DS_ABSALIGN - Указывает, что координаты диалогового окна - экранные координаты. Если этот стиль не определен, Windows предполагает, что они - координаты рабочей области.
  • DS_CENTER - Центрирует диалоговое окно в рабочей области; то есть в области, не затененной блоком.
  • DS_CENTERMOUSE - Центрирует курсор мыши в диалоговом окне.
  • DS_CONTEXTHELP - Включает вопросительный знак в строку заголовка диалогового окна. Когда пользователь щелкает по вопросительному знаку, курсор изменяется на вопросительный знак с указателем. Если пользователь затем щелкает по органу управления в диалоговом окне, элемент управления принимает сообщение WM_HELP. Орган управления должен передать сообщение в процедуру диалогового окна, которая должна вызвать функцию WinHelp, используя команду HELP_WM_HELP. Прикладная программа Справка (Help) отображает на экране выскакивающее окно, которое обычно содержит справку для органа управления. Обратите внимание, что DS_CONTEXTHELP - только символ- заменитель шаблона. Когда создается диалоговое окно, система проверяет наличие флажка включения для DS_CONTEXTHELP и, если он имеется, прибавляет WS_EX_CONTEXTHELP к расширенному стилю блока диалога. WS_EX_CONTEXTHELP не может быть использован со стилями WS_MAXIMIZEBOX или WS_MINIMIZEBOX.
  • DS_CONTROL - Создает диалоговое окно, которое работает также как дочернее окно другого диалогового окна, очень похоже на страницу в окне свойств. Этот стиль позволяет пользователю перемешаться при помощи клавиши TAB среди органов управления окна дочернего блока диалога, использовать его клавиши - ускорители и так далее.
  • DS_FIXEDSYS - Вынуждает диалоговое окно использовать SYSTEM_FIXED_FONT вместо значения по умолчанию SYSTEM_FONT. SYSTEM_FIXED_FONT - шрифт фиксированной ширины, совместимый с Системным шрифтом в версиях Windows ранее чем 3.0.
  • DS_LOCALEDIT - Применяется только в 16-разрядных прикладных программах. Этот стиль предписывает полям редактирования в диалоговом окне распределять память из сегмента данных прикладной программы. Иначе, редактируемые поля распределяют память для хранения данных из объекта глобальной памяти.
  • DS_MODALFRAME - Создает диалоговое окно с рамкой модального блока диалога, которая может быть объединена со строкой заголовка и Системным меню, путем установки стилей WS_CAPTION и WS_SYSMENU.
  • DS_NOFAILCREATE - Только для Windows 95: Создает диалоговое окно, даже если происходят ошибки - например, если дочернее окно не может быть создано или, если система не может создать специальный сегмент данных для поля редактирования.
  • DS_NOIDLEMSG - Подавляет сообщения WM_ENTERIDLE, которые Windows, иначе передал бы владельцу диалогового окна, в то время когда блок диалога отображался на экране.
  • DS_SETFONT - Указывает, что заголовок шаблона блока диалога содержит дополнительные данные, определяющие шрифт, который используется для текста в рабочей области и органах управления диалогового окна. Данные о шрифте начинаются по границе слова (WORD), которая следует за массивом заголовка. Они определяет 16-разрядное значение размера в пунктах и строку с именем шрифта Уникода. Если возможно, система создает шрифт согласно заданным величинам. Затем система передает дескриптор шрифта в блок диалога и в каждый орган управления, отправляя им сообщение WM_SETFONT. Если этот стиль не определен, шаблон диалогового окна не включает данные о шрифте.
  • DS_SETFOREGROUND - Вынуждает систему использовать функцию SetForegroundWindow, чтобы привести диалоговое окно в активный режим.
  • DS_SYSMODAL - Создает системно - модальный блок диалога. Этот стиль заставляет диалоговое окно иметь стиль WS_EX_TOPMOST, а в остальном, он не оказывает никакого влияния на блок диалога или поведение других окон в системе, когда диалоговое окно показывается на экране.

dwExtendedStyle
Определяет расширенные стили для окна. Этот член структуры не используется для создания диалогового окна, но прикладные программы, которые используют шаблоны блока диалога, могут использовать его, чтобы создать другие типы окон.
cdit
Определяет число элементов в диалоговом окне.
x
Устанавливает x-координату, в единицах измерения диалогового окна, левого верхнего угла блока диалога.
y
Устанавливает y-координату, в единицах измерения диалогового окна, левого верхнего угла блока диалога.
cx
Устанавливает ширину, в единицах измерения диалогового окна, блока диалога.
cy
Устанавливает высоту, в единицах измерения диалогового окна, блока диалога.

Замечания
В стандартном шаблоне для блока диалога, структура DLGTEMPLATE всегда непосредственно сопровождается тремя массивами переменной длины, которые определяют меню, класс и заголовок для диалогового окна. Когда дается стиль DS_SETFONT, эти массивы сопровождаются к тому же 16-разрядным значением, определяющим размер в пунктах, а другой массив переменной длины определяет название шрифта. Каждый массив состоит из одного или большего числа 16-разрядных элементов. Меню, класс, заголовок и массивы шрифта должны быть выровнены по границам СЛОВА (WORD).
Непосредственно после структуры DLGTEMPLATE - массив меню, который идентифицирует ресурс меню для блока диалога. Если первый элемент этого массива - 0x0000, у диалогового окна нет никакого меню, и массив не имеет никаких других элементов. Если первый элемент - 0xFFFF, массив имеет один дополнительный элемент, который определяет порядковое значение ресурса меню в исполняемом файле. Если первый элемент имеет какое-либо другое значение, система обрабатывает массив как строку Уникода с нулевым символом в конце, которая определяет название ресурса меню в исполняемом файле.
После массива меню - массив класса, который идентифицирует класс окна органа управления. Если первый элемент массива - 0x0000, система использует предопределенный класс диалогового окна для блока диалога, и массив не имеет никаких других элементов. Если первый элемент - 0xFFFF, массив имеет один дополнительный элемент, который определяет порядковое значение предопределенного системного класса окна. Если первый элемент имеет любое другое значение, система обрабатывает массив как строку Уникода с нулевым символом в конце, которая устанавливает имя зарегистрированного класса окна.
После массива класса - массив заголовка, определяющий строку Уникода с нулевым символом в конце, которая содержит заголовок диалогового окна. Если первый элемент этого массива - 0x0000, диалоговое окно не имеет никакого заголовка, а массив не имеет никаких других элементов.
16-разрядное значение размера шрифта в пунктах и массив шрифта следуют за массивом заголовка, но только тогда, если элемент style структуры определяет стиль DS_SETFONT. Значение кегля в пунктах определяет размер в пунктах шрифта, который используется для текста в диалоговом окне и его органах управления. Массив шрифта является строкой Уникода с нулевым символом в конце, определяющей название гарнитуры для шрифта. Когда эти значения даются, Windows создает шрифт, имеющий данный размер и гарнитуру (если возможно) и отправляет сообщение WM_SETFONT процедуре диалогового окна и оконным процедурам элементов управления, поскольку оно создает блок диалога и органы управления.
После заголовка DLGTEMPLATE в стандартном шаблоне диалогового окна имеется одна или несколько структур DLGITEMTEMPLATE, которые определяют габариты и стиль органов управления в блоке диалога. Член структуры cdit определяет число структур DLGITEMTEMPLATE в шаблоне. Эти структуры DLGITEMTEMPLATE должны быть выровнены по границам ДВОЙНОГО СЛОВА (DWORD).
Если Вы определяете строки символов в меню, классе, заголовке, или массивах шрифта, Вы должны использовать строки Уникода. Чтобы создать код, который работает, и в Windows NT, и в Windows 95, используйте функцию MultiByteToWideChar, чтобы генерировать эти строки Уникода.
Члены структуры x, y, cx, и cy устанавливают значения в единицах измерения диалогового окна. Вы можете преобразовывать эти значения в экранные единицы измерения (пиксели), используя функцию MapDialogRect.

Смотри также
CreateDialogIndirect, CreateDialogIndirectParam, DialogBoxIndirect, DialogBoxIndirectParam, DLGITEMTEMPLATE, DLGITEMTEMPLATEEX, DLGTEMPLATEEX, MapDialogRect, MultiByteToWideChar

Размещение и совместимость DLGTEMPLATE

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


6.31.2 3 - Структура MSGBOXPARAMS

Структура MSGBOXPARAMS содержит информацию, используемую для отображения окна сообщений. Эту структуру использует функция MessageBoxIndirect.

Синтаксис

typedef struct
{
    UINT cbSize;
    HWND hwndOwner;
    HINSTANCE hInstance;
    LPCSTR lpszText;
    LPCSTR lpszCaption;
    DWORD dwStyle;
    LPCSTR lpszIcon;
    DWORD dwContextHelpId;
    MSGBOXCALLBACK lpfnMsgBoxCallback;
    DWORD dwLanguageId;
} MSGBOXPARAMS, *PMSGBOXPARAMS, FAR *LPMSGBOXPARAMS;

Члены структуры
cbSize
Определяет размер структуры в байтах.
hwndOwner
Идентифицирует окно владельца. Этот член структуры может быть значением ПУСТО (NULL).
hInstance
Идентифицирует экземпляр, содержащий ресурс пиктограммы, идентифицированный членом структуры lpszIcon и строковый ресурс, идентифицированный членом структуры lpszText или lpszCaption.
lpszText
Указывает на строку с символом нуля в конце, или идентификатор строкового ресурса, который содержит сообщение, которое будет отображено на экране.
lpszCaption
Указывает на строку с символом нуля в конце или идентификатор строкового ресурса, который содержит заголовок окна сообщений. Если этот член структуры имеет значение ПУСТО (NULL), по умолчанию используется заголовок, Ошибка (Error).
dwStyle
Определяет установку битов флажков, которые определяют содержание и поведение диалогового окна. Этот член структуры может быть комбинацией флажков, описанных параметром uType функции MessageBoxEx.
Кроме того, Вы можете определить флажок MB_USERICON, если хотите, чтобы окно сообщений отобразило на экране пиктограмму, заданную членом структуры lpszIcon.
lpszIcon
Идентифицирует ресурс пиктограммы. Этот параметр может быть или строкой с символом нуля в конце, или целочисленным идентификатором ресурса, переданным макрокомандой MAKEINTRESOURCE.
Чтобы загрузить одну из предопределенных пиктограмм Windows, установите член структуры hInstance в значение ПУСТО (NULL), а lpszIcon установите в одно из значений, перечисленных в функции LoadIcon.
Этот элемент игнорируется, если член структуры dwStyle не определяет флажок MB_USERICON.
dwContextHelpId
Идентифицирует контекст Справки (Help). Если происходит событие Справки (Help), это значение определено в структуре HELPINFO, которое окно сообщений передает окну владельца или функции повторного вызова.
lpfnMsgBoxCallback
Указывает на функцию повторного вызова, которая обрабатывает события Справки для окна сообщений. Функция повторного вызова имеет следующую форму:

VOID CALLBACK MsgBoxCallback(LPHELPINFO lpHelpInfo);

Если этот элемент имеет значение ПУСТО (NULL), когда происходят события Справки окно сообщений отправляет окну владельца сообщения WM_HELP.
dwLanguageId
Определяет язык, на котором отображается текст, содержащийся в предопределенных командных кнопках. Это значение должно быть в форме, возвращаемой макрокомандой MAKELANGID.
Список идентификаторов языка, поддерживаемых Win32, можно посмотреть в статье Идентификаторы Языка. Обратите внимание, что каждый привязанный к конкретной стране выпуск Windows обычно содержит ресурсы только для ограниченного набора языков. Таким образом, например, Американская версия предлагает вниманию LANG_ENGLISH, Французская версия предлагает вниманию LANG_FRENCH, Немецкая версия предлагает вниманию LANG_GERMAN и Японская версия предлагает вниманию LANG_JAPANESE. Каждая версия предлагает LANG_NEUTRAL. Это ограничивает набор значений, которые могут быть использованы параметром wLanguageId. Перед определением идентификатора языка, Вы должны перечислить местности, которые установлены в системе.

Смотри также
HELPINFO, LoadIcon, MAKEINTRESOURCE, MAKELANGID, MessageBoxEx, MessageBoxIndirect, WM_HELP

Размещение и совместимость MSGBOXPARAMS

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			Winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


6.31.2 4 - Псевдоструктура DLGITEMTEMPLATEEX

Структура DLGITEMTEMPLATEEX не определена в каком-либо стандартном заголовочном файле. Определение структуры предусмотрено здесь, чтобы объяснить формат расширенного шаблона для диалогового окна.

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

Синтаксис

//typedef struct {
//	DWORD helpID;
//	DWORD exStyle;
//	DWORD style;
//	short x;
//	short y;
//	short cx;
//	short cy;
//	WORD id;
//	sz_Or_Ord windowClass; // название или порядковое числительное класса окна
//	sz_Or_Ord title;       // строка заголовка или порядковое числительное ресурса
//	WORD   extraCount;     // байты, сопутствующие данным создания
//} DLGITEMTEMPLATEEX;

Члены структуры
helpID
Определяет идентификатор справочного контекста для органа управления. Когда система передает сообщение WM_HELP, она посылает значение helpID в член dwContextId структуры HELPINFO.
dwExtendedStyle
Определяет расширенные стили для окна. Этот элемент структуры не используется для создания органов управления в блоках диалога, но в прикладных программах, которые используют шаблоны диалогового окна, его можно использовать, чтобы создать другие типы окон.
style
Определяет стиль органа управления. Этот элемент структуры может быть комбинацией значений стиля окна (типа WS_BORDER) и одного или нескольких значений стиля органа управления (типа BS_PUSHBUTTON и ES_LEFT).
x
Определяет x-координату, в единицах измерения диалогового окна, левого верхнего угла элемента управления. Эта координата - всегда относительно левого верхнего угла рабочей области блока диалога.
y
Определяет y-координату, в единицах измерения диалогового окна, левого верхнего угла элемента управления. Эта координата - всегда относительно левого верхнего угла рабочей области блока диалога.
cx
Определяет ширину, в единицах измерения диалогового окна, органа управления.
cy
Определяет высоту, в единицах измерения диалогового окна, элемента управления.
id
Определяет идентификатор органа управления.
windowClass
Определяет массив переменной длины 16-разрядных элементов, который идентифицирует класс окна органа управления. Если первый элемент этого массива является каким-либо значением, отличающимся от 0xFFFF, система обрабатывает массив как строку Уникода с нулевым символом в конце, которая определяет название зарегистрированного класса окна.
Если первый элемент является 0xFFFF, массив имеет один дополнительный элемент, который определяет порядковое значение предопределенного системного класса. Порядковым числом может быть одно из следующих значений атома.

  • 0x0080 - Кнопка (Button)
  • 0x0081 - Редактируемое окно (Edit)
  • 0x0082 - Статическое окно (Static)
  • 0x0083 - Окно со списком (List box)
  • 0x0084 - Линейка прокрутки (Scroll bar)
  • 0x0085 - Комбинированное окно (Combo box)

title
Определяет массив переменной длины 16-разрядных элементов, который содержит начальный текст или идентификатор ресурса органа управления. Если первый элемент этого массива - 0xFFFF, массив имеет один дополнительный элемент, который определяет порядковое число, которое идентифицирует ресурс, типа пиктограммы, в исполняемом файле. Вы можете использовать идентификатор ресурса для органов управления, типа статических элементов управления пиктограммы, которые загружают и показывают пиктограмму или другой ресурс, а не текст.
Если первый элемент - какое-либо значение, отличающееся от 0xFFFF, система обрабатывает массив как строку Уникода с нулевым символом в конце, которая определяет начальный текст.
extraCount
Устанавливает число байтов данных создания, которые следуют за этим членом структуры. Если он имеет значение большее, чем нуль, данные создания начинаются со следующей границы ДВОЙНОГО СЛОВА (DWORD). Эти данные создания могут иметь любой размер и формат. Оконная процедура органа управления должна получить возможность, чтобы интерпретировать данные. Когда система создает орган управления, она передает указатель на эти данные в параметре lParam сообщения WM_CREATE, который передается элементу управления.

Замечания
Расширенный шаблон для диалогового окна состоит из заголовка DLGTEMPLATEEX, сопровождаемого структурой DLGITEMTEMPLATEEX для каждого органа управления в блоке диалога.
Каждая структура DLGITEMTEMPLATEEX должна быть выровнена по границе ДВОЙНОГО СЛОВА (DWORD). Массивы переменной длины windowClass и title должны быть выровнены по границам СЛОВА (WORD). Массив данных создания, если он имеется, должен быть выровнен по границе ДВОЙНОГО СЛОВА (DWORD).
Если Вы определяете в строки символов в массивах windowClass и title, Вы должны использовать строки Уникода. Чтобы создать код, который работает, и в Windows NT и в Windows 95, используйте функцию MultiByteToWideChar, чтобы генерировать эти строки Уникода.
Члены структуры x, y, cx и cy определяют значения в единицах измерения диалогового окна. Вы можете преобразовывать эти значения в экранные единицы измерения (пиксели), используя функцию MapDialogRect.

Смотри также
CreateDialogIndirect, CreateDialogIndirectParam, CreateWindowEx, DialogBoxIndirect, DialogBoxIndirectParam, DLGITEMTEMPLATE, DLGTEMPLATE, DLGTEMPLATEEX, MapDialogRect, MultiByteToWideChar

Размещение и совместимость DLGITEMTEMPLATEEX

Windows NT				Да
Win95					Да
Win32s					Нет
Импортируемая библиотека			-
Заголовочный файл				-
Unicode					Нет
Замечания по платформе			Не имеется


6.31.2 5 - Псевдоструктура DLGTEMPLATEEX

Структура DLGTEMPLATEEX не определена в каком-либо стандартном заголовочном файле. Определение структуры предусмотрено здесь, чтобы объяснить формат расширенного шаблона для диалогового окна.
Расширенный шаблон диалогового окна начинается с заголовка DLGTEMPLATEEX, который описывает блок диалога и определяет число органов управления в диалоговом окне. Для каждого элемента управления в блоке диалога, расширенный шаблон диалогового окна имеет блок данных, который использует формат DLGITEMTEMPLATEEX, чтобы описать орган управления.

//typedef struct {
//	WORD dlgVer;
//	WORD signature;
//	DWORD helpID;
//	DWORD exStyle;
//	DWORD style;
//	WORD cDlgItems;
//	short x;
//	short y;
//	short cx;
//	short cy;
//	sz_Or_Ord menu;         	// название или порядковое число ресурса меню
//	sz_Or_Ord windowClass; 	// название или порядковое число  класса окна
//	WCHAR title[titleLen];   	// строка заголовка диалогового окна
//	short pointsize;       	// только если установлен флаг DS_SETFONT
//	short weight;          	// только если установлен флаг DS_SETFONT
//	short bItalic;         	// только если установлен флаг DS_SETFONT
//	WCHAR font[fontLen]; 	// название гарнитуры, если установлен флаг DS_SETFONT
//} DLGTEMPLATEEX;

Члены структуры
dlgVer
Указывает, не является ли шаблон расширенным шаблоном диалогового окна. Значение 0xFFFF указывает на расширенный шаблон блока диалога. В этом случае, член структуры signature определяет номер версии шаблона. Если dlgVer - любое другое значение, а не 0xFFFF, это - стандартный шаблон, который использует структуры DLGTEMPLATE и DLGITEMTEMPLATE.
signature
Определяет номер версии расширенного шаблона диалогового окна. Этот член структуры должен установить 1.
helpID
Определяет идентификатор контекста справки для окна блока диалога. Когда система отправляет сообщение WM_HELP, она передает это значение в член dwContextId структуры HELPINFO.
exStyle
Определяет расширенные стили для окна. Этот элемент структуры не используется для создания диалогового окна, однако, прикладные программы, которые используют шаблоны блока диалога, могут использовать его, чтобы создать другие типы окон.
style
Определяет стиль диалогового окна. Этот член структуры может быть комбинацией значений стиля окна (типа WS_CAPTION и WS_SYSMENU) и одного или нескольких следующих значений стиля блока диалога.

  • DS_3DLOOK - Предоставляет диалоговому окну не полужирный шрифт и чертит трехмерные рамки вокруг окон органов управления в блоке диалога.Стиль DS_3DLOOK требуется только прикладным программам, базирующимися на Win32, откомпилированным для версий Windows более ранних, чем Windows 95 или Windows NT 4.0. Система автоматически применяет трехмерный вид к диалоговым окнам, созданным прикладными программами, откомпилированными для текущих версий Windows.
  • DS_ABSALIGN - Указывает, что координаты диалогового окна - экранные координаты. Если этот стиль не определен, система обрабатывает их как координаты пользователя.
  • DS_CENTER - Центрирует диалоговое окно в рабочей области; то есть в области, не закрытой содержимым.
  • DS_CENTERMOUSE - Центрирует курсор мыши в диалоговом окне.
  • DS_CONTEXTHELP - Включает вопросительный знак в область заголовка диалогового окна. Когда пользователь щелкает по вопросительному знаку, курсор изменяется в вопросительный знак с указателем. Если пользователь затем щелкает по органу управления в блоке диалога, элемент управления принимает сообщение WM_HELP. Орган управления должен передать сообщение в процедуру диалогового окна, которая должна вызвать функцию WinHelp, используя команду HELP_WM_HELP. Справка (Help) прикладной программы показывает на экране выскакивающее окно, которое обычно содержит справку на орган управления. Обратите внимание, что DS_CONTEXTHELP является только меткой - заместителем. Когда блок диалога создается, система проверяет наличие DS_CONTEXTHELP и, если он там имеется, добавляет WS_EX_CONTEXTHELP к расширенному стилю диалогового окна. Вы не можете использовать стиль WS_EX_CONTEXTHELP со стилями WS_MAXIMIZEBOX или WS_MINIMIZEBOX.
  • DS_CONTROL - Создает диалоговое окно, которое работает также как дочернее окно другого диалогового окна, очень похожее на страницу в окне свойств. Этот стиль позволяет пользователю перемещаться при помощи клавиши TAB среди окон органов управления дочернего блока диалога, использовать его клавиши - ускорители и так далее.
  • DS_FIXEDSYS - Вынуждает диалоговое окно использовать SYSTEM_FIXED_FONT вместо значения по умолчанию SYSTEM_FONT. SYSTEM_FIXED_FONT - шрифт моноширинный (фиксированной ширины), совместимый с Системным шрифтом в версиях Windows ранее чем 3.0.
  • DS_LOCALEDIT - Применяется только в 16-разрядных прикладных программах. Этот стиль предписывает полям редактирования в диалоговом окне назначать память в сегменте данных приложения. Иначе, поле редактирования назначает память в объекте глобальной памяти.
  • DS_MODALFRAME - Создает диалоговое окно с модальной структурой блока диалога, которое может быть объединено с областью заголовка и Системным меню, при помощи установки стилей WS_CAPTION и WS_SYSMENU.
  • DS_NOFAILCREATE - Windows 95 только: Создает диалоговое окно, даже если происходят ошибки - например, если дочернее окно не может быть создано или если система не может создать специальный сегмент данных для поля редактирования.
  • DS_NOIDLEMSG - Подавляет сообщения WM_ENTERIDLE, которые Windows, иначе отправил бы владельцу диалогового окна, в то время кода блок диалога показывается на экране.
  • DS_SETFONT - Указывает, что заголовок расширенного шаблона диалогового окна DLGTEMPLATEEX содержит четыре дополнительных члена (pointsize, weight, bItalic и font), которые описывают шрифт, использующийся для текста в рабочей области и органах управления блока диалога. Если возможно, система создает шрифт согласно значениям, заданным в этих членах. Затем система передает дескриптор шрифта в диалоговое окно и в каждый орган управления, отправляя им сообщение WM_SETFONT.Если этот стиль не определен, расширенный шаблон диалогового окна не включает члены pointsize, weight, bItalic и font.
  • DS_SETFOREGROUND - Вынуждает систему использовать функцию SetForegroundWindow, чтобы привести диалоговое окно в режим переднего плана.
  • DS_SYSMODAL - Создает системно - модальный блок диалога. Этот стиль вынуждает диалоговое окно иметь стиль WS_EX_TOPMOST. Иначе, он не имеет никакого влияния на блок диалога или поведение других окон в системе, когда блок диалога отображается на экране.

cDlgItems
Определяет число органов управления в диалоговом окне.
x
Определяет x-координату, в единицах измерения диалогового окна, левого верхнего угла блока диалога.
y
Определяет y-координату, в единицах измерения диалогового окна, левого верхнего угла блока диалога.
cx
Определяет ширину, в единицах измерения диалогового окна, блока диалога.
cy
Определяет высоту, в единицах измерения диалогового окна, блока диалога.
menu
Определяет массив переменной длины 16-разрядных элементов, который идентифицирует ресурс меню для диалогового окна. Если первый элемент этого массива - 0x0000, у блока диалога нет меню, а у массива нет других элементов. Если первый элемент - 0xFFFF, массив имеет один дополнительный элемент, который определяет порядковое значение ресурса меню в исполняемом файле. Если первый элемент имеет какое-либо другое значение, система обрабатывает массив как строку Уникода с нулевым символом в конце, которая определяет название ресурса меню в исполняемом файле.
windowClass
Определяет массив переменной длины 16-разрядных элементов, который идентифицирует класс диалогового окна. Если первый элемент этого массива является 0х0000, система использует предопределенный класс диалогового окна, а у массива нет других элементов. Если первый элемент является 0xFFFF, массив имеет один дополнительный элемент, который определяет порядковое значение предопределенного системного класса окна. Если первый элемент этого массива является каким-либо другим значением, система обрабатывает массив как строку Уникода с нулевым символом в конце, которая определяет название зарегистрированного класса окна.
title
Определяет строку Уникода с символом нуля в конце, которая содержит заголовок диалогового окна. Если первый элемент этого массива - 0x0000, у блока диалога нет никакого заголовка, а у массива нет никаких других элементов.
pointsize
Определяет размер шрифта в пунктах, который используется для текста в диалоговом окне и его органах управления. Члены pointsize, weight, bItalic и font присутствуют в расширенном шаблоне блока диалога, только тогда, если член структуры style определяет стиль DS_SETFONT.
weight
Определяет толщину шрифта в диапазоне от 0 до 1000. Она может быть любой из значений, перечисленных для члена lfWeight структуры LOGFONT. Этот член структуры присутствует, только тогда, если член style определяет DS_SETFONT.
bItalic
Указывает, является ли шрифт курсивным. Если это значение - ИСТИНА (TRUE), шрифт курсивный. Этот элемент структуры присутствует, только тогда, если член style определяет DS_SETFONT.
font
Определяет строку Уникода с символом нуля в конце, которая содержит название гарнитуры для шрифта. Этот элемент структуры присутствует, только тогда, если член style определяет DS_SETFONT.

Замечания
Вы можете использовать расширенный шаблон диалогового окна вместо стандартного шаблона блока диалога в функциях CreateDialogIndirectParam и DialogBoxIndirectParam и макрокомандах CreateDialogIndirect и DialogBoxIndirect. Стандартный шаблон диалогового окна использует структуры DLGTEMPLATE и DLGITEMTEMPLATE.
После заголовка в расширенном шаблоне диалогового окна DLGTEMPLATEEX располагаются одна или несколько структур DLGITEMTEMPLATEEX, которые описывают органы управления блока диалога. Член структуры cDlgItems определяет число структур DLGITEMTEMPLATEEX в шаблоне.
Каждая структура DLGITEMTEMPLATEEX в шаблоне должна быть выровнена по границе ДВОЙНОГО СЛОВА (DWORD). Если член style определяет стиль DS_SETFONT, первая структура DLGITEMTEMPLATEEX начинается на первой границе ДВОЙНОГО СЛОВА (DWORD) после строки font. Если стиль DS_SETFONT не установлен, первая структура начинается на первой границе ДВОЙНОГО СЛОВА (DWORD) после строки title.
Массивы menu, windowClass, title и font должны быть выровнены по границам СЛОВА (WORD).
Если Вы определяете строки символов в массивах menu, windowClass, title и font, Вы должны использовать строки Уникода. Чтобы создать код, который работает, и в Windows NT и в Windows 95, используйте функцию MultiByteToWideChar, чтобы генерировать эти строки Уникода.
Члены структуры x, y, cx, и cy определяют значения в единицах измерения диалогового окна. Вы можете преобразовать эти значения в экранные единицы измерения (пиксели), используя функцию MapDialogRect.

Смотри также
CreateDialogIndirect, CreateDialogIndirectParam, DialogBoxIndirect, DialogBoxIndirectParam, DLGITEMTEMPLATE, DLGITEMTEMPLATEEX, DLGTEMPLATE, MapDialogRect, MultiByteToWideChar, WM_SETFONT

Размещение и совместимость DLGTEMPLATEEX

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			-
Unicode				Нет
Замечания по платформе		Не имеется


6.31.3 - Сообщения диалогового окна

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


6.31.3 1 - Сообщение DM_GETDEFID

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

Синтаксис

DM_GETDEFID

Параметры
У этого сообщения нет параметров.

Возвращаемые значения
Если командная кнопка по умолчанию существует, в старшем слове возвращается значение содержащее величину DC_HASDEFID, а в младшем слове содержится идентификатор органа управления. В противном случае, возвращаемое значение - ноль

Замечания
Это сообщение обрабатывает функция DefDlgProc.

Смотри также
DefDlgProc, DM_SETDEFID

Размещение и совместимость DM_GETDEFID

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


6.31.3 2 Сообщение DM_REPOSITION

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

Синтаксис

DM_REPOSITION
wParam = 0;
lParam = 0;

Параметры
У этого сообщения нет параметров.

Возвращаемые значения
У этого сообщения нет возвращаемых значений.

Замечания
Это сообщение не имеет влияния, если блок диалога дочернее окно.

Размещение и совместимость DM_REPOSITION

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


6.31.3 3 Сообщение DM_SETDEFID

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

Синтаксис

DM_SETDEFID
wParam = idControl; // идентификатор созданной по умолчанию (выделенной) командной кнопки

Параметры
idControl
Значение wParam. Определяет идентификатор командной кнопки органа управления, которая станет «по умолчанию» (выделенной).

Замечания
Это сообщение обрабатывается функцией DefDlgProc. Чтобы установить заданную по умолчанию командную кнопку, функция может отправить сообщения WM_GETDLGCODE и BM_SETSTYLE в данный орган управления и текущей заданной по умолчанию командной кнопке.
Использование сообщения DM_SETDEFID может привести к показу больше чем одной кнопки, имеющей статус «по умолчанию» командной кнопки. Когда Windows поднимает диалоговое окно, она выводит сначала командную кнопку из шаблона блока диалога с рамкой состояния «по умолчанию» (выделенной). Отправка сообщения DM_SETDEFID для изменения кнопки по умолчанию не всегда удаляет рамку состояния «по умолчанию» из первой командной кнопки. В этих случаях, прикладная программа должна передать сообщение BM_SETSTYLE, чтобы изменить первоначальный стиль рамки командной кнопки.

Возвращаемые значения
Возвращаемое значение всегда ИСТИНА (TRUE).

Смотри также
BM_SETSTYLE, DefDlgProc, DM_GETDEFID, EM_SETLIMITTEXT, WM_GETDLGCODE

Размещение и совместимость DM_SETDEFID

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


6.31.3 4 - Сообщение WM_CTLCOLORDLG

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

Синтаксис

WM_CTLCOLORDLG
hdcDlg = (HDC) wParam;   // дескриптор диалогового окна контекста отображения
hwndDlg = (HWND) lParam; // дескриптор диалогового окна

Параметры
hdcDlg
Значение wParam. Идентифицирует контекст устройства для диалогового окна.
hwndDlg
Значение lParam. Идентифицирует диалоговое окно.

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

Действие по умолчанию
Функция DefWindowProc выбирает заданные по умолчанию системные цвета для диалогового окна.

Замечания
Сообщение WM_CTLCOLORDLG никогда не передается между потоками. Оно отправляется только в пределах одного потока.
Обратите внимание, что сообщение WM_CTLCOLORDLG отправляется непосредственно диалоговому окну; все другие сообщения WM_CTLCOLOR* отправляются владельцу органа управления.

Смотри также
DefWindowProc, RealizePalette, SelectPalette, WM_CTLCOLORBTN, WM_CTLCOLOREDIT, WM_CTLCOLORLISTBOX, WM_CTLCOLORMSGBOX, WM_CTLCOLORSCROLLBAR, WM_CTLCOLORSTATIC

Размещение и совместимость WM_CTLCOLORDLG

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			-
Заголовочный файл			winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


6.31.3 5 - Сообщение WM_CTLCOLORMSGBOX

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

Синтаксис

WM_CTLCOLORMSGBOX
hdcMB = (HDC) wParam;   // дескриптор контекста, который отображает окно сообщений
hwndMB = (HWND) lParam; // дескриптор окна сообщений

Параметры
hdcMB
Значение wParam. Идентифицирует контекст устройства для окна сообщений.
hwndMB
Значение lParam. Идентифицирует окно сообщений.

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

Действия по умолчанию
Функция DefWindowProc выбирает заданные по умолчанию системные цвета для окна сообщений.

Замечания
Сообщение WM_CTLCOLORMSGBOX никогда не передается между потоками. Оно отправляется только в пределах одного потока.

Смотри также
DefWindowProc, RealizePalette, SelectPalette, WM_CTLCOLORBTN, WM_CTLCOLORDLG, WM_CTLCOLOREDIT, WM_CTLCOLORLISTBOX, WM_CTLCOLORSCROLLBAR, WM_CTLCOLORSTATIC

Размещение и совместимость WM_CTLCOLORMSGBOX

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


6.31.3 6 - Сообщение WM_ENTERIDLE

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

Синтаксис

WM_ENTERIDLE
fuSource = wParam;    		// флажок "источник пустой"
hwnd = (HWND) lParam;		// дескриптор диалогового окна или окна владельца

Параметры
fuSource
Значение wParam. Определяет, является ли сообщение ответом отображаемого на экране диалогового окна или меню. Этот параметр может быть одно из следующих значений:

  • MSGF_DIALOGBOX - Система является свободной, потому что диалоговое окно отображено на экране.
  • MSGF_MENU - Система является свободной, потому что меню отображено на экране.

hwnd
Значение lParam. Содержит дескриптор диалогового окна (если fuSource - MSGF_DIALOGBOX) или окна, содержащего отображенное меню (если fuSource - MSGF_MENU).

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

Замечания
Функция DefWindowProc возвращает значение нуль.

Смотри также
DefWindowProc

Размещение и совместимость WM_ENTERIDLE

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			-
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


6.31.3 7 - Сообщение WM_GETDLGCODE

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

Синтаксис
WM_GETDLGCODE

Параметры
У этого сообщения нет параметров

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

  • DLGC_BUTTON - Кнопка (Button).
  • DLGC_DEFPUSHBUTTON - Командная кнопка по умолчанию (Default push button).
  • DLGC_HASSETSEL - Сообщение EM_SETSEL.
  • DLGC_RADIOBUTTON - Радио-кнопка (Radio button).
  • DLGC_STATIC - Статический элемент управления (Static control).
  • DLGC_UNDEFPUSHBUTTON - Командная кнопка не по умолчанию (Nondefault push button).
  • DLGC_WANTALLKEYS - Все вводимые данные с клавиатуры.
  • DLGC_WANTARROWS - Клавиши со стрелками.
  • DLGC_WANTCHARS - Сообщения WM_CHAR.
  • DLGC_WANTMESSAGE - Все вводимые данные с клавиатуры (прикладная программа передает это сообщение органу управления).
  • DLGC_WANTTAB - Клавиша TAB.

Действие по умолчанию
Функция DefWindowProc возвращает значение нуль.

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

Смотри также
DefWindowProc, EM_SETSEL, WM_CHAR

Размещение и совместимость WM_GETDLGCODE

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			-
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


6.31.3 8 - Сообщение WM_INITDIALOG

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

Синтаксис

WM_INITDIALOG
hwndFocus = (HWND) wParam;	 	// дескриптор блока диалога принявшего
                    // фокус ввода
lInitParam = lParam;       		// параметры инициализации

Параметры
hwndFocus
Значение wParam. Идентифицирует орган управления, который по умолчанию принимает фокус клавиатуры. Windows устанавливает заданный по умолчанию фокус клавиатуры только тогда, если процедура диалогового окна возвратит значение ИСТИНА (TRUE).
lInitParam
Значение lParam. Определяет дополнительные данные инициализации. Эти данные передаются в Windows как параметр lParamInit при вызове функций CreateDialogIndirectParam, CreateDialogParam, DialogBoxIndirectParam или DialogBoxParam, используемых для создания диалогового окна. Этот параметр нулевой, если использована другая функция создания блока диалога.

Возвращаемые значения
Процедура диалогового окна должна возвратить значение ИСТИНА (TRUE), чтобы направить Windows на установку фокуса клавиатуры в орган управления, заданный параметром hwndFocus. Иначе, она должна возвратить значение ЛОЖЬ(FALSE), чтобы не допустить Windows к установке заданного по умолчанию фокуса клавиатуры.

Замечания
Орган управления, который принимает заданный по умолчанию фокус клавиатуры, является всегда первым элементом управления в диалоговом окне, которое является видимым, не заблокированным, и оно имеет стиль WS_TABSTOP. Когда процедура диалогового окна возвращает значение ИСТИНА (TRUE), Windows отмечает этот орган управления, чтобы гарантировать, чтобы процедура не отключит его. Если оно заблокировано, Windows устанавливает фокус клавиатуры в следующем элементе управления, который является видимым, не заблокированным, и имеет стиль WS_TABSTOP.
Прикладная программа может возвратить значение ЛОЖЬ(FALSE) только тогда, если она установила фокус клавиатуры в одном из органов управления диалогового окна.

Смотри также
CreateDialogIndirectParam, CreateDialogParam, DialogBoxIndirectParam, DialogBoxParam, SetFocus

Размещение и совместимость WM_INITDIALOG

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			-
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


6.31.3 9 - Сообщение WM_NEXTDLGCTL

Сообщение WM_NEXTDLGCTL отправляется процедуре диалогового окна, чтобы установить фокус клавиатуры в другом органе управления диалогового окна.

Синтаксис

WM_NEXTDLGCTL
wCtlFocus = wParam;           			// идентифицирует орган управления для фокуса
fHandle = (BOOL) LOWORD(lParam); 			// флажок дескриптора wParam

Параметры
wCtlFocus
Значение wParam. Если параметр fHandle - ИСТИНА (TRUE), параметр wCtlFocus идентифицирует орган управления, который принимает фокус. Если fHandle - ЛОЖЬ(FALSE), wCtlFocus - флажок, который указывает, принимает ли следующий или предыдущий орган управления со стилем WS_TABSTOP фокус. Если параметр wCtlFocus нулевой, следующий элемент управления принимает фокус; иначе, фокус принимает предыдущий орган управления со стилем WS_TABSTOP.
fHandle
Значение lParam. Содержит флажок, который указывает, как Windows использует параметр wCtlFocus. Если параметр fHandle - ИСТИНА (TRUE), wCtlFocus - дескриптор, связанный с органом управления, который принимает фокус; иначе, wCtlFocus - флажок, который указывает, принимает ли следующий или предыдущий элемент управления со стилем WS_TABSTOP фокус.

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

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

Смотри также
PostMessage, SendMessage, SetFocus

Размещение и совместимость WM_NEXTDLGCTL

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			-
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется
Предыдущий Шаг


2.1 - Каретки

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

1_1.gif (3448 b)

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

Прикладная программа, написанная для Microsoft ® Windows ® может создавать каретку, показывать или скрывать её, перемещать каретку и изменять частоту мерцания.

Следующий Шаг


2.2 - О каретках

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

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

Прошедшее время, в миллисекундах, требуемых, чтобы инвертировать каретку называется частотой мерцания (blink time). Пользователь может устанавливать частоту мерцания каретки, используя Панель Управления, а прикладные программы должны соблюдать параметры настройки, которые выбрал пользователь. Прикладная программа может определять частоту мерцания каретки, используя функцию GetCaretBlinkTime. Если Вы пишите прикладную программу, которая позволяет пользователю корректировать частоту мерцания, типа апплета Панели Управления, используйте функцию SetCaretBlinkTime, чтобы установить скорость частоты мерцания путем установки числа миллисекунд. Период мерцания (flash time) - затраченное время, в миллисекундах, требуемое, чтобы показать, инвертировать и восстановить изображение каретки. Время мерцания каретки - вдвое больше, чем частота мерцания.

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


2.3 - Удаление каретки

Прикладная программа может использовать функцию HideCaret, чтобы удалить каретку с экрана. Это полезно, когда ваша прикладная программа должна перерисовать экран при обработке сообщения, но должна сохранить каретку вне этой области. Когда прикладная программа заканчивает прорисовку окна, она может показывать каретку снова, используя функцию ShowCaret. Сокрытие каретки не разрушает её форму и не аннулирует точку ввода. Сокрытие каретки - это совокупность действий; то есть, если прикладная программа вызывала HideCaret пять раз, она должна также вызвать ShowCaret пять раз прежде, чем каретка появится вновь.

Прикладная программа может удалять каретку с экрана и уничтожать форму, используя функцию DestroyCaret. DestroyCaret уничтожает каретку только тогда, если окно, включаемое в текущей задаче обладает кареткой(Примеч. переводчика: сразу двух кареток на экране не должно быть! Это чревато зависанием системы).


2.4 - Использование каретки

Создание и отображение каретки
Сокрытие каретки
Уничтожение каретки
Регулировка частоты мерцания
Обработка вводимой информации с клавиатуры


2.4.1 - Создание и отображение каретки

После приема фокуса клавиатуры, окно должно создать и показывать каретку. Используйте функцию CreateCaret, чтобы создать каретку в данном окне. Вы можете затем вызывать SetCaretPos, чтобы установить текущую позицию каретки и ShowCaret, чтобы сделать каретку видимой.

Система посылает сообщение WM_SETFOCUS окну, принимающему фокус клавиатуры; следовательно, прикладная программа должна создать и показывать каретку при обработке этого сообщения.

HWND hwnd,       // дескриптор окна
int x;           // горизонтальная координата каретки
int y;           // вертикальная координата каретки
int nWidth;      // ширина каретки
int nHeight;     // высота каретки
char *lpszChar;  // указатель на символ

    case WM_SETFOCUS:

// Создаем плотную черную каретку.
CreateCaret(hwnd, (HBITMAP) NULL, nWidth, nHeight);
// Регулировка позиции каретки, в рабочих координатах.
 SetCaretPos(x, y);
// Отображаем каретку.
ShowCaret(hwnd);
break;

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

// Загрузка определенного программой ресурса каретки.
hCaret = LoadBitmap(hinst, MAKEINTRESOURCE(120));
// Создание точечного рисунка каретки.
CreateCaret(hwnd, hCaret, 0, 0);

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

Если ваша прикладная программа определяет дескриптор точечного рисунка, CreateCaret игнорирует параметры высоты и ширины. Точечный рисунок определяет размер каретки.


2.4.2 - Сокрытие каретки

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

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

HWND hwnd,   // дескриптор окна
HDC hdc;     // контекст устройства

case WM_CHAR:
switch (wParam)
{
case 0x08:
    // Обработка клавиши "Backspace"
    break;
case 0x09:
    // Обработка табуляции
    break;
case 0x0D:
    // Обработка возврата каретки
    break;
case 0x1B:
    // Обработка клавиши "Esc"
    break;
case 0x0A:
    // Обработка перевода строки
    break;
default:
    // Сокрытие каретки
    HideCaret(hwnd);
    // Прорисовка символа на экране
    hdc = GetDC(hwnd);
    SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
    TextOut(hdc, x, y, lpszChar, 1);
    ReleaseDC(hwnd, hdc);
    // Изображение каретки
    ShowCaret(hwnd);
}

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


2.4.3 - Уничтожение каретки

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

case WM_KILLFOCUS:
    // Окно теряет фокус клавиатуры, так что уничтожьте каретку
    DestroyCaret();
    break;


2.4.4 - Регулировка частоты мерцания

В Windows 3.x, базирующаяся на Windows 16-разрядная прикладная программа может вызывать функцию GetCaretBlinkTime, чтобы сохранить текущую частоту мерцания, затем вызвать функцию SetCaretBlinkTime, чтобы откорректировать частоту мерцания в ходе обработки сообщения WM_SETFOCUS. Прикладная программа восстанавливает сохраненную частоту мерцания для использования другими прикладными программами, вызывая SetCaretBlinkTime в ходе обработки сообщения WM_KILLFOCUS. Однако эта методика не работает в среде Windows NT и Windows 95, потому что они - устойчивые, многопоточные среды. А именно, деактивизация одной из прикладных программ не синхронизирована с активизацией другой прикладной программы, так что, если одна прикладная программа зависла, другая прикладная программа может быть все еще активной.

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


2.4.5 - Обработка вводимой информации из клавиатуры

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

#define TEXTMATRIX(x, y) *(pTextMatrix + (y * nWindowCharsX) + x)
// Глобальные переменные
HINSTANCE hinst;		// текущий экземпляр программы
HBITMAP hCaret;		// точечный рисунок каретки
HDC hdc;			// контекст устройства
PAINTSTRUCT ps;		// информация о прорисовке рабочей области
static char *pTextMatrix = NULL;	// указатель на текстовую матрицу
static int
    nCharX,		// ширина символа в логических единицах
    nCharY,		// высота символа в логических единицах
    nWindowX,		// ширина рабочей области
    nWindowY,		// высота рабочей области
    nWindowCharsX,	// ширина рабочей области для символа
    nWindowCharsY,	// высота рабочей области для символа
    nCaretPosX,	// x-координата каретки
    nCaretPosY;	// y-координата каретки
static UINT uOldBlink;	// предыдущая частота мерцания
int x, y;			// x и y координаты, используемые в текстовой матрице
TEXTMETRIC tm;		// информация о фонте

LONG APIENTRY MainWndProc(
    HWND hwnd,	// дескриптор окна
    UINT message,	// тип сообщения
    UINT wParam,	// дополнительная информация
    LONG lParam)	// дополнительная информация
{
    switch (message)
    {
        case WM_CREATE:
// Выбор фиксированной ширины системного фонта и получение его текстовой матрицы.
            hdc = GetDC(hwnd);
            SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
            GetTextMetrics(hdc, &tm);
            ReleaseDC(hwnd, hdc);
// Сохранение средней высоты и ширины символов.
            nCharX = tm.tmAveCharWidth;
            nCharY = tm.tmHeight;
            return 0;
        case WM_SIZE:
// Определение ширины рабочей области, в пикселях и в количестве символов.
            nWindowX = LOWORD(lParam);
            nWindowCharsX = max(1, nWindowX/nCharX);
// Определение высоты рабочей области, в пикселях и в количестве символов.
            nWindowY = HIWORD(lParam);
            nWindowCharsY = max(1, nWindowY/nCharY);
// Очистка буфера, который содержит введенный текст.
            if (pTextMatrix != NULL)
                free(pTextMatrix);
// Если имеется достаточно памяти, распределите пространство для буфера ввода текста.
            pTextMatrix = malloc(nWindowCharsX * nWindowCharsY);
            if (pTextMatrix == NULL)
                ErrorHandler("Not enough memory.");
            else
                for (y = 0; y < nWindowCharsY; y++)
                    for (x = 0; x < nWindowCharsX; x++)
                        TEXTMATRIX(x, y) = ' ';
// Переместим каретку в начало координат
            SetCaretPos(0, 0);
            return 0;
        case WM_KEYDOWN:
            switch (wParam)
            {
                case VK_HOME:	// в начало
                    nCaretPosX = 0;
                    break;
                case VK_END:	// в конец
                    nCaretPosX = nWindowCharsX - 1;
                    break;
                case VK_PRIOR:	// предыдущая страница
                    nCaretPosY = 0;
                    break;
                case VK_NEXT:	// следующая страница
                    nCaretPosY = nWindowCharsY -1;
                    break;
                case VK_LEFT:	// перемещение стрелкой влево
                    nCaretPosX = max(nCaretPosX - 1, 0);
                    break;
                case VK_RIGHT:	// перемещение стрелкой вправо
                    nCaretPosX = min(nCaretPosX + 1,
                    nWindowCharsX - 1);
                    break;
                case VK_UP:	// перемещение стрелкой вверх
                    nCaretPosY = max(nCaretPosY - 1, 0);
                    break;
                case VK_DOWN:	// перемещение стрелкой вниз
                    nCaretPosY = min(nCaretPosY + 1,
                    nWindowCharsY - 1);
                    break;
                case VK_DELETE:	// удалить
// Переместите все символы, которые следовали за удаленным символом (на той же самой строке) на один
// пробел обратно (влево) в матрице
                    for (x = nCaretPosX; x < nWindowCharsX; x++)
                        TEXTMATRIX(x, nCaretPosY) = TEXTMATRIX(x + 1, nCaretPosY);
// Замена последнего символа в строке с пробелом.
                    TEXTMATRIX(nWindowCharsX - 1,
                    nCaretPosY) = ' ';
// Прикладная программа будет рисовать вне обработки сообщения
// WM_PAINT, так скрывают каретку.
                    HideCaret(hwnd);
// Перерисовка строки для удаленного символа.
                    hdc = GetDC(hwnd);
                    SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
                    TextOut(hdc, nCaretPosX * nCharX,
                        nCaretPosY * nCharY,
                        &TEXTMATRIX(nCaretPosX, nCaretPosY),
                        nWindowCharsX - nCaretPosX);
                    ReleaseDC(hwnd, hdc);
// Показать каретку.
                    ShowCaret(hwnd);
                    break;
            }
// Корректировать позицию каретки, основанную при обработке виртуальной клавиши
            SetCaretPos(nCaretPosX * nCharX, nCaretPosY * nCharY);
            return 0;
        case WM_CHAR:
            switch (wParam)
            {
            case 0x08:	// Обратный Пробел (Back Space)
// Перемещение каретки на один пробел, а затем обработка этого действия подобно клавише DEL.
                if (nCaretPosX > 0)
                {
                    nCaretPosX--;
                    SendMessage(hwnd, WM_KEYDOWN, VK_DELETE, 1L);
                }
                break;
            case 0x09:	// табуляция (Tab)
// Табуляция останавливается, проходя каждые четыре пробела, таким образом добавляются пробелы,
// до тех пор, пока пользователь нажимает следующий раз на клавишу табуляции.
                do
                {
                    SendMessage(hwnd, WM_CHAR, ' ', 1L);
                } while (nCaretPosX % 4 != 0);
                break;

            case 0x0D:	// возврат каретки
// Переход к началу следующей строки. Нижняя строка переносится по кругу в верхнюю часть.
                nCaretPosX = 0;
                if (++nCaretPosY == nWindowCharsY)
                    nCaretPosY = 0;
                break;

            case 0x1B:	// Escape
            case 0x0A:	// перевод строки
                MessageBeep((UINT) -1);
                break;
            default:
// Добавление символа в буфер текста.
                TEXTMATRIX(nCaretPosX, nCaretPosY) = (char) wParam;
// Прикладная программа будет рисовать вне обработки сообщения WM_PAINT; так скрывают каретку.
                HideCaret(hwnd);
// Прорисовка символа на экране
                hdc = GetDC(hwnd);
                SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
                TextOut(hdc, nCaretPosX * nCharX,
                    nCaretPosY * nCharY,
                    &TEXTMATRIX(nCaretPosX, nCaretPosY), 1);
                ReleaseDC(hwnd, hdc);
// Отобразим каретку
                ShowCaret(hwnd);
// Подготовка переноса по словам с начала до конца, если Вы достигли конца строки
                if (++nCaretPosX == nWindowCharsX)
                {
                    nCaretPosX = 0;
                    if (++nCaretPosY == nWindowCharsY)
                        nCaretPosY = 0;
                }
                break;
            }
// Регулировка позиции каретки, основанной на обработке символа.
            SetCaretPos(nCaretPosX * nCharX, nCaretPosY * nCharY);
            return 0;

        case WM_PAINT:
// Прорисовка всех символов в буфере, строка за строкой.

            hdc = BeginPaint(hwnd, &ps);
            SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
            for (y = 0; y < nWindowCharsY; y++)
                TextOut(hdc, 0, y * nCharY, &TEXTMATRIX(0, y), nWindowCharsX);
            EndPaint(hwnd, &ps);
        case WM_SETFOCUS:
// Окно имеет фокус ввода. Загрузка каретки определенной ресурсом программного приложения.
            hCaret = LoadBitmap(hinst, MAKEINTRESOURCE(120));
// Создание каретки
            CreateCaret(hwnd, hCaret, 0, 0);
// Регулировка позиции каретки
            SetCaretPos(nCaretPosX * nCharX, nCaretPosY * nCharY);
// Изображение каретки.
            ShowCaret(hwnd);
            break;
        case WM_KILLFOCUS:
// Окно теряет фокус ввода, так что каретка уничтожается.
            DestroyCaret();
            break;
        default:
            return DefWindowProc(hwnd, message, wParam, lParam);
        }
        return NULL;
}


2.5 - Функции каретки

Следующие функции используются при работе с кареткой:

  • CreateCaret
  • DestroyCaret
  • GetCaretBlinkTime
  • GetCaretPos
  • HideCaret
  • SetCaretBlinkTime
  • SetCaretPos
  • ShowCaret


2.5.1 - Функция CreateCaret

(СоздатьКаретку)

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

Синтаксис

BOOL CreateCaret
(
    HWND hWnd,		// дескриптор окна владельца каретки
    HBITMAP hBitmap,	// дескриптор точечного рисунка для формы каретки
    int nWidth,		// ширина каретки
    int nHeight 		// высота каретки
);

Параметры
hWnd
Идентифицирует окно, которое обладает кареткой.
hBitmap
Идентифицирует точечный рисунок, который определяет форму каретки. Если этот параметр - НОЛЬ (NULL), каретка объемная. Если этот параметр - (HBITMAP) 1, каретка серая. Если этот параметр - дескриптор точечного рисунка, каретка - определяется точечным рисунком. Дескриптор точечного рисунка, должен быть создан функцией CreateBitmap, CreateDIBitmap, или LoadBitmap. Если hBitmap - дескриптор точечного рисунка, CreateCaret игнорирует параметры nWidth и nHeight; точечный рисунок сам определяет собственную ширину и высоту.
nWidth
Устанавливает ширину каретки в логических единицах измерения. Если этот параметр нулевой, ширина устанавливается шириной границы определенного системой окна. Если hBitmap - дескриптор точечного рисунка, CreateCaret игнорирует этот параметр.
nHeight
Устанавливает высоту, в логических единицах измерения, каретки. Если этот параметр нулевой, высота устанавливается высотой границы определенной системой окна. Если hBitmap - дескриптор точечного рисунка, CreateCaret игнорирует этот параметр.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение отлично от нуля. Если функция потерпит неудачу, возвращаемое значение нулевое. Чтобы получить расширенные данные об ошибках, вызовите GetLastError.

Замечания
Параметры nWidth и nHeight устанавливают ширину и высоту каретки, в логических единицах измерения; точная ширина и высота, в пикселях, зависят от режима отображения окна.
CreateCaret автоматически уничтожает предыдущую форму каретки, если таковая имеется, независимо от окна, которое обладает кареткой. Каретка скрыта до вызова из прикладной программы функцией ShowCaret, которая делает каретку видимой.
Каретка - общедоступный ресурс; имеется только одна каретка в системе. Окно должно создать каретку только тогда, когда оно имеет фокус клавиатуры или активно. Окно должно уничтожить каретку перед потерей фокуса клавиатуры или перед потерей активности.
Вы можете возвратить ширину или высоту границы окна системы, используя функцию GetSystemMetrics, определяя значения флажков SM_CXBORDER и SM_CYBORDER. Использование ширины или высоты границы окна гарантирует, что каретка будет видима на экране с высокой разрешающей способностью.

Смотри также
CreateBitmap, CreateDIBitmap, DestroyCaret, GetSystemMetrics, HideCaret, LoadBitmap, ShowCaret

Размещение и совместимость CreateCaret

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


2.5.2 - Функция DestroyCaret

(РазрушитьКаретку)

Функция DestroyCaret уничтожает текущую форму каретки, освобождает каретку от окна и удаляет каретку с экрана. Если форма каретки основана на точечном рисунке, DestroyCaret не освобождает точечный рисунок.

Синтаксис

BOOL DestroyCaret(VOID)

Параметры
У этой функции нет параметров.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение отлично от нуля. Если функция потерпит неудачу, возвращаемое значение нулевое. Чтобы получить расширенные данные об ошибках, вызовите GetLastError.

Замечания
Функция DestroyCaret уничтожает каретку только тогда, если окно в текущей задаче обладает кареткой. Если окно, которое не в текущей задаче, обладает кареткой, DestroyCaret не делает ничего и возвращает значение ЛОЖЬ (FALSE). Каретка - общедоступный ресурс; в системе имеется только одна каретка. Окно должно создавать каретку только тогда, когда оно имеет фокус клавиатуры или активно. Окно должно уничтожить каретку перед потерей фокуса клавиатуры или переходом в режим не активного.

Смотри также
CreateCaret, HideCaret, ShowCaret

Размещение и совместимость DestroyCaret

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


2.5.3 - Функция GetCaretBlinkTime

Функция GetCaretBlinkTime возвращает прошедшее время, в миллисекундах, требуемых, чтобы инвертировать пиксели каретки. Пользователь может устанавливать это значение, используя Панель Управления.

Синтаксис

UINT GetCaretBlinkTime(VOID)

Параметры
У этой функции нет параметров.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - частота мерцания, в миллисекундах. Если функция потерпит неудачу, возвращаемое значение нулевое. Чтобы получать расширенные данные об ошибках, вызовите GetLastError.

Смотри также
SetCaretBlinkTime

Размещение и совместимость GetCaretBlinkTime

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


2.5.4 - Функция GetCaretPos

(ПолучитьПозициюКаретки)

Функция GetCaretPos копирует позицию каретки, в рабочих координатах, в определяемой структуре POINT.

Синтаксис

BOOL GetCaretPos
(
    LPPOINT lpPoint 	// адрес структуры, которая принимает координаты
);

Параметры
lpPoint
Указывает на структуру POINT, которая принимает рабочие координаты каретки.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение отлично от нуля. Если функция потерпит неудачу, возвращаемое значение нулевое. Чтобы получить расширенные данные об ошибках, вызовите GetLastError.

Замечания
Позиция каретки всегда дана в рабочих координатах окна, которое содержит каретку.

Смотри также
SetCaretPos, POINT

Размещение и совместимость GetCaretPos

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


2.5.5 - Функция HideCaret

(СкрытьКаретку)

Функция HideCaret удаляет каретку с экрана. Сокрытие каретки не уничтожает её текущую форму и не считает не состоявшейся вставку указателя.

Синтаксис

BOOL HideCaret
(
    HWND hWnd 	// дескриптор окна с кареткой
);

Параметры
hWnd
Идентифицирует окно, которое обладает кареткой. Если этот параметр - НОЛЬ (NULL), HideCaret ищет текущую задачу для окна, которое обладает кареткой.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение отлично от нуля. Если функция потерпит неудачу, возвращаемое значение нулевое. Чтобы получить расширенные данные об ошибках, вызовите GetLastError.

Замечания
Функция HideCaret скрывает каретку только в том случае, если заданное окно обладает кареткой. Если заданное окно не обладает кареткой, HideCaret не делает ничего и возвращает значение ЛОЖЬ (FALSE). Сокрытие накапливается. Если ваша прикладная программа вызвала HideCaret пять раз подряд, она должна также вызвать ShowCaret пять раз прежде, чем каретка отобразится на экране.

Смотри также
CreateCaret, DestroyCaret, GetCaretPos, SetCaretPos, ShowCaret

Размещение и совместимость HideCaret

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


2.5.6 - Функция SetCaretBlinkTime

(УстановкаЧастотыМерцания)

Функция SetCaretBlinkTime устанавливает частоту мерцания каретки по установленному числу миллисекунд. Частота мерцания - прошедшее время, в миллисекундах, требуемых, чтобы инвертировать пиксели каретки.

Синтаксис

BOOL SetCaretBlinkTime
   (
    UINT uMSeconds 	// частота мерцания, в миллисекундах
   );

Параметры
uMSeconds
Устанавливает новую частоту мерцания, в миллисекундах.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение отлично от нуля. Если функция потерпит неудачу, возвращаемое значение нулевое. Чтобы получить расширенные данные об ошибках, вызовите GetLastError.

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

Смотри также
GetCaretBlinkTime

Размещение и совместимость SetCaretBlinkTime

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


2.5.7 - Функция SetCaretPos

(УстановитьПозициюКаретки)

Функция SetCaretPos перемещает каретку в заданные координаты. Если окно, которое обладает кареткой, было создано со стилем класса CS_OWNDC, то определяемые координаты подчинены режиму отображения контекста устройства, связанного с этим окном.

Синтаксис

BOOL SetCaretPos
(
    int X,	// позиция по горизонтали
    int Y 	// позиция по вертикали
);

Параметры
X
Устанавливает новую x-координату каретки.
Y
Устанавливает новую y-координату каретки.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение отлично от нуля. Если функция потерпит неудачу, возвращаемое значение нулевое. Чтобы получить расширенные данные об ошибках, вызовите GetLastError.

Замечания
Функция SetCaretPos перемещает каретку, независимо от того скрыта каретка или нет. Каретка - общедоступный ресурс; имеется только одна каретка в системе. Окно может устанавливать позицию каретки только тогда, если оно обладает кареткой.

Смотри также
GetCaretPos, HideCaret, ShowCaret

Размещение и совместимость SetCaretPos

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


2.5.8 - Функция ShowCaret

(ПоказатьКаретку)

Функция ShowCaret делает каретку видимой на экране в текущей позиции каретки. Когда каретка становится видимой, она начинает автоматически мерцать.

Синтаксис

BOOL ShowCaret
(
    HWND hWnd 	// дескриптор окна с кареткой
);

Параметры
hWnd
Идентифицирует окно, которое обладает кареткой. Если этот параметр - НОЛЬ (NULL), ShowCaret ищет текущую задачу окна, которая обладает кареткой.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение отлично от нуля. Если функция потерпит неудачу, возвращаемое значение нулевое. Чтобы получить расширенные данные об ошибках, вызовите GetLastError.

Замечания
ShowCaret показывает каретку только в том случае, если определяемое окно обладает кареткой, каретка имеет форму и не была скрыта два или больше раз подряд. Если одно или большее количество из этих условий не выполнено, ShowCaret не делает ничего и возвращает значение ЛОЖЬ (FALSE).
Сокрытие накапливается. Если ваша прикладная программа обратились к функции HideCaret пять раз подряд, она должна также обратиться к ShowCaret пять раз прежде, чем каретка появится вновь.
Каретка - общедоступный ресурс; имеется только одна каретка в системе. Окно должно показать каретку только тогда, когда окно имеет фокус клавиатуры или активно.

Смотри также
CreateCaret, DestroyCaret, GetCaretPos, HideCaret, SetCaretPos

Размещение и совместимость ShowCaret

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется
Предыдущий Шаг


Глава 10 - Ввод информации с клавиатуры

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

Следующий Шаг


10.1 - О вводе информации с клавиатуры

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


10.2 - Модель ввода информации с клавиатуры

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

Присвоенное для каждой клавиши на клавиатуре уникальное значение, называемое скэн-кодом (scan code), аппаратно-зависимый идентификатор для клавиши на клавиатуре. Клавиатура генерирует два скэн-кода, когда пользователь манипулирует клавишей - первый, когда пользователь нажимает клавишу, а второй, когда пользователь отпускает клавишу.

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

3_1.gif (8077 b)


10.3 - Фокус и активизация клавиатуры

Windows посылает сообщения клавиатуры в очередь сообщений активного потока, который создал окно с фокусом клавиатуры. Фокус клавиатуры (keyboard focus) - временное свойство окна. Windows дает возможность совместно использовать клавиатуру всем окнам на экране, при помощи перемещения фокуса клавиатуры по указанию пользователя из одного окна в другое. Окно, которое имеет фокус клавиатуры, принимает (из очереди сообщений потока, который создал его) все сообщения клавиатуры, пока фокус не перейдет к другому окну.

Поток может вызывать функцию GetFocus, чтобы определить, которое из его окон (если есть в наличии) в настоящее время имеет фокус клавиатуры. Поток может дать фокус клавиатуры одному из своих окон, при помощи вызова функции SetFocus. Когда фокус клавиатуры меняет одно окно на другое, система отправляет сообщение WM_KILLFOCUS окну, которое потеряет фокус, а затем отправляет сообщение WM_SETFOCUS окну, которое получает фокус.

Концепция фокуса клавиатуры связывается с понятием активного окна. Активное окно (active window) - окно верхнего уровня, с которым пользователь в настоящее время работает. Окно с фокусом клавиатуры является или активным окном, или дочерним окном активного окна. Таким образом, чтобы пользователь мог легко идентифицировать активное окно, система размещает его сверху в Z-последовательности и делает выделенными область его заголовка (если оно является единственным) и рамку.

Пользователь может активизировать окно верхнего уровня, щелкнув по нему мышью, выбрать его, используя комбинацию клавиш ALT+TAB или ALT+ESC, или выбрать его, если оно в Списке Задач (Task List). Поток может активизировать окно верхнего уровня, используя функцию SetActiveWindow. Он может определить, является ли окно верхнего уровня, которое он создал активным, используя функцию GetActiveWindow.

Когда одно окно деактивизируется, а другое активизируется, Windows сначала отправляет сообщение WM_ACTIVATE деактивизируемому, а затем активизируемому окну. Младшее слово параметра wParam равно нулю, если окно деактивизируется, и отличается от нуля, если оно активизируется. Когда заданная по умолчанию оконная процедура принимает сообщение WM_ACTIVATE, она устанавливает фокус клавиатуры в активном окне.


10.4 - Сообщения о нажатии клавиши

Нажатие клавиши заканчивается сообщением WM_KEYDOWN или WM_SYSKEYDOWN, помещаемое в очередь сообщений потока, связанного с окном, которое имеет фокус клавиатуры. Отпуск клавиши заканчивается сообщением WM_KEYUP или WM_SYSKEYUP, помещаемым в очередь.

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


10.5 - Системные и несистемные нажатия клавиш

Windows делает различие между системными и несистемными нажатиями клавиш. Системные нажатия клавиш производят системные сообщения WM_SYSKEYDOWN и WM_SYSKEYUP. Несистемные нажатия клавиш производят несистемные сообщения WM_KEYDOWN и WM_KEYUP.

Если ваша оконная процедура должна обработать сообщение системного нажатия клавиши, удостоверьтесь, что после обработки сообщения процедура посылает его в функцию DefWindowProc. Иначе, все системные действия, включающие клавишу ALT, будут заблокированы всякий раз, когда окно получает фокус клавиатуры. То есть пользователь не будет получать возможности обратиться к меню окна или Системному меню, или использовать комбинацию клавиш ALT+ESC или ALT+TAB, чтобы активизировать другое окно.

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

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


10.6 - Описание кодов виртуальной клавиши

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

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


10.7 - Флажки сообщения о нажатии клавиши

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

8_1.gif (7221 b)

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

  • KF_ALTDOWN - Управляет флажком клавиши ALT, который указывает, нажата ли клавиша ALT.
  • KF_DLGMODE - Управляет флажком режима диалога, который указывает, является ли диалоговое окно активным.
  • KF_EXTENDED - Управляет флажком дополнительной клавиши.
  • KF_MENUMODE - Управляет флажком режима меню, который указывает, является ли меню активным.
  • KF_REPEAT - Управляет счетчиком повторений.
  • KF_UP - Управляет флажком переходного состояния.

Счетчик повторений

Вы можете проверить счетчик повторений, чтобы определить, представляет ли сообщение нажатия клавиши больше чем одно нажатие. Система увеличивает счетчик, когда клавиатура генерирует сообщения WM_KEYDOWN или WM_SYSKEYDOWN быстрее, чем прикладная программа может обрабатывать их. Это часто происходит тогда, когда пользователь удерживает нажатой клавишу достаточно долго, чтобы запустить функцию автоматического повторения клавиатуры. Вместо заполнения системной очереди сообщениями, происходящими в результате нажатия клавиши, система объединяет сообщения в единственное сообщение нажатой клавиши и увеличивает счет повторений. Отпуск клавиши не может запустить функцию автоматического повторения, так что счет повторений для сообщений WM_KEYUP и WM_SYSKEYUP всегда устанавливается в 1.

Скэн-код

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

Флажок дополнительной клавиши

Флажок дополнительной клавиши указывает, произошло ли сообщение нажатия клавиши от одной из дополнительных клавиш на расширенной клавиатуре. Дополнительные клавиши состоят из клавиш ALT и CTRL в правой части клавиатуры; INS, DEL, HOME, END, PAGE UP, PAGE DOWN и клавиши курсора в группах слева от цифровой клавиатуры; клавиша NUM LOCK; клавиша BREAK (CTRL+PAUSE); клавиша PRINT SCRN; делитель (/) и клавиши ENTER в цифровой клавиатуре. Флажок дополнительной клавиши устанавливается, если клавиша является дополнительной клавишей.

Контекстный Код

Контекстный код указывает, была ли клавиша ALT нажата тогда, когда было сгенерировано сообщение о нажатии клавиши. Если клавиша ALT была нажата, код будет 1 и 0, если этого не было.

Флажок предыдущего состояния клавиши

Флажок предыдущего состояния клавиши указывает, была ли клавиша, которая генерировала сообщение о нажатии, перед этим нажата или отпущена. Он будет 1, если клавиша в предыдущем состоянии была нажата и 0, если клавиша в предыдущем состоянии была отпущена. Вы можете использовать этот флажок, чтобы идентифицировать сообщения нажатия клавиши, сгенерированные автоматической функцией повторения клавиатуры. Этот флажок установлен в 1 для сообщений WM_KEYDOWN и WM_SYSKEYDOWN нажатия клавиши, сгенерированных автоматической функцией повторения. Он всегда устанавливается в 0 для сообщений WM_SYSKEYUP и WM_KEYUP.

Флажок переходного состояния

Флажок переходного состояния указывает, что генерировало сообщение нажатия клавиши - либо нажатие клавиши или отпуск её. Этот флажок всегда устанавливается в 0 для сообщений WM_SYSKEYDOWN и WM_KEYDOWN; он всегда устанавливается в 1 для сообщений WM_SYSKEYUP и WM_KEYUP.


10.8 - Символьные сообщения

Сообщения о нажатии клавиши предоставляют много информации о нажатой клавише, но они не предусматривают кодов букв при нажатии символьных клавиш. Чтобы получить данные о кодах букв, прикладная программа должна включить функцию TranslateMessage в цикл сообщений своего потока. Функция TranslateMessage посылает сообщение WM_KEYDOWN или WM_SYSKEYDOWN раскладке символов на клавиатуре. Раскладка проверяет код виртуальной клавиши сообщения и, если он соответствует клавише знака, предоставляет эквивалент кода буквы (принимая во внимание состояние клавиш SHIFT и CAPS LOCK). Функция затем генерирует символьное сообщение, которое включает в себя код буквы и размещает сообщение сверху очереди сообщений. Следующий повтор цикла сообщения удаляет символьное сообщение из очереди и отсылает сообщение соответствующей оконной процедуре.


10.9 - Несистемные символьные сообщения

Оконная процедура может принимать четыре различных символьных сообщения, включая WM_CHAR, WM_DEADCHAR, WM_SYSCHAR и WM_SYSDEADCHAR. Функция TranslateMessage генерирует сообщение WM_CHAR или WM_DEADCHAR тогда, когда она обрабатывает сообщение WM_KEYDOWN. Точно так же она генерирует сообщение WM_SYSCHAR или WM_SYSDEADCHAR тогда, когда обрабатывает сообщение WM_SYSKEYDOWN.

Прикладная программа, которая обрабатывает ввод информации с клавиатуры обычно, игнорирует все, кроме сообщения WM_CHAR, посылая любые другие сообщения функции DefWindowProc. Windows использует сообщения WM_SYSCHAR и WM_SYSDEADCHAR, чтобы осуществлять мнемонику меню.

Параметр wParam всех символьных сообщений содержит код буквы клавиши, которая была нажата. Значение кода буквы зависит от класса окна, принимающего сообщение. Если функция RegisterClass была использована, чтобы зарегистрировать класс окна в версии Уникода, система предоставляет символы Unicode всем окнам этого класса. И напротив, система предоставляет коды букв ASCII из набора символов Windows. Для получения дополнительной информации об Уникоде, см. Уникод и наборы символов.

Содержание параметра lParam символьного сообщения идентично содержанию параметра lParam сообщения о нажатии клавиши, которое было оттранслировано, чтобы произвести символьное сообщение. За информацией о содержании параметра lParam, см. Флажки сообщения о нажатии клавиши.


10.10 - Сообщения о диакритическом знаке

Некоторые неанглийские клавиатуры содержат знаковые клавиши, которые не требуют создания своих символов. Вместо этого, они используются, чтобы добавить диакритический знак к символу, произведенному последующим нажатием клавиши. Эти клавиши - называются "мертвыми" клавишами (dead keys). Клавиша диакритического знака (A) над гласной (который по-другому называется циркумфлекс) в немецкой клавиатуре - пример "мертвой" клавиши. Чтобы ввести символ, состоящий из "o" с циркумфлексом, немецкий пользователь нажимает клавишу циркумфлекса, сопровождаемую нажатием клавиши "o". Окно с фокусом клавиатуры принимает следующую последовательность сообщений:

WM_KEYDOWN
WM_DEADCHAR
WM_KEYUP
WM_KEYDOWN
WM_CHAR
WM_KEYUP

Функция TranslateMessage генерирует сообщение WM_DEADCHAR тогда, когда она обрабатывает сообщение WM_KEYDOWN от "мертвой" клавиши. Хотя параметр wParam сообщения WM_DEADCHAR содержит код буквы диакритического знака для мертвой клавиши, прикладная программа обычно игнорирует это сообщение. Вместо этого она обрабатывает сообщение WM_CHAR, сгенерированное последующим нажатием клавиши. Параметр wParam сообщения WM_CHAR содержит код буквы символа с диакритическим знаком. Если последующее нажатие клавиши генерирует символ, который не может быть объединен с диакритическим знаком, Windows генерирует два сообщения WM_CHAR. Параметр wParam первого содержит код буквы диакритического знака; параметр wParam второго содержит код буквы последующей знаковой клавиши.

Функция TranslateMessage генерирует сообщение WM_SYSDEADCHAR тогда, когда она обрабатывает сообщение WM_SYSKEYDOWN от системной "мертвой" клавиши ("мертвая" клавиша, которая нажата в комбинации с клавишей ALT). Прикладная программа обычно игнорирует сообщение WM_SYSDEADCHAR.


10.11 - Состояние клавиши

В ходе обработки сообщения клавиатуры, у прикладной программы возникает необходимость установить состояние другой клавиши кроме той, для которой сгенерировано текущее сообщение. Например, прикладная программа обработки текстов (текстовый процессор), которая позволяет пользователю нажимать SHIFT+END, чтобы выбрать блок текста, должна проверять состояние клавиши SHIFT всякий раз, когда она принимает сообщение о нажатии от клавиши END. Прикладная программа может использовать функцию GetKeyState, чтобы установить, было ли сгенерировано состояние виртуальной клавиши во время текущего сообщения; она может использовать функцию GetAsyncKeyState, чтобы получить данные о текущем состоянии виртуальной клавиши.

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


10.12 - Трансляции нажатия клавиши и символьной клавиши

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


10.13 - Поддержка "горячей" клавиши

Windows предоставляет набор функций, которые прикладные программы могут использовать, чтобы определить "горячую" клавишу. "Горячая" клавиша (hot key) - комбинация клавиш, которая генерирует сообщение WM_HOTKEY, сообщение, которое система помещает сверху очереди сообщений потока, обходя любые существующие сообщения в очереди. Прикладные программы используют "горячую" клавишу, чтобы получить первоочередной ввод информации с клавиатуры от пользователя. Например, определяя "горячую" клавишу, состоящую из комбинации клавиш CTRL+C, прикладная программа может дать возможность пользователю отменить затянувшуюся операцию.

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

Прикладные программы могут использовать управление "горячей" клавишей, чтобы сделать себя легкодоступными для пользователя, который выбирает комбинацию "горячая клавиша". Элементы управления комбинацией "горячая" клавиша обычно используются, чтобы определить "горячую" клавишу, которая активизирует окно; они не используют функции RegisterHotKey и UnregisterHotKey. Вместо этого, прикладная программа, которая использует орган управления комбинацией "горячая" клавиша обычно, передает сообщение WM_SETHOTKEY, чтобы установить "горячую" клавишу. Всякий раз, когда пользователь нажимает "горячую" клавишу, система отправляет сообщение WM_SYSCOMMAND, устанавливающее SC_HOTKEY. Для получения дополнительной информации об элементах управления комбинацией "горячая клавиша", см. Органы управления "горячей " клавишей.


10.14 - Языки, регионы и раскладки символов на клавиатуре

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

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

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

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

Функция ActivateKeyboardLayout устанавливает язык ввода для текущей задачи. Её параметр hkl может быть или дескриптор раскладки символов на клавиатуре или дополненный нулями идентификатор языка. Дескрипторы раскладки символов на клавиатуре могут быть получены из функции LoadKeyboardLayout или GetKeyboardLayoutList. Значения HKL_NEXT и HKL_PREV могут также быть использованы, чтобы выбрать следующую или предыдущую клавиатуру. Для некоторых операционных систем, значение KLF_UNLOADPREVIOUS не имеет никакого смысла и игнорируется.

Функция GetKeyboardLayoutName извлекает данные о названии активной раскладки символов на клавиатуре для вызывающего потока. Если прикладная программа создает активную раскладку, используя функцию LoadKeyboardLayout, GetKeyboardLayoutName извлекает ту же самую строку, которую использовали, чтобы создать раскладку. Иначе, эта строка - первичный идентификатор языка, соответствующий региону активной раскладки. Это означает, что функция не обязательно может различать между собой различные раскладки с тем же самым первичным языком, так как не может возвратить конкретную информацию о языке ввода. Тем не менее, функция GetKeyboardLayout может быть использована, чтобы установить язык ввода информации.

Функция LoadKeyboardLayout загружает раскладку символов на клавиатуре и делает её доступной пользователю. Прикладные программы могут делать раскладку активной непосредственно для текущего потока, используя значение KLF_ACTIVATE. Прикладная программа может использовать значение KLF_REORDER, чтобы переупорядочить раскладки без такой установки значения KLF_ACTIVATE. Прикладные программы должны всегда использовать значение KLF_SUBSTITUTE_OK при загрузке раскладок символов на клавиатуре, чтобы гарантировать, что предпочтение пользователя, если таковое вообще имеются, обеспечено. Для некоторых операционных систем, значение KLF_UNLOADPREVIOUS игнорируется.

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

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


10.15 - Использование ввода информации с клавиатуры

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

Обработка сообщений о нажатии клавиши

Трансляция символьных сообщений

Обработка символьных сообщений

Использование каретки

Отображение ввода информации с клавиатуры


10.15.1 - Обработка сообщений о нажатии клавиши

Оконная процедура окна, которое имеет фокус клавиатуры, принимает сообщения о нажатии клавиши, когда пользователь печатает на клавиатуре. Сообщения о нажатии клавиши - WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN и WM_SYSKEYUP. Типичная оконная процедура игнорирует все сообщения о нажатии клавиши кроме WM_KEYDOWN. Windows посылает сообщение WM_KEYDOWN, когда пользователь нажимает клавишу.

Когда оконная процедура принимает сообщение WM_KEYDOWN, она должна проверить код виртуальной клавиши, который сопровождает сообщение, чтобы установить, как обработать нажатие клавиши. Код виртуальной клавиши находится в параметре wParam сообщения. Как правило, приложение обрабатывает только нажатия клавиши, сгенерированные не символьными клавишами, включая функциональные клавиши, клавиши управления курсором, и клавиши специального назначения типа INS, DEL, HOME и END.

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

case WM_KEYDOWN:
    switch (wParam) {
        case VK_LEFT:
            .
            . /* Обрабатывает клавишу LEFT ARROW (Стрелка влево). */
            .
        break;

        case VK_RIGHT:
            .
            . /* Обрабатывает клавишу RIGHT ARROW (Стрелка вправо). */
            .
        break;

        case VK_UP:
            .
            . /* Обрабатывает клавишу UP ARROW (Стрелка вверх). */
            .
        break;

        case VK_DOWN:
            .
            . /* Обрабатывает клавишу DOWN ARROW (Стрелка вниз). */
            .
        break;

        case VK_HOME:
            .
            . /* Обрабатывает клавишу HOME. */
            .
        break;

        case VK_END:
            .
            . /* Обрабатывает клавишу END. */
            .
        break;

        case VK_INSERT:
            .
            . /* Обрабатывает клавишу INS. */
            .
        break;

        case VK_DELETE:
            .
            . /* Обрабатывает клавишу DEL. */
            .
        break;

        case VK_F2:
            .
            . /* Обрабатывает клавишу F2. */
            .
        break;

        .
        . /* Обрабатывает другие не символьные нажатия клавиш. */
        .
        default:
        break;
    }


10.15.2 - Трансляция символьных сообщений

Любой поток, который принимает символьный ввод информации от пользователя, должен включать в свой цикл сообщений функцию TranslateMessage. Эта функция проверяет в сообщении о нажатии клавиши ее виртуальный код и, если код соответствует символу, помещает символьное сообщение в очередь сообщений. Символьное сообщение удаляется и отправляется при следующем повторении цикла сообщения; параметр wParam сообщения содержит код буквы.

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

while (GetMessage(&msg, (HWND) NULL, 0, 0))
{
    if (TranslateAccelerator(hwndMain, haccl, &msg) == 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}


10.15.3 - Обработка символьных сообщений

Оконная процедура принимает символьное сообщение тогда, когда функция TranslateMessage транслирует код виртуальной клавиши соответствующий клавише знака. Символьными сообщениями являются WM_CHAR, WM_DEADCHAR, WM_SYSCHAR, и WM_SYSDEADCHAR. Типичная оконная процедура игнорирует все символьные сообщения кроме WM_CHAR. Функция TranslateMessage генерирует сообщение WM_CHAR тогда, когда пользователь нажимает какую-либо из следующих клавиш.

Любую символьную клавишу
BACKSPACE
ENTER (перевод каретки)
ESC
SHIFT+ENTER (перевод строки)
TAB

Когда оконная процедура принимает сообщение WM_CHAR, она должна проверить код буквы, который сопровождает сообщение, чтобы установить, как обрабатывать символ. Код буквы находится в параметре wParam сообщения.

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

case WM_CHAR:
switch (wParam)
{
case 0x08:
    .
    . /* Обработка BACKSPACE . */
    .
    break;

case 0x0A:
    .
    . /* Обработка перевода строки. */
    .
    break;

case 0x1B:
    .
    . /* Обработка Esc. */
    .
    break;

case 0x09:
    .
    . /* Обработка табуляции TAB. */
    .
    break;

case 0x0D:
    .
    . /* Обработка перевода каретки. */
    .
    break;

default:
    .
    . /* Обработка воспроизводимых символов. */
    .
    break;
}


10.15.4 - Использование каретки

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


10.15.5 - Отображение ввода информации с клавиатуры

Пример в этом разделе показывает, как прикладная программа может принимать символы от клавиатуры, отображать их в рабочей области окна и обновлять позицию каретки с каждым напечатанным символом. Он также демонстрирует, и как переместить каретку в ответ на нажатие клавиш LEFT ARROW (стрелка влево), RIGHT ARROW (стрелка вправо), HOME (вверх документа) и END (в конец документа), и показывает, как выделить выбранный текст в ответ на нажатие комбинации клавиш SHIFT+RIGHT ARROW.

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

Оконная процедура создает и отображает на экране каретку при обработке сообщения WM_SETFOCUS. Она скрывает и удаляет каретку при обработке сообщения WM_KILLFOCUS.

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

Оконная процедура исполняет движения каретки влево, вправо, в конец и в исходную позицию при обработке сообщения WM_KEYDOWN. При обработке действия клавиши RIGHT ARROW (стрелки "вправо"), оконная процедура проверяет состояние клавиши SHIFT и, если она нажата, выбирает символ справа от каретки, поскольку каретка перемещается.

Обратите внимание! на то, что нижеследующий код написан так, чтобы его можно было откомпилировать или как Уникод ™ или как ANSI. Если исходный текст определяет Уникод, строки обрабатываются как символы Уникода; иначе, они обрабатываются как символы ANSI.

#define BUFSIZE 65535
#define SHIFTED 0x8000

LONG APIENTRY MainWndProc(hwndMain, uMsg, wParam, lParam)
HWND hwndMain;
UINT uMsg;
UINT wParam;
LONG lParam;
{
    HDC hdc;			/* дескриптор контекста устройства */
    TEXTMETRIC tm;		/* структура для текстовой метрики  */
    static DWORD dwCharX;	/* средняя ширина символа */
    static DWORD dwCharY;	/* высота символа */
    static DWORD dwClientX;	/* ширина рабочей области	*/
    static DWORD dwClientY;	/* высота рабочей области */
    static DWORD dwLineLen;	/* длина строки */
    static DWORD dwLines;	/* строки текста в рабочей области */
    static int nCaretPosX = 0;	/* горизонтальная позиция каретки */
    static int nCaretPosY = 0;	/* вертикальная позиция каретки */
    static int nCharWidth = 0;	/* ширина символа */
    static int cch = 0;	/* символы в буфере */
    static int nCurChar = 0;	/* индекс текущего символа */
    static PTCHAR pchInputBuf;	/* адрес вводного буфера */
    int i, j;			/* цикл счета */
    int cCR = 0;		/* счетчик переводов каретки */
    int nCRIndex = 0;		/* индекс последнего перевода каретки */
    int nVirtKey;		/* код виртуальной клавиши */
    TCHAR szBuf[128];		/* временный буфер */
    TCHAR ch;			/* текущий символ */
    PAINTSTRUCT ps;		/* требуется для BeginPaint */
    RECT rc;			/* прямоугольник вывода для DrawText */
    SIZE sz;			/* размеры строк */
    COLORREF crPrevText;	/* предыдущий цвет текста */
    COLORREF crPrevBk;		/* предыдущий цвет фона */

    switch (uMsg) {
        case WM_CREATE:
            /* Получим метрику текущего шрифта. */
            hdc = GetDC(hwndMain);
            GetTextMetrics(hdc, &tm);
            ReleaseDC(hwndMain, hdc);

            /* Сохраним среднюю ширину и высоту символа. */
            dwCharX = tm.tmAveCharWidth;
            dwCharY = tm.tmHeight;

            /* Разместим в памяти буфер для ввода информации с клавиатуры. */
            pchInputBuf = (LPTSTR) GlobalAlloc(GPTR,
                BUFSIZE * sizeof(TCHAR));
            return 0;

        case WM_SIZE:
            /* Сохраним новую ширину и высоту рабочей области. */
            dwClientX = LOWORD(lParam);
            dwClientY = HIWORD(lParam);

            /* Вычислим максимальную ширину строки и максимальное
            * число строк в рабочей области. */
            dwLineLen = dwClientX - dwCharX;
            dwLines = dwClientY / dwCharY;
            break;

        case WM_SETFOCUS:
            /*
            * Создадим, позиционируем и отобразим каретку в окне,
            * которое приняло фокус ввода.
            */

            CreateCaret(hwndMain, (HBITMAP) 1, 0, dwCharY);
            SetCaretPos(nCaretPosX, nCaretPosY * dwCharY);
            ShowCaret(hwndMain);
            break;

        case WM_KILLFOCUS:
            /*
            * Скроем и разрушим каретку, когда окно теряет фокус ввода с клавиатуры.
            */
            HideCaret(hwndMain);
            DestroyCaret();
            break;

        case WM_CHAR:
            switch (wParam) {
            case 0x08:	/* на символ назад */
            case 0x0A:	/* перевод строки */
            case 0x1B:	/* переход */
                MessageBeep(0xFFFFFFFF);
                return 0;

            case 0x09:	/* табуляция */
                /* Преобразование табуляции в четыре последовательных пробела. */
                for (i = 0; i < 4; i++)
                    SendMessage(hwndMain, WM_CHAR, 0x20, 0);
                return 0;

            case 0x0D:	/* возврат каретки */
                /*
                * Запись перевода каретки и позиции каретки в начале новой строки.
                */

                pchInputBuf[cch++] = 0x0D;
                nCaretPosX = 0;
                nCaretPosY += 1;
                break;

            default:	/* отображаемый символ */
                ch = (TCHAR) wParam;
                HideCaret(hwndMain);

                /*
                * Извлечение данных о ширине символа и вывод символа.
                */

                hdc = GetDC(hwndMain);
                GetCharWidth32(hdc, (UINT) wParam, (UINT) wParam, &nCharWidth);
                TextOut(hdc, nCaretPosX, nCaretPosY * dwCharY, &ch, 1);
                ReleaseDC(hwndMain, hdc);

                /* сохранение символа в буфере. */
                pchInputBuf[cch++] = ch;

                /*
                * Вычисление новой горизонтальной позиции каретки.
                * Если позиция превышает максимум, вставьте перевод каретки,
                * и переместите каретку в начало следующей строки.
                */
                nCaretPosX += nCharWidth;
                if ((DWORD) nCaretPosX > dwLineLen) {
                    nCaretPosX = 0;
                    pchInputBuf[cch++] = 0x0D;
                    ++nCaretPosY;
                }
                nCurChar = cch;
                ShowCaret(hwndMain);
                break;
            }
            SetCaretPos(nCaretPosX, nCaretPosY * dwCharY);
            break;

        case WM_KEYDOWN:
            switch (wParam) {
            case VK_LEFT:	/* клавиша LEFT ARROW */
                /*
                * Каретка может переместится только в начало текущей строки.
                */
                if (nCaretPosX < 0) {
                    HideCaret(hwndMain);

                    /*
                    * Извлекает данные о символе слева от каретки,
                    * вычисляет ширину символа затем вычитает ширину
                    * из текущей горизонтальной позиции каретки, чтобы
                    * получить новую позицию.
                    */

                    ch = pchInputBuf[--nCurChar];
                    hdc = GetDC(hwndMain);
                    GetCharWidth32(hdc, ch, ch, &nCharWidth);

                    ReleaseDC(hwndMain, hdc);
                    nCaretPosX = max(nCaretPosX - nCharWidth,0);
                    ShowCaret(hwndMain);
                }
                break;

            case VK_RIGHT:	/* Клавиша RIGHT ARROW */
                /*
                * Каретка перемещается вправо или когда
                * определяется перевод каретки, чтобы начать
                * следующую строку.
                */

                if (nCurChar > cch) {
                    HideCaret(hwndMain);

                    /*
                    * Извлекаем данные о символе справа от каретки.
                    * Если они являются переводом каретки, каретка
                    * позиционируется в начале следующей строки.
                    */
                    ch = pchInputBuf[nCurChar];

                    if (ch == 0x0D) {
                        nCaretPosX = 0;
                        nCaretPosY++;
                    }

                    /*
                    * Если символ не является переводом каретки, то
                    * проверяем, не нажата ли клавиша SHIFT. Если она
                    * нажата. Инвертируем цвет текста и выводим символ.
                    */

                    else {
                        hdc = GetDC(hwndMain);
                        nVirtKey = GetKeyState(VK_SHIFT);
                        if (nVirtKey & SHIFTED) {
                        crPrevText = SetTextColor(hdc,RGB(255, 255, 255));
                        crPrevBk = SetBkColor(hdc,RGB(0,0,0));
                        TextOut(hdc, nCaretPosX,nCaretPosY * dwCharY,&ch,1);
                        SetTextColor(hdc, crPrevText);
                        SetBkColor(hdc, crPrevBk);
                        }

                        /*
                        * Получаем ширину символа и вычисляем новую
                        * горизонтальную позицию каретки.
                        */
                        GetCharWidth32(hdc, ch, ch, &nCharWidth);
                        ReleaseDC(hwndMain, hdc);
                        nCaretPosX = nCaretPosX + nCharWidth;
                    }
                    nCurChar++;
                    ShowCaret(hwndMain);
                    break;
                }
                break;

            case VK_UP:	/* клавиша UP ARROW (стрелка вверх)  */
            case VK_DOWN:	/* клавиша DOWN ARROW (стрелка вниз)*/
                MessageBeep(0xFFFFFFFF);
                return 0;

            case VK_HOME:	/*клавиша HOME */
                *
                * Устанавливаем позицию каретки в верхнем левом
                * углу рабочей области.
                */
                nCaretPosX = nCaretPosY = 0;
                nCurChar = 0;
                break;

            case VK_END:	/* клавиша END */
                /* Перемещаем каретку в конец текста. */
                for (i=0; i < cch; i++) {
                    /*
                    * Считаем число переводов каретки и сохраняем
                    * индекс последнего счета.
                    */
                    if (pchInputBuf[i] == 0x0D) {
                        cCR++;
                        nCRIndex = i + 1;
                    }
                }
                nCaretPosY = cCR;

                /*
                * Копируем весь текст между последним переводом
                * каретки и концом из буфера ввода с клавиатуры
                * во временный буфер.
                */

                for (i = nCRIndex, j = 0; i < cch; i++, j++)
                    szBuf[j] = pchInputBuf[i];
                szBuf[j] = TEXT('\0');

                /*
                * Извлекаем данные о протяженности текста и используем
                * их, чтобы установить горизонтальную позицию каретки.
                */
                hdc = GetDC(hwndMain);
                GetTextExtentPoint32(hdc, szBuf, lstrlen(szBuf),&sz);
                nCaretPosX = sz.cx;
                ReleaseDC(hwndMain, hdc);
                nCurChar = cch;
                break;
            default:
                break;
            }
            SetCaretPos(nCaretPosX, nCaretPosY * dwCharY);
            break;

        case WM_PAINT:
            if (cch == 0)	/* в вводном буфере нет ничего */
                break;

            hdc = BeginPaint(hwndMain, &ps);
            HideCaret(hwndMain);

            /*
            * Устанавливаем прямоугольник отсечения, а затем
            * рисуем текст внутри него.
            */

            SetRect(&rc, 0, 0, dwLineLen, dwClientY);
            DrawText(hdc, pchInputBuf, -1, &rc, DT_LEFT);
            ShowCaret(hwndMain);
            EndPaint(hwndMain, &ps);
            break;

            .
            . /* Обрабатываем другие сообщения. */
            .

        case WM_DESTROY:
            PostQuitMessage(0);

            /* Освобождаем  буфер ввода. */
            GlobalFree((HGLOBAL) pchInputBuf);
            UnregisterHotKey(hwndMain, 0xAAAA);
            break;

        default:
            return DefWindowProc(hwndMain, uMsg, wParam, lParam);
    }
    return NULL;
}


10.16 - Справочник по вводу информации с клавиатуры

Следующие функции и сообщения связаны с вводом информации с клавиатуры.


10.16.1 - Функции ввода информации с клавиатуры

Следующие функции используются, чтобы принимать и обрабатывать ввод информации с клавиатуры.
ActivateKeyboardLayout
EnableWindow
GetActiveWindow
GetAsyncKeyState
GetFocus
GetKeyboardLayout
GetKeyboardLayoutList
GetKeyboardLayoutName
GetKeyboardState
GetKeyNameText
GetKeyState
IsWindowEnabled
keybd_event
LoadKeyboardLayout
MapVirtualKey
MapVirtualKeyEx
OemKeyScan
RegisterHotKey
SetActiveWindow
SetFocus
SetKeyboardState
ToAscii
ToAsciiEx
ToUnicode
UnloadKeyboardLayout
UnregisterHotKey
VkKeyScan
VkKeyScanEx

Устаревшие функции
GetKBCodePage


10.16.1.1 - Функция ActivateKeyboardLayout

(АктивизацияРаскладкиКлавиатуры)

Выполнение функции в среде Windows 95 и Windows NT существенно различается. Чтобы выявить эти различия, эта страница справочника первые представляет ее реализацию в среде Windows 95 во всей полноте, в соответствии с версией Windows NT.

Windows 95:

Функция ActivateKeyboardLayout устанавливает язык ввода для текущего потока. Эта функция принимает дескриптор раскладки символов на клавиатуре, который идентифицирует регион также как и физическую раскладку клавиатуры.

Синтаксис

HKL ActivateKeyboardLayout
(
    HKL hkl,		// дескриптор раскладки клавиатуры
    UINT Flags	// флажки раскладки клавиатуры
);

Параметры
hkl
Дескриптор раскладки символов на клавиатуре или дополненный нулями идентификатор региона. Этот параметр может быть любой допустимый дескриптор раскладки символов на клавиатуре, полученный при помощи использования функции LoadKeyboardLayout или GetKeyboardLayoutList или одного из следующих значений:

  • HKL_NEXT - Выбирает следующую раскладку в списке раскладок символов на клавиатуре, поддерживаемых системой.
  • HKL_PREV - Выбирает предыдущую раскладку в списке раскладок символов на клавиатуре, поддерживаемых системой.

Flags
Определяет флажки раскладки символов на клавиатуре. Значение этого параметра может быть:

  • KLF_REORDER - Переупорядочивает список раскладок символов на клавиатуре, перемещая данный дескриптор раскладки в начало списка. Если это значение не дается, список пролистывается без изменения порядка. Например, если пользователь имеет активной Английскую раскладку, а также имеет загруженные Французскую, Немецкую и Испанскую раскладки (вот в таком порядке), то активизация Немецкой раскладки с установленным битом KLF_REORDER создаст следующий порядок: Немецкая, Английская, Французская, Испанская раскладки. Активизация Немецкой раскладки без установки значения KLF_REORDER создала бы следующий порядок: Немецкая, Испанская, Английская, Французская раскладки.

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

Замечания
Несколько раскладок символов на клавиатуре могут быть загруженными в любой момент, но в каждый отдельный момент, активной - может быть только одна. Загрузка многочисленных раскладок клавиатуры делает возможным быстро переключаться между ними.
Прикладная программа может создать правильный дескриптор раскладки, при помощи установки в старшем слове нулей, а младшем слове идентификатора региона. Использование таких дескрипторов раскладки символов на клавиатуре изменяет язык ввода данных без воздействия на физическую раскладку.
Когда для каждого региона предусмотрены многочисленные редакторы метода ввода данных (IME), передающийся дескриптор раскладки символов на клавиатуре, в котором старшее слово (дескриптор устройства) является нулевым, приводит в действие первый IME в списке "принадлежащем" региону.

Смотри также
LoadKeyboardLayout, GetKeyboardLayoutName, UnloadKeyboardLayout

Windows NT:

Функция ActivateKeyboardLayout активизирует другую раскладку символов на клавиатуре и устанавливает активную раскладку символов в целом для системы, а не для вызывающего потока.

Синтаксис

BOOL ActivateKeyboardLayout(
    HKL hkl,		// дескриптор раскладки клавиатуры
    UINT Flags	// флажки раскладки клавиатуры
);

Параметры
hkl
Идентифицирует раскладку символов на клавиатуре, которая будет активизирована. Раскладка должна быть загружена предыдущим вызовом функции LoadKeyboardLayout. Этот параметр должен быть или дескриптор раскладки символов на клавиатуре или одно из следующих значений:

  • HKL_NEXT - Выбирает следующую раскладку в списке раскладок символов на клавиатуре, поддерживаемых системой.
  • HKL_PREV - Выбирает предыдущую раскладку в списке раскладок символов на клавиатуре, поддерживаемых системой.

Flags
Определяет, какая раскладка символов на клавиатуре должна быть активизирована. Этот параметр может быть одним из следующих значений:

  • KLF_REORDER - Если этот бит установлен, кольцевой список системы загруженных раскладок символов на клавиатуре переупорядычевается. Если этот бит не установлен, список чередуется без изменения порядка. Например, если пользователь имел активной Английскую раскладку, а также имеет загруженные Французскую, Немецкую и Испанскую раскладки (вот в таком порядке), то активизация Немецкой раскладки с установленным битом KLF_REORDER создаст следующий порядок: Немецкая, Английская, Французская, Испанская раскладки. Активизация Немецкой раскладки без установки значения KLF_REORDER создала бы следующий порядок: Немецкая, Испанская, Английская, Французская раскладки.Если загружены меньше чем три раскладки символов на клавиатуре, значение этого флажка не применяется.
  • KLF_UNLOADPREVIOUS - Предварительно загружает активную раскладку клавиатуры.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - ИСТИНА (TRUE).
Если функция не выполняет задачу, величина возвращаемого значения - ЛОЖЬ(FALSE). Чтобы получить расширенные данные об ошибках, вызовите GetLastError.

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

Смотри также
LoadKeyboardLayout, GetKeyboardLayoutName, UnloadKeyboardLayout

Размещение и совместимость ActivateKeyboardLayout

Windows NT				Да
Win95					Да
Win32s					Нет
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


10.16.1.2 - Функция EnableWindow

(ВключитьОкно)

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

Синтаксис

BOOL EnableWindow
(
    HWND hWnd,	// дескриптор окна
    BOOL bEnable	// флажок для включения или отключения ввода
);

Параметры
hWnd
Идентифицирует окно, которое будет включено или заблокировано.
bEnable
Определяет, включить или отключить окно. Если этот параметр - ИСТИНА (TRUE), окно включено. Если параметр - ЛОЖЬ(FALSE), окно заблокировано.

Возвращаемые значения
Если окно было предварительно заблокировано, величина возвращаемого значения отличная от нуля.
Если окно предварительно не было заблокировано, величина возвращаемого значения нулевая. Чтобы получить расширенные данные об ошибках, вызовите GetLastError.

Замечания
Если включенное состояние окна изменяется, отправляется сообщение WM_ENABLE перед возвратом значения функцией EnableWindow. Если окно уже заблокировано, все его дочерние окна неявно заблокированы, хотя они не отправляют сообщение WM_ENABLE.
Окно должно быть включено прежде, чем оно может быть активизировано. Например, если прикладная программа показывает немодальное диалоговое окно, и отключила свое главное окно, перед разрушением диалогового окна программа должна включить главное окно. Иначе, другое окно примет фокус клавиатуры и будет активизировано. Если дочернее окно заблокировано, оно игнорируется, когда Windows пробует установить, какое окно должно принять сообщения мыши.
По умолчанию окно включается тогда, когда создается. Чтобы создать окно, которое первоначально заблокировано, прикладная программа, может определить в функции CreateWindow или CreateWindowEx стиль WS_DISABLED. После того, как окно будет создано, прикладная программа может использовать EnableWindow, чтобы включать или отключать окно.
Прикладная программа может использовать эту функцию, чтобы включить или отключить орган управления в диалоговом окне. Заблокированный элемент управления не может принимать фокус клавиатуры, и при этом пользователь не может получить доступ к нему.

Смотри также
CreateWindow, CreateWindowEx, IsWindowEnabled, WM_ENABLE

Размещение и совместимость EnableWindow

Windows NT					Да
Win95						Да
Win32s						Да
Импортируемая библиотека				user32.lib
Заголовочный файл					winuser.h
Unicode						Нет
Замечания по платформе				Не имеется


10.16.1.3 - Функция GetActiveWindow

(ПолучитьАктивноеОкно)

Функция GetActiveWindow извлекает оконный дескриптор активного окна, связанного с потоком, который вызывает функцию.

Синтаксис

HWND GetActiveWindow(VOID)

Параметры
У этой функции нет параметров.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - дескриптор активного окна, связанного с потоком, который вызывает функцию. Если вызывающий поток не имеет активного окна, величина возвращаемого значения - ПУСТО (NULL).

Смотри также
SetActiveWindow

Размещение и совместимость GetActiveWindow

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


10.16.1.4 - Функция GetAsyncKeyState

(ПолучитьАсинхронноСостояниеКлавиши)

Функция GetAsyncKeyState устанавливает, в нажатом или отпущенном состоянии находится клавиша во время, когда вызывается функция и была ли клавиша нажата после предыдущего вызова GetAsyncKeyState().

Синтаксис

SHORT GetAsyncKeyState
(
    int vKey	// код виртуальной клавиши
);

Параметры
vKey
Определяет один из 256 возможных кодов виртуальной клавиши.

Windows NT: Вы можете использовать лево - и правосторонние константы, чтобы определять некоторые клавиши. Для дополнительной информации см. раздел Замечания.
Windows 95: Windows 95 не поддерживает лево - и правосторонние константы, доступные в Windows NT.

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

Замечания
Вы можете использовать константы кода виртуальной клавиши VK_SHIFT, VK_CONTROL и VK_MENU как значения для параметра vKey. Это дает состояние клавиш SHIFT, CTRL или ALT без различия между левой и правой сторонами.
Windows NT: Вы можете использовать следующие константы кода виртуальной клавиши как значения для vKey, чтобы делать различие между левыми и правыми экземплярами этих клавиш:

VK_LSHIFT	VK_RSHIFT
VK_LCONTROL	VK_RCONTROL
VK_LMENU	VK_RMENU

Эти лево- и правосторонние константы доступны только тогда, когда Вы вызываете функции GetKeyboardState, SetKeyboardState, GetAsyncKeyState, GetKeyState и MapVirtualKey
Windows 95: Windows 95 не поддерживает лево - и правосторонние константы и возвращается 0, когда Вы используете эти константы.
Функция GetAsyncKeyState работает с кнопками мыши. Однако она контролирует состояние физических, а не логических кнопок мыши, которыми физические кнопки отображаются. Например, вызов GetAsyncKeyState (VK_LBUTTON) всегда возвращает состояние левой физической кнопки мыши, которая может отображать левую или правую логическую кнопку мыши. Вы можете установить текущее отображение физических кнопок мыши в логических кнопках мыши системой путем вызова функции

GetSystemMetrics(SM_SWAPBUTTON)

которая возвращает значение ИСТИНА (TRUE), если кнопки мыши менялись.

Смотри также
GetKeyboardState, GetKeyState, GetSystemMetrics, MapVirtualKey, SetKeyboardState

Размещение и совместимость GetAsyncKeyState

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


10.16.1.5 - Функция GetFocus

(ПолучитьФокус)

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

Синтаксис

HWND GetFocus(VOID)

Параметры
У этой функции нет параметров.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - дескриптор окна с фокусом клавиатуры. Если очередь сообщений вызывающего потока не имеет связанного окна с фокусом клавиатуры, величина возвращаемого значения - ПУСТО (NULL).

Замечания
Даже если GetFocus возвращает значение ПУСТО (NULL), очередь другого потока может быть связана с окном, которое имеет фокус клавиатуры.
Используйте функцию GetForegroundWindow, чтобы извлечь дескриптор окна, с которым пользователь в настоящее время работает. Вы можете сопоставить очередь сообщений вашего потока с окнами, принадлежащими другому потоку, используя функцию AttachThreadInput.

Смотри также
AttachThreadInput, GetForegroundWindow, SetFocus, WM_KILLFOCUS, WM_SETFOCUS

Размещение и совместимость GetFocus

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


10.16.1.6 - Функция GetKeyboardLayout

(ПолучитьРаскладкуКлавиатуры)

[Теперь поддерживается Windows NT]

Функция GetKeyboardLayout извлекает данные об активной раскладке символов на клавиатуре для заданного потока. Если параметр dwLayout нулевой, возвращается значение раскладки для активного потока.

Синтаксис

HKL GetKeyboardLayout
(
    DWORD dwLayout	// идентификатор потока
);

Параметры
dwLayout
Идентифицирует поток, который делает запрос или является нулем для текущего потока.

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

Смотри также
ActivateKeyboardLayout, CreateThread, LoadKeyboardLayout

Размещение и совместимость GetKeyboardLayout

Windows NT				Да
Win95					Да
Win32s					Нет
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


10.16.1.7 - Функция GetKeyboardLayoutList

(ПолучитьСписокРаскладокКлавиатуры)

[Теперь поддерживается Windows NT]

Функция GetKeyboardLayoutList() извлекает дескрипторы раскладки символов на клавиатуре, соответствующие текущему набору входящих регионов в системе. Функция копирует дескрипторы в данный буфер.

Синтаксис

UINT GetKeyboardLayoutList
(
    int nBuff,		// размер буфера в элементе массива
    HKL FAR *lpList	// буфер для дескрипторов раскладки символов на клавиатуре
);

Параметры
nBuff
Определяет максимальное число дескрипторов, которые буфер может содержать.
lpList
Указывает на буфер, массив которого принимает дескрипторы раскладки символов на клавиатуре.

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

Смотри также
GetKeyboardLayout

Размещение и совместимость GetKeyboardLayoutList

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


10.16.1.8 - Функция GetKeyboardLayoutName

(ПолучитьИмяРаскладкиКлавиатуры)

Функция GetKeyboardLayoutName извлекает данные о названии активной раскладки символов на клавиатуре.

Синтаксис

BOOL GetKeyboardLayoutName
(
    LPTSTR pwszKLID	//адрес буфера для названия раскладки клавиатуры
);

Параметры
pwszKLID
Указывает на буфер, по крайней мере, символов KL_NAMELENGTH, который должен принять название раскладки символов на клавиатуре, включая признак конца (нуль-терминатор). Это должна быть копия строки, предоставленная функции LoadKeyboardLayout, если замена раскладки не происходила.

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

Замечания
Windows NT:
GetKeyboardLayoutName получает название активной раскладки символов на клавиатуре для системы.
Windows 95:
GetKeyboardLayoutName получает название активной раскладки символов на клавиатуре для вызывающего потока.

Смотри также
ActivateKeyboardLayout, LoadKeyboardLayout, UnloadKeyboardLayout

Размещение и совместимость GetKeyboardLayoutName

Windows NT				Да
Win95					Да
Win32s					Нет
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					WinNT
Замечания по платформе			Не имеется


10.16.1.9 - Функция GetKeyboardState

(ПолучитьСостояниеКлавиатуры)

Функция GetKeyboardState копирует состояние 256 виртуальных клавиш в заданный буфер.

Синтаксис

BOOL GetKeyboardState
(
    PBYTE lpKeyState	// адрес массива, который принимает данные состояния
);

Параметры
lpKeyState
Указывает на 256-байтовый массив, который принимает данные состояния для каждой виртуальной клавиши.

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

Замечания
Прикладная программа может вызвать эту функцию, чтобы извлечь данные о текущем состоянии всех виртуальных клавиш. Состояние изменяется тогда, когда поток удаляет сообщения клавиатуры из ее очереди сообщений. Состояние не изменяется тогда, когда сообщения клавиатуры посланы в очередь сообщений.
Когда функция возвращает значение, каждый элемент массива, указанного параметром lpKeyState содержит данные о состоянии виртуальной клавиши. Если старший бит равен 1, клавиша нажата; иначе она не отпущена. Если младший бит равен 1, клавиша переключилась. Клавиша, такая как CAPS LOCK, переключается, если она является включенной. Клавиша выключена и не переключает, если младший бит равен 0. Когда клавиша переключается, индикатор переключения клавиши на клавиатуре (если он есть) должен быть включен, и отключен, когда клавиша не переключается.
Чтобы извлекать информацию состояния для отдельной клавиши, используйте функцию GetKeyState.
Прикладная программа может использовать константы кодов виртуальных клавиш VK_SHIFT, VK_CONTROL и VK_MENU как индексы в массиве, указанном lpKeyState. Это дает состояние клавиш SHIFT, CTRL или ALT без различия между левой и правой сторонами. Прикладная программа может также использовать следующие константы кода виртуальной клавиши как индексы, чтобы различить между левыми и правыми экземплярами этих клавиш:

VK_LSHIFT	VK_RSHIFT
VK_LCONTROL	VK_RCONTROL
VK_LMENU	VK_RMENU

Эти лево- и правосторонние константы доступны прикладной программе только через функции GetKeyboardState, SetKeyboardState, GetAsyncKeyState, GetKeyState и MapVirtualKey.

Смотри также
GetKeyState, GetAsyncKeyState, MapVirtualKey, SetKeyboardState

Размещение и совместимость GetKeyboardState

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


10.16.1.10 - Функция GetKeyNameText

(ПолучитьТекстИмениКлавиши)

Функция GetKeyNameText извлекает строку, которая представляет название клавиши.

Синтаксис

int GetKeyNameText(
    LONG lParam,	// второй параметр сообщения клавиатуры
    LPTSTR lpString,	// адрес буфера с именем клавиши
    int nSize	// максимальная длина строки с именем клавиши
);

Параметры
lParam
Определяет второй параметр сообщения клавиатуры (типа WM_KEYDOWN) для обработки. Функция интерпретирует следующие части lParam (Бит-Предназначение):

  • 16-23 - Скэн-код.
  • 24 - Флажок дополнительной клавиши. Дает отличительный признак для некоторых клавиш расширенной клавиатуры.
  • 25 - Бит " Безразличное состояние ". Прикладная программа, вызывающая эту функцию устанавливает этот бит, чтобы указать, что функция не должна различать, например, между левыми и правыми клавишами CTRL и SHIFT.

lpString
Указывает на буфер, который примет название клавиши.
nSize
Определяет максимальную длину, в символах, названия клавиши, включая символ завершения строки (нуль-терминатор). (Этот параметр должен быть равен размеру буфера, указанного параметром lpString.)

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

Замечания
Формат строки с названием клавиши зависит от текущей раскладки символов на клавиатуре. Драйвер клавиатуры поддерживает список названий в форме символьных строк для клавиш с названиями длиннее, чем один символ. Название клавиши транслируется в соответствии с текущей раскладкой установленной клавиатуры. Названием символьных клавиш является сам символ, обозначающий её. Названия мертвых клавиш вполне обстоятельно разъяснены.

Размещение и совместимость GetKeyNameText

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					WinNT
Замечания по платформе			Не имеется


10.16.1.11 - Функция GetKeyState

(ПолучитьСостояниеКлавиши)

Функция GetKeyState извлекает данные о состоянии заданной виртуальной клавиши. Состояние определяет, является ли клавиша нажатой, не нажатой или переключенной (вкл., выкл. - чередуется, каждый раз, когда нажимается клавиша).

Синтаксис

SHORT GetKeyState
(
    int nVirtKey	// код виртуальной клавиши
);

Параметры
nVirtKey
Определяет виртуальную клавишу. Если нужная виртуальная клавиша - буква или цифра (от А до Z, от а до z или от 0 до 9), nVirtKey должен быть установлен в значение ASCII этого символа. Для других клавиш, он должен быть кодом виртуальной клавиши.
Если на клавиатуре используется неанглийская раскладка символов, используются виртуальные клавиши со значениями в диапазоне ASCII от А до Z и от 0 до 9, чтобы определить большинство знаковых клавиш. Например, для немецкой раскладки символов на клавиатуре, виртуальная клавиша «O» со значение ASCII (0x4F) представляет клавишу "o", принимая во внимание, что VK_OEM_1 представляет клавишу "o с умлаутом".

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения определяет состояние данной виртуальной клавиши. Если старший бит равен 1, клавиша нажата; иначе она отпущена. Если младший бит равен 1, клавиша переключилась. Клавиша, такая как CAPS LOCK, переключается, если она является включенной. Клавиша выключена и не переключает, если младший бит равен 0. Когда клавиша переключается, индикатор переключения клавиши на клавиатуре (если он есть) должен быть включен, и отключен, когда клавиша не переключается.

Замечания
Состояние клавиши, возвращенное этой функцией, изменяется, так как данный поток читает клавишные сообщения из ее очереди сообщений. Состояние клавиши не отражает состояния уровня прерывания, связанное с аппаратными средствами. Используйте функцию GetAsyncKeyState, чтобы получить эту информацию.
Прикладная программа, в ответ на сообщение ввода информации с клавиатуры, вызывает GetKeyState. Эта функция извлекает данные о состоянии клавиши, когда было сгенерировано сообщение о вводе данных.
Чтобы получить информацию о состоянии для всех виртуальных клавиш, используйте функцию GetKeyboardState.
Прикладная программа может использовать константы кодов виртуальных клавиш VK_SHIFT, VK_CONTROL и VK_MENU как значения для параметра nVirtKey. Это дает состояние клавиш SHIFT, CTRL или ALT без различия между ними левого и правого расположения. Прикладная программа может также использовать следующие константы кода виртуальной клавиши как значения для nVirtKey, чтобы различить между левыми и правыми экземплярами этих клавиш:

VK_LSHIFT	VK_RSHIFT
VK_LCONTROL	VK_RCONTROL
VK_LMENU	VK_RMENU

Эти лево- и правосторонние константы доступны прикладной программе только через функции GetKeyboardState, SetKeyboardState, GetAsyncKeyState, GetKeyState и MapVirtualKeyM.

Смотри также
GetAsyncKeyState, GetKeyboardState, MapVirtualKey, SetKeyboardState

Размещение и совместимость GetKeyState

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


10.16.1.12 - Функция IsWindowEnabled

(ОкноВключено)

Функция IsWindowEnabled устанавливает, включено ли заданное окно для ввода информации от мыши и клавиатуры.

Синтаксис

BOOL IsWindowEnabled
(
    HWND hWnd	// дескриптор окна, которое тестируется
);

Параметры
hWnd
Идентифицирует окно, которое тестируется

Возвращаемые значения
Если окно включено, величина возвращаемого значения отличная от нуля.
Если окно не включено, величина возвращаемого значения нуль.

Замечания
Дочернее окно принимает ввод информации, только тогда, если оно не только включено, но и видимое.

Смотри также
EnableWindow, IsWindowVisible

Размещение и совместимость IsWindowEnabled

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


10.16.1.13 - Функция keybd_event

(событие_клавиатуры)

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

Синтаксис

VOID keybd_event
(
    BYTE bVk,		// код виртуальной клавиши
    BYTE bScan,		// аппаратный скэн-код
    DWORD dwFlags,	// флажки, определяющие различные параметры функции
    DWORD dwExtraInfo	// дополнительные данные, связанные с нажатием клавиши
);

Параметры
bVk
Определяет код виртуальной клавиши. Код должен быть значением в диапазоне от 1 до 254.
bScan
Определяет для клавиши аппаратный скэн-код.
dwFlags
Набор флаговых битов, которые определяют различные виды операций функции. Прикладная программа может использовать любую комбинацию следующих предопределенных постоянных значений, чтобы установить флажки:

  • KEYEVENTF_EXTENDEDKEY - Если она установлена, скэн-коду предшествует префиксный байт, имеющий значение 0xE0 (224).
  • KEYEVENTF_KEYUP - Если установлена, клавиша была отпущена. Если не установлена, клавиша была нажата.

dwExtraInfo
Определяет дополнительное 32-разрядное значение, связанное с нажатием клавиши.

Возвращаемые значения
У этой функции нет возвращаемых значений.

Замечания
Несмотря на то, что keybd_event посылает в Windows OEM-зависимый аппаратный скэн-код, прикладные программы не должны использовать скэн-код. Windows внутри себя преобразует его в коды виртуальной клавиши и сбрасывает/устанавливает биты в скэн-коде перед передачей его в прикладную программу.
Прикладная программа может смоделировать нажатие клавиши PrintScreen, чтобы получить снимок экрана и сохранить его в буфере обмена Windows. Чтобы делать это, вызовите keybd_event с установленным параметром bVk в VK_SNAPSHOT, а параметром bScan установите в 0 для снимка полного экрана, или установите bScan в 1 для снимка активного окна.

Смотри также
GetAsyncKeyState, GetKeyState, MapVirtualKey, SetKeyboardState

Размещение и совместимость keybd_event

Windows NT				Да
Win95					Да
Win32s					Нет
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


10.16.1.14 - Функция LoadKeyboardLayout

Реализация LoadKeyboardLayout в Windows 95 и Windows NT существенно различаются. Чтобы выявить эти различия, эта страница справочника первые представляет ее реализацию в среде Windows 95 во всей полноте, в соответствии с версией Windows NT.

Windows 95:

Функция LoadKeyboardLayout загружает новую раскладку символов на клавиатуре в систему. Одновременно могут быть загруженными несколько раскладок символов на клавиатуре, но в одно и тоже время активизируется только одна на процесс. Загрузка многочисленных раскладок символов на клавиатуре делает возможным быстро переключаться между ними.

Синтаксис

HKL LoadKeyboardLayout(
    LPCTSTR pwszKLID,	// название раскладки, которая загружена
    UINT Flags 		// флажки раскладки клавиатуры
);

Параметры
pwszKLID
Указывает на буфер, который определяет название раскладки символов на клавиатуре. Это название является строкой, составленной из шестнадцатеричного значения первичного идентификатора языка (младшее слово) и идентификатора устройства (старшее слово). Например, Американский Английский язык имеет идентификатор языка 0x0409, так что первичная Американская Английская раскладка имеет название "00000409". Варианты раскладки Американского Английского языка, такие как раскладки Дворака, названы "00010409", "00020409" и так далее. За списком первичных и вторичных идентификаторов языка, которые составляют общий идентификатор языка, следит макрокоманда MAKELANGID.
Flags
Определяет, как раскладка символов на клавиатуре должна быть загружена. Этот параметр может быть одним из следующих значений:

  • KLF_ACTIVATE - Если данная раскладка ещё не загружена, функция загружает и активизирует раскладку для текущего потока, вставляя раскладку в голову списка раскладок символов на клавиатуре, впереди активной предыдущей раскладки. Если раскладка уже загружена, а значение KLF_REORDER не дается, функция просто вращает список раскладок символов на клавиатуре, делая следующую раскладку активной.
  • KLF_NOTELLSHELL - Препятствует подключаемой процедуре ShellProc принимать код hook-точки HSHELL_LANGUAGE, когда загружается новая раскладка. Это значение обычно используется тогда, когда прикладная программа загружает многочисленные раскладки, одну за другой. Применение этого значения, ко всем кроме последней раскладки, задерживает обработку оболочки, пока не будут добавлены все раскладки.
  • KLF_REORDER - Перемещает данную раскладку в голову списка раскладок символов на клавиатуре, делая её активной для текущего потока. Это значение переупорядочивает список раскладок символов на клавиатуре, даже если не дается KLF_ACTIVATE
  • KLF_REPLACELANG - Если новая раскладка имеет тот же самый идентификатор языка, как и текущая раскладка, новая раскладка заменяет текущую как раскладку для этого языка. Если это значение не дается, а раскладки имеют те же самые идентификаторы языка, текущая раскладка не заменяется, а функция возвращает значение ПУСТО (NULL).
  • KLF_SUBSTITUTE_OK - Меняет заданную раскладку символов на клавиатуре другой раскладкой, предпочитаемой пользователем. Замена происходит, только тогда, если ключ регистрации HKEY_CURRENT_USER\Keyboard Layout\Substitutes явно определяет замену раскладки. Например, если ключ включает в себя значение названия "00000409" со значением "00010409", загрузка Американской Английского языка раскладки ("00000409") вынуждает быть загруженной вместо её раскладку США Английского языка Дворака ("00010409"). Система использует KLF_SUBSTITUTE_OK при загрузке, и рекомендуется, чтобы все прикладные программы использовали также это значение.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - дескриптор раскладки символов на клавиатуре, согласованного с требуемым названием или ПУСТО (NULL), если никакая согласующаяся клавиатура не доступна.

Замечания
Если раскладка загружается с тем же самым языком, какой был до этого загружен, а флажок KLF_REPLACELANG не устанавливается, вызов функции терпит неудачу. Только одна загруженная раскладка может быть связана с данным языком. (Это приемлемо для многих IMEs, которые загружаются связанные с тем же самым языком.)
Прикладная программа может и должна, обычно желательно, загрузить заданную по умолчанию раскладку или IME для языка, а может сделать так при помощи определения только строковой версии идентификатора языка. Если прикладная программа хочет загрузить заданную раскладку или IME, она должна прочитать системный реестр, чтобы установить заданный идентификатор раскладки, чтобы передать его в LoadKeyboardLayout. В этом случае, запрос активизирует заданный по умолчанию дескриптор раскладки символов на клавиатуре для региона, который приведет в действие одно из первых соответствий. Заданный IME должен быть активизирован, используя явный дескриптор раскладки символов на клавиатуре, возвращенный от одной из функций GetKeyboardLayout, GetKeyboardLayoutList или LoadKeyboardLayout.

Смотри также
ActivateKeyboardLayout, GetKeyboardLayout, GetKeyboardLayoutName, MAKELANGID, UnloadKeyboardLayout

Windows NT:

Функция LoadKeyboardLayout загружает раскладку символов на клавиатуре.

Синтаксис

HKL LoadKeyboardLayout(
    LPCTSTR pwszKLID,	// адрес буфера с названием раскладки
    UINT Flags		// флажки раскладки клавиатуры
);

Параметры
pwszKLID
Указывает на буфер, который определяет название раскладки символов на клавиатуре. Название должно быть получено из шестнадцатеричного значения идентификатора языка, соответствующего раскладке. Например, Американский Английский язык имеет идентификатор языка 0x0409, так что первичная Американская Английского языка раскладка называется "00000409". Варианты Американской Английского языка раскладки, типа раскладки Дворака, названы "00010409", "00020409", и так далее. За списком первичных идентификаторов языка и идентификаторов подмножества языка, которые составляют идентификатор языка, следит макрокоманда MAKELANGID.
Flags
Устанавливает, как раскладка символов на клавиатуре должна быть загружена. Этот параметр может быть одним из следующих значений:

  • KLF_ACTIVATE - Функция загружает раскладку, если она ещё не загружена, и активизирует её. Это значение активизирует раскладку для системы, взятой в целом, а не только для вызывающего потока.
  • KLF_REORDER - Этот флажок значим, только тогда, если установлен флажок KLF_ACTIVATE, а раскладка уже загружена. Если эти условия выполнены и бит KLF_REORDER установлен, функция удаляет заданную раскладку из её позиции в круговом списке системы загруженных раскладок и перемещает её в голову списка как активную раскладку.Если бит KLF_ACTIVATE установлен и раскладка загружена, но бит KLF_REORDER не установлен, функция просто вращает круговой список загруженных раскладок в системе.Если флажок KLF_ACTIVATE установлен, а раскладка ещё не загружена, она загружается как активная раскладка и вставляется в системный круговой список раскладок клавиатуры впереди активной предыдущей раскладки.
  • KLF_SUBSTITUTE_OK - Заданная раскладка ищет в конфигурации пользователя (в системном реестре под ключом HKEY_CURRENT_USER\Keyboard Layout\Substitutes) раскладку замены, предпочитаемую пользователем. Например, если в этом разделе имелось значение названия "00000409" равное "00010409", загружается Американская Английского языка раскладка ("00000409") с установкой флажка KLF_SUBSTITUTE_OK, который заставит быть загруженной раскладку США Английского языка Дворака ("00010409")
  • KLF_UNLOADPREVIOUS - Если флажок KLF_ACTIVATE установлен, а раскладка успешно загружена и активизирована, функция выгружает активную предыдущую раскладку. Иначе, функция игнорирует этот флажок.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - дескриптор раскладки символов на клавиатуре.
Если функция не выполняет задачу, величина возвращаемого значения - ПУСТО (NULL). Чтобы получить расширенные данные об ошибках, вызовите GetLastError.

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

Смотри также
ActivateKeyboardLayout, GetKeyboardLayoutName, UnloadKeyboardLayout

Размещение и совместимость LoadKeyboardLayout

Windows NT				Да
Win95					Да
Win32s					Нет
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					WinNT
Замечания по платформе			Windows 95: В одно и то же время загружается только 1 клавиатура


10.16.1.15 - Функция MapVirtualKey

(ПреобразоватьВиртуальнуюКлавишу)

Функция MapVirtualKey транслирует код виртуальной клавиши в скэн-код или символьное значение, или переводит скэн-код в код виртуальной клавиши.

Синтаксис

UINT MapVirtualKey(
    UINT uCode,	// код виртуальной клавиши или скэн-код
    UINT uMapType	// трансляция для исполнения
);

Параметры
uCode
Определяет код виртуальной клавиши или скэн-код для клавиши. Как это значение интерпретируется, зависит от значения параметра uMapType.
uMapType
Определяет трансляцию для исполнения. Значение этого параметра зависит от значения параметра uCode:

Значение 		Предназначение
0		uCode - код виртуальной клавиши и транслируется в скэн-код. Если это код виртуальной клавиши,
        который не делает различия между лево - и правосторонними клавишами, возвращается скэн-код левой клавиши.
        Если не происходит никакой трансляции, функция возвращает значение 0.
1		uCode - скэн-код и транслируется в код виртуальной клавиши, который не делает различия между лево -
        и правосторонними клавишами. Если не происходит никакой трансляции, функция возвращает значение 0.
2		uCode - код виртуальной клавиши и транслируется в значение символов нижнего регистра, в младшем
        слове величина возвращаемого значения. Мертвые клавиши (диакритические знаки) обозначаются при
        помощи установки старшего бита величины возвращаемого значения. Если не происходит никакой
        трансляции, функция возвращает значение 0.
3		uCode - скэн-код и транслируется в код виртуальной клавиши, который делает различие между
        лево - и правосторонними клавишами. Если не производится никакой трансляции, функция
        возвращает значение 0.

Возвращаемые значения
Величина возвращаемого значения является или скэн-кодом, кодом виртуальной клавиши, или символьным значением, которое зависит от значения uCode и uMapType. Если не производится никакой трансляции, величина возвращаемого значения нулевая.

Замечания
Прикладная программа может использовать MapVirtualKey, чтобы перевести скэн-коды в константы кода виртуальной клавиши VK_SHIFT, VK_CONTROL и VK_MENU и наоборот. Эти трансляции не делают различия между левыми и правыми экземплярами клавиш SHIFT, CTRL или ALT. Прикладная программа может получить скэн-код, соответствующий для левого или правого экземпляра одной из этих клавиш путем вызова MapVirtualKey с установкой uCode в одну из следующих констант кода виртуальной клавиши:

VK_LSHIFT	VK_RSHIFT
VK_LCONTROL	VK_RCONTROL
VK_LMENU	VK_RMENU

Эти лево - и правосторонние константы доступны прикладной программе только через функции GetKeyboardState, SetKeyboardState, GetAsyncKeyState, GetKeyState и MapVirtualKey.

Смотри также
GetAsyncKeyState, GetKeyboardState, GetKeyState, SetKeyboardState

Размещение и совместимость MapVirtualKey

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


10.16.1.16 - Функция MapVirtualKeyEx

(ПреобразоватьВиртуальнуюКлавишуРасширенная)

[Теперь поддерживается в Windows NT]

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

Синтаксис

UINT MapVirtualKeyEx(
    UINT uCode,		// код виртуальной клавиши или скэн-код
    UINT uMapType,	// трансляция для выполнения
    HKL dwhkl		// дескриптор раскладки символов для клавиатуры
);

Параметры
uCode
Определяет код виртуальной клавиши или скэн-код для клавиши. Как это значение интерпретируется, зависит от значения параметра uMapType.
uMapType
Определяет трансляцию для исполнения. Значение этого параметра зависит от значения параметра uCode:

Значение 		Предназначение
0		uCode - код виртуальной клавиши и транслируется в скэн-код. Если это код виртуальной клавиши,
        который не делает различия между лево - и правосторонними клавишами, возвращается скэн-код левой
        клавиши. Если не происходит никакой трансляции, функция возвращает значение 0.
1		uCode - скэн-код и транслируется в код виртуальной клавиши, который не делает различия между
        лево - и правосторонними клавишами. Если не происходит никакой трансляции, функция возвращает
        значение 0.
2		uCode - код виртуальной клавиши и транслируется в значение символов нижнего регистра, в
        младшем слове величина возвращаемого значения. Мертвые клавиши (диакритические знаки) обозначаются
        при помощи установки старшего бита величины возвращаемого значения. Если не происходит никакой
        трансляции, функция возвращает значение 0.
3		uCode - скэн-код и транслируется в код виртуальной клавиши, который делает различие между лево -
        и правосторонними клавишами. Если не производится никакой трансляции, функция возвращает значение 0.

dwhkl
Идентифицирует раскладку символов на клавиатуре, которая используется для трансляции данного кода. Этот параметр может быть любой дескриптор раскладки символов на клавиатуре, предварительно возвращенный функцией LoadKeyboardLayout.

Возвращаемые значения
Величина возвращаемого значения является или скэн-кодом, кодом виртуальной клавиши, или символьным значением, которое зависит от значения uCode и uMapType. Если не производится никакой трансляции, величина возвращаемого значения нулевая.

Замечания
Прикладная программа может использовать MapVirtualKeyEx, чтобы перевести скэн-коды в константы кода виртуальной клавиши VK_SHIFT, VK_CONTROL и VK_MENU и наоборот. Эти трансляции не делают различия между левыми и правыми экземплярами клавиш SHIFT, CTRL или ALT. Прикладная программа может получить скэн-код, соответствующий для левого или правого экземпляра одной из этих клавиш путем вызова MapVirtualKeyEx с установкой uCode в одну из следующих констант кода виртуальной клавиши:

VK_LSHIFT	VK_RSHIFT
VK_LCONTROL	VK_RCONTROL
VK_LMENU	VK_RMENU

Эти лево - и правосторонние константы доступны прикладной программе только через функции GetKeyboardState, SetKeyboardState, GetAsyncKeyState, GetKeyState, MapVirtualKey и MapVirtualKeyEx.

Смотри также
GetAsyncKeyState, GetKeyboardState, GetKeyState, LoadKeyboardLayout, MapVirtualKey, SetKeyboardState

Размещение и совместимость MapVirtualKeyEx

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


10.16.1.17 - Функция OemKeyScan

(ОпределитьКлавишуОЕМ)

Функция OemKeyScan преобразует OEM ASCII коды от 0 до 0x0FF в OEM скэн-коды и состояние переключения. Функция предоставляет информацию, которая позволяет программе посылать текст OEM другой программе, моделируя ввод информации с клавиатуры.

Синтаксис

DWORD OemKeyScan
(
    WORD wOemChar		// значение ASCII символа OEM
);

Параметры
wOemChar
Определяет значение ASCII символа OEM.

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

Бит 	Значение
1	Любая клавиша SHIFT нажата.
2	Любая клавиша CTRL нажата.
4	Любая клавиша ALT нажата.

Если символ не может быть произведен единственным нажатием клавиши, при использовании текущей раскладки символов на клавиатуре, величина возвращаемого значения - 0xFFFFFFFF.

Замечания
Эта функция не предусматривает трансляции для символов, которые требуют CTRL+ALT или мертвых клавиш. Символы, не оттранслированные этой функцией должны быть скопированы, при помощи моделирования ввода, используя ALT + механизм вспомогательной клавиатуры. Клавиша NUMLOCK должна быть отключена.
Эта функция не предусматривает трансляции для символов, которые не могут быть введены с клавиатуры одним нажатием клавиши, используя текущую раскладку символов на клавиатуре, типа символов с диакритическими знаками, требующими мертвых клавиш. Символы, не оттранслированные этой функцией могут моделироваться, используя ALT + механизм вспомогательной клавиатуры. Клавиша NUMLOCK должна быть включена.
Эта функция является инструментом, использующим функцию VkKeyScan.

Смотри также
VkKeyScan

Размещение и совместимость OemKeyScan

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


10.16.1.18 - Функция RegisterHotKey

(РегистрацияГрячейКлавиши)

Функция RegisterHotKey определяет комбинацию "горячая" клавиша для текущего потока.

Синтаксис

BOOL RegisterHotKey
(
    HWND hWnd,		// окно, которое принимает уведомление "горячей" клавиши
    int id,		// идентификатор "горячей" клавиши
    UINT fsModifiers,	// флажки модификации клавиш
    UINT vk		// код виртуальной клавиши
);

Параметры
hWnd
Идентифицирует окно, которое примет сообщения WM_HOTKEY, сгенерированные комбинацией "горячая" клавиша. Если этот параметр - ПУСТО (NULL), сообщения WM_HOTKEY посылаются в очередь сообщений вызывающего потока и должны быть обработаны в цикле сообщений.
id
Определяет идентификатор комбинации "горячая" клавиша. Никакая другая "горячая" клавиша в вызывающем потоке не может иметь тот же самый идентификатор. Прикладная программа должна определить значение в диапазоне от 0x0000 до 0xBFFF. Динамически подключаемая библиотека DLL совместного использования должна определить значение в диапазоне от 0xC000 до 0xFFFF (диапазон, возвращаемый функцией GlobalAddAtom). Чтобы избежать конфликтов с идентификаторами "горячей" клавиши, определенными другими разделяемыми DLL, динамически подключаемая библиотека, чтобы получить идентификатор "горячей" клавиши, должна использовать функцию GlobalAddAtom.
fsModifiers
Определяет клавиши, которые должны быть нажаты в комбинации с клавишей, заданной параметром nVirtKey, чтобы генерировать сообщение WM_HOTKEY. Параметр fsModifiers может быть комбинацией следующих значений:

  • MOD_ALT - Любая клавиша ALT должна удерживаться нажатой.
  • MOD_CONTROL - Любая клавиша CTRL должна удерживаться нажатой.
  • MOD_SHIFT - Любая клавиша SHIFT должна удерживаться нажатой.

vk
Определяет код виртуальной клавиши комбинации "горячая" клавиша.

Возвращаемые значения
Если функция завершилась успешно, возвращается значение отличное от нуля.
Если функция потерпела неудачу, возвращаемое значение - ноль.

Замечания
Когда клавиша нажимается, система ищет соответствие во всех комбинациях "горячая" клавиша потока. После обнаружения соответствия, система посылает сообщение WM_HOTKEY в очередь сообщений потока, который зарегистрировал комбинацию "горячая" клавиша. Это сообщение посылается в начало очереди, так что оно удаляется следующим повтором цикла сообщений.
Эта функция не может связывать комбинацию "горячая" клавиша с окном, созданным другим потоком.
Функция RegisterHotKey терпит неудачу, если нажатия клавиш, определенные для "горячей" клавиши были уже зарегистрированы другой "горячей" клавишей.
Если окно, идентифицированное параметром hWnd, уже зарегистрировало комбинацию "горячая" клавиша с тем же самым идентификатором, как тот, что определен параметром id, новые значения для параметров fsModifiers и vk заменяют предварительно заданные величины для этих параметров.

Смотри также
GlobalAddAtom, UnregisterHotKey, WM_HOTKEY

Размещение и совместимость RegisterHotKey

Windows NT				Да
Win95					Да
Win32s					Нет
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


10.16.1.19 - Функция SetActiveWindow

(УстановитьАктивноеОкно)

Функция SetActiveWindow активизирует окно.

Синтаксис

HWND SetActiveWindow
(
    HWND hWnd		// дескриптор окна, которое активизируется
);

Параметры
hWnd
Идентифицирует окно верхнего уровня, которое будет активизировано.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - дескриптор окна, которое было до этого активно.

Замечания
Функция SetActiveWindow активизирует окно, но только не в том случае, когда прикладная программа в фоновом режиме. Окно будет приведено в активный режим (на вершину Z-последовательности), если прикладная программа являлась высокоприоритетной, когда ему устанавливали активность.
Если окно, идентифицированное параметром hWnd, было создано вызывающим потоком, состояние активного окна вызывающего потока устанавливается в hWnd. Иначе, состояние активного окна вызывающего потока устанавливается в значение ПУСТО (NULL).
С другой стороны, функция окна SetForegroundWindow, активизирует окно и переводит его в разряд приоритетных. Прикладная программа должна вызвать SetForegroundWindow только тогда, если требуется отобразить критические ошибки или информацию, которая нуждается в немедленном внимании пользователя.

Смотри также
GetActiveWindow, SetForegroundWindow, WM_ACTIVATE

Размещение и совместимость SetActiveWindow

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


10.16.1.20 - Функция SetFocus

(УстановитьФокус)

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

Синтаксис

HWND SetFocus
(
    HWND hWnd	// дескриптор окна, которому передается фокус
);

Параметры
hWnd
Идентифицирует окно, которое примет ввод информации с клавиатуры. Если этот параметр - ПУСТО (NULL), нажатия клавиши игнорируются.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - дескриптор окна, которое до этого имело фокус клавиатуры. Если параметр hWnd недопустимый или окно не связано с очередью сообщений вызывающего потока, величина возвращаемого значения - ПУСТО (NULL).

Замечания
Функция SetFocus отправляет сообщение WM_KILLFOCUS окну, которое теряет фокус клавиатуры, а сообщение WM_SETFOCUS окну, которое принимает фокус клавиатуры. Она также активизирует или окно, которое принимает фокус или родителя этого окна.
Если окно активное, но не имеет фокуса, любая нажатая клавиша произведет сообщение WM_SYSCHAR, WM_SYSKEYDOWN или WM_SYSKEYUP. Если клавиша VK_MENU также нажата, параметр lParam сообщения будет иметь установленным 30-й бит. Иначе, созданные сообщения не получат установки этого бита.
При использовании функции AttachThreadInput, поток может подключить обработку своего ввода информации к другому потоку. Это дает возможность потоку вызывать SetFocus, чтобы установить фокус клавиатуры в окно, связанное с очередью сообщений другого потока.

Смотри также
AttachThreadInput, GetFocus, WM_KILLFOCUS, WM_SETFOCUS, WM_SYSCHAR, WM_SYSKEYDOWN, WM_SYSKEYUP

Размещение и совместимость SetFocus

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


10.16.1.21 - Функция SetKeyboardState

(УстановитьСостояниеКлавиатуры)

Функция SetKeyboardState копирует 256-байтовый массив состояний клавиш клавиатуры в таблицу состояния ввода информации с клавиатуры вызывающего потока. Это - та же самая таблица, к которой обращаются функции GetKeyboardState и GetKeyState. Изменения, сделанные в этой таблице, не воздействуют на ввод информации с клавиатуры любого другого потока.

Синтаксис

BOOL SetKeyboardState
(
    LPBYTE lpKeyState	// адрес массива с кодами виртуальных клавиш
);

Параметры
lpKeyState
Указывает на 256-байтовый массив, который содержит состояния клавиш клавиатуры.

Возвращаемые значения
Если функция завершилась успешно, возвращается значение отличное от нуля.
Если функция потерпела неудачу, возвращаемое значение - ноль. Чтобы получить расширенные данные об ошибках, обратитесь к функции GetLastError.

Замечания
Поскольку функция SetKeyboardState изменяет состояние ввода данных вызывающего потока, а не глобальное состояние ввода данных системы, прикладная программа не может использовать SetKeyboardState, чтобы установить свечение индикаторов NUM LOCK, CAPS LOCK или SCROLL LOCK на клавиатуре.

Смотри также
GetAsyncKeyState, GetKeyboardState, GetKeyState, MapVirtualKey

Размещение и совместимость SetKeyboardState

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


10.16.1.22 - Функция ToAscii

(в ASCII)

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

Синтаксис

int ToAscii
(
    UINT uVirtKey,	// код виртуальной клавиши
    UINT uScanCode,	// скэн-код
    PBYTE lpKeyState,	// адрес массива состояния клавиши
    LPWORD lpChar,	// буфер для трансляции клавиши
    UINT uFlags	// флажок активного меню
);

Параметры
uVirtKey
Определяет код виртуальной клавиши, который будет оттранслирован.
uScanCode
Определяет аппаратный скэн-код клавиши, которая будет оттранслирована. Старший бит этого значения установлен, если клавиша вверху (не нажата).
lpKeyState
Указывает на 256-байтовый массив, который содержит текущее состояние клавиатуры. Каждый элемент (байт) в массиве содержит состояние в одной из клавиш. Если старший бит байта установлен, клавиша - внизу (нажата).
Если установлен младший бит, он указывает на то, что клавиша подключена. В этой функции важен только бит подключения клавиши CAPS LOCK. Состояние переключения клавиш NUM LOCK и SCROLL LOCK игнорируется.
lpChar
Указывает на буфер, который примет оттранслированный символ или символы Windows.
uFlags
Определяет, является ли меню активным. Этот параметр должен быть 1, если меню активно, или иначе 0.

Возвращаемые значения
Если заданная клавиша - мертвая клавиша, величина возвращаемого значения отрицательная. Иначе, она равна одному из следующих значений:

  • 0 - Заданная виртуальная клавиша не транслируется для текущего состояния клавиатуры.
  • 1 - Один символ Windows был скопирован в буфер.
  • 2 - Два символа были скопированы в буфер. Это обычно случается тогда, когда символ мертвой клавиши (знак ударения или диакритический знак), сохраненный в раскладке символов на клавиатуре, не может быть скомбинирован с заданной виртуальной клавишей, чтобы сформировать единый символ.

Замечания
Параметров, данных в функции ToAscii, может быть не достаточно, чтобы транслировать код виртуальной клавиши, потому что предыдущая мертвая клавиша сохраняется в раскладке символов на клавиатуре.
Как правило, ToAscii исполняет трансляцию, опираясь на код виртуальной клавиши. Однако в некоторых случаях, бит 15 параметра uScanCode может быть использован, чтобы различить между нажатием клавиши и её отпуском. Скэн-код используется для трансляции комбинации клавиш ALT + числовая клавиша.
Хотя NUM LOCK - клавиша - переключатель, которая воздействует на поведение клавиатуры, ToAscii игнорирует установку переключателя (младший бит) lpKeyState (VK_NUMLOCK), потому что одного параметра uVirtKey достаточно, чтобы отличить клавиши управления курсором (VK_HOME, VK_INSERT и так далее) от числовых клавиш (VK_DECIMAL, VK_NUMPAD0 - VK_NUMPAD9).

Смотри также
OemKeyScan, ToUnicode, VkKeyScan

Размещение и совместимость ToAscii

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


10.16.1.23 - Функция ToAsciiEx

(вASCIIРасширенная)

[Теперь поддерживается в Windows NT]

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

Синтаксис

int ToAsciiEx
(
    UINT uVirtKey,	// код виртуальной клавиши
    UINT uScanCode,	// скэн-код
    PBYTE lpKeyState,	// адрес массива состояния клавиши
    LPWORD lpChar,	// буфер для трансляции клавиши
    UINT uFlags,	// флажок активного меню
    HKL dwhkl	// дескриптор раскладки символов на клавиатуре
);

Параметры
uVirtKey
Определяет код виртуальной клавиши, который будет оттранслирован.
uScanCode
Определяет аппаратный скэн-код клавиши, которая будет оттранслирована. Старший бит этого значения установлен, если клавиша вверху (не нажата).

Указывает на 256-байтовый массив, который содержит текущее состояние клавиатуры. Каждый элемент (байт) в массиве содержит состояние в одной из клавиш. Если старший бит байта установлен, клавиша - внизу (нажата).
Если установлен младший бит, он указывает на то, что клавиша подключена. В этой функции важен только бит подключения клавиши CAPS LOCK. Состояние переключения клавиш NUM LOCK и SCROLL LOCK игнорируется.
lpChar
Указывает на буфер, который примет оттранслированный символ или символы Windows.
uFlags
Определяет, является ли меню активным. Этот параметр должен быть 1, если меню активно, или иначе 0.
dwhkl
Идентифицирует раскладку символов на клавиатуре, чтобы использовать для перевода данного кода. Этот параметр может быть любой дескриптор раскладки символов на клавиатуре, предварительно возвращенный функцией LoadKeyboardLayout.

Возвращаемые значения
Если заданная клавиша - мертвая клавиша, величина возвращаемого значения отрицательная. Иначе, она - одно из следующих значений:

  • 0 - Заданная виртуальная клавиша не транслируется для текущего состояния клавиатуры.
  • 1 - Один символ Windows был скопирован на буфер.
  • 2 - Два символа были скопированы в буфер. Это обычно случается, когда символ мертвой клавиши (знак ударения или диакритический знак), сохраненный в раскладке символов на клавиатуре, не может быть скомбинирован с заданной виртуальной клавишей, чтобы сформировать единый символ.

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

Как правило, ToAscii исполняет трансляцию, опираясь на код виртуальной клавиши. Однако в некоторых случаях, бит 15 параметра uScanCode может быть использован, чтобы различить между нажатием клавиши и её отпуском. Скэн-код используется для трансляции комбинации клавиш ALT + числовая клавиша.

Хотя NUM LOCK - клавиша - переключатель, которая воздействует на поведение клавиатуры, ToAscii игнорирует установку переключателя (младший бит) lpKeyState (VK_NUMLOCK), потому что одного параметра uVirtKey достаточно, чтобы отличить клавиши управления курсором (VK_HOME, VK_INSERT и так далее) от числовых клавиш (VK_DECIMAL, VK_NUMPAD0 - VK_NUMPAD9).

Смотри также
LoadKeyboardLayout, MapVirtualKeyEx, OemKeyScan, ToAscii, VkKeyScan

Размещение и совместимость ToAsciiEx

Windows NT				Да
Win95					Да
Win32s					Нет
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


10.16.1.24 - Функция ToUnicode

(вУникод)

Функция ToUnicode переводит заданный код виртуальной клавиши и состояние клавиатуры в соответствующий символ или символы Unicode.

Синтаксис

int ToUnicode(
    UINT wVirtKey,	// код виртуальной клавиши
    UINT wScanCode,	// скэн-код
    PBYTE lpKeyState,	// адрес массива состояния клавиши
    LPWSTR pwszBuff,	// буфер для трансляции клавиши
    int cchBuff,	// размер буфера для трансляции клавиши
    UINT wFlags	// установка флажков, согласования функций
);

Параметры
wVirtKey
Определяет код виртуальной клавиши, который будет оттранслирован.
wScanCode
Определяет аппаратный скэн-код клавиши, которая будет оттранслирована. Старший бит этого значения установлен, если клавиша вверху (не нажата).
lpKeyState
Указывает на 256-байтовый массив, который содержит текущее состояние клавиатуры. Каждый элемент (байт) в массиве содержит состояние одной из клавиш. Если старший бит байта установлен, клавиша - внизу (нажата).
pwszBuff
Указывает на буфер, который примет оттранслированный символ или символы Unicode.
cchBuff
Определяет размер буфера, указанного параметром pwszBuff, в символах.
wFlags
Набор битовых флажков, которые определяют поведение функции. Бит 0 установлен, если меню активно. Биты от 1 до 31 зарезервированы.

Возвращаемые значения
Функция возвращает одно из следующих значений:

  • - 1 - Заданная виртуальная клавиша - символ мертвой клавиши (знак ударения или диакритический знак). Это значение возвращается независимо от раскладки символов на клавиатуре, даже если несколько символов были введены с клавиатуры и сохранены в состоянии клавиатуры. Если возможно, наравне с раскладками символов Уникода на клавиатуре, функция запишет разделенную пробелами версию символа мертвой клавиши в буфер, заданный pwszBuffer. Например, функция запишет символ SPACING ACUTE (0x00B4), а не символ NON_SPACING ACUTE (0x0301).
  • 0 - Заданная виртуальная клавиша не транслируется для текущего состояния клавиатуры. Ничего не пишется в буфер, определенный при помощи pwszBuffer
  • 1 - Один символ был записан в буфер, заданный pwszBuffer.
  • 2 или больше - Два или больше символа были записаны в буфер, заданный pwszBuff. Наиболее общая причина для этого является то, что символ мертвой клавиши (знак ударения или диакритический знак) сохраненный в раскладке символов на клавиатуре не может быть объединен с заданной виртуальной клавишей, чтобы сформировать единый символ.

Замечания
Параметров, данных в функции ToUnicode, может быть не достаточно, чтобы перевести код виртуальной клавиши, потому что предыдущая мертвая клавиша сохраняется в раскладке символов на клавиатуре.
Как правило, ToUnicode исполняет трансляцию, опираясь на код виртуальной клавиши. Однако в некоторых случаях, бит 15 параметра wScanCode может быть использован, чтобы различить между нажатием клавиши и её отпуском.

Смотри также
ToAscii, VkKeyScan

Размещение и совместимость ToUnicode

Windows NT			Да
Win95				Нет
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


10.16.1.25 - Функция UnloadKeyboardLayout

(ВыгрузитьРаскладкуКлавиатуры)

Функция UnloadKeyboardLayout удаляет раскладку символов на клавиатуре.

Синтаксис

BOOL UnloadKeyboardLayout
(
    HKL hkl		// дескриптор раскладки символов на клавиатуре
);

Параметры
hkl
Идентифицирует раскладку символов на клавиатуре, которую надо выгрузить.

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

  1. Был послан недопустимый дескриптор раскладки символов на клавиатуре.
  2. Раскладка была предварительно загружена.
  3. Раскладка находится в использовании.

Замечания
Windows 95: UnloadKeyboardLayout не может выгрузить системную, по умолчанию раскладку символов на клавиатуре. Это гарантирует то, что соответствующий набор символов всегда доступен для пользователя, чтобы ввести с клавиатуры команды для оболочки или названий для файловой системы.
Windows NT: UnloadKeyboardLayout может выгрузить системную, по умолчанию раскладку символов на клавиатуре.

Смотри также
ActivateKeyboardLayout, GetKeyboardLayoutName, LoadKeyboardLayout

Размещение и совместимость UnloadKeyboardLayout

Windows NT				Да
Win95					Да
Win32s					Нет
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


10.16.1.26 - Функция UnregisterHotKey

(РегистрацияГорячейКлавиши)

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

Синтаксис

BOOL UnregisterHotKey
(
    HWND hWnd,	// окно, связанное с "горячей" клавишей
    int id	// идентификатор "горячей" клавиши
);

Параметры
hWnd
Идентифицирует окно, связанное с комбинацией "горячая" клавиша, которая будет освобождена. Этот параметр должен иметь значение ПУСТО (NULL), если комбинация "горячая" клавиша не связана с окном.
id
Определяет идентификатор комбинации "горячая" клавиша, которая будет освобождена.

Возвращаемые значения
Если функция завершилась успешно, возвращается значение отличное от нуля.
Если функция потерпела неудачу, возвращаемое значение - ноль. Чтобы получить расширенные данные об ошибках, обратитесь к функции GetLastError.

Смотри также
RegisterHotKey, WM_HOTKEY

Размещение и совместимость UnregisterHotKey

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


10.16.1.27 - Функция VkKeyScan

(СканироватьВиртуальнуюКлавишу)

Функция VkKeyScan переводит символ в соответствующий код виртуальной клавиши и состояние переключения для текущей клавиатуры.

Синтаксис

SHORT VkKeyScan
(
    TCHAR ch	// символ, который транслируется
);

Параметры
ch
Определяет символ, который будет оттранслирован в код виртуальной клавиши.

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

  • 1 бит - Нажата любая клавиша SHIFT.
  • 2 бит - Нажата любая клавиша CTRL.
  • 4 бит - Нажата любая клавиша ALT.

Если функция не находит клавишу, которая транслируется, чтобы послать код буквы, то младшие и старшие байты содержат – (минус)1.

Замечания
Для раскладок символов на клавиатуре, которые используют правостороннюю клавишу ALT как клавишу SHIFT (например, Французская раскладка символов на клавиатуре), состояние переключения представлено значением 6, потому что правосторонняя клавиша ALT внутренне преобразуется в CTRL+ALT.
Трансляция для цифрового клавишного поля (от VK_NUMPAD0 до VK_DIVIDE) игнорируется. Эта функция предназначена для того, чтобы переводить символы в нажатия клавиш только из главного раздела клавиатуры. Например, символ "7" транслируется в VK_7, не VK_NUMPAD7.
VkKeyScan используется прикладными программами, которые посылают символы, используя сообщения WM_KEYDOWN и WM_KEYUP.

Смотри также
GetAsyncKeyState, GetKeyboardState, GetKeyNameText, GetKeyState, SetKeyboardState, WM_KEYDOWN, WM_KEYUP

Размещение и совместимость VkKeyScan

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					WinNT
Замечания по платформе			Не имеется


10.16.1.28 - Функция VkKeyScanEx

(СканироватьВиртуальнуюКлавишуРасширенная)

[Теперь поддерживается в Windows NT]

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

Синтаксис

SHORT VkKeyScanEx
(
    CHAR ch,	// символ, который транслируется
    HKL dwhkl	// дескриптор раскладки символов на клавиатуре
);

Параметры
ch
Определяет символ, который будет оттранслирован в код виртуальной клавиши.
dwhkl
Идентифицирует раскладку символов на клавиатуре, которая используется, чтобы оттранслировать символ. Этот параметр может быть дескриптор любой раскладки символов на клавиатуре, предварительно возвращенный функцией LoadKeyboardLayout.

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

  • 1 бит - Нажата любая клавиша SHIFT.
  • 2 бит - Нажата любая клавиша CTRL.
  • 4 бит - Нажата любая клавиша ALT.

Если функция не находит клавишу, которая транслируется, чтобы послать код буквы, то младшие и старшие байты содержат – (минус)1.

Замечания
Для раскладок символов на клавиатуре, которые используют правостороннюю клавишу ALT как клавишу SHIFT (например, Французская раскладка символов на клавиатуре), переключение состояния представлено значением 6, потому что правосторонняя клавиша ALT внутренне преобразуется в CTRL+ALT.
Трансляции для цифровой клавиатуры (от VK_NUMPAD0 до VK_DIVIDE) игнорируются. Эта функция предназначена для того, чтобы переводить символы в нажатия клавиш только из главного раздела клавиатуры. Например, символ "7" транслируется в VK_7, не VK_NUMPAD7.
VkKeyScanEx используется прикладными программами, которые посылают символы, используя сообщения WM_KEYDOWN и WM_KEYUP.

Смотри также
GetAsyncKeyState, GetKeyboardState, GetKeyNameText, GetKeyState, LoadKeyboardLayout, SetKeyboardState, ToAsciiEx, VkKeyScan

Размещение и совместимость VkKeyScanEx

Windows NT				Да
Win95					Да
Win32s					Нет
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					WinNT
Замечания по платформе			Не имеется


10.16.1.29 - Функция GetKBCodePage

Устаревшая функция

Функция GetKBCodePage предусмотрена для совместимости с более ранними версиями Windows. В прикладном программном интерфейсе (API)Win32 она только вызывает функцию GetOEMCP. Новые прикладные программы должны использовать функцию GetOEMCP.

Синтаксис

UINT GetKBCodePage(VOID)

Параметры
У этой функции нет параметров.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - идентификатор OEM кодовой страницы, или оно - заданный по умолчанию идентификатор, если значение системного реестра не читаемо. Список OEM идентификаторов кодовой страницы, см. GetOEMCP.

Смотри также: GetACP, GetOEMCP

Размещение и совместимость GetKBCodePage:

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


10.16.2 - Сообщения при вводе информации с клавиатуры

Следующие сообщения используются, чтобы принимать и обрабатывать ввод информации с клавиатуры.
WM_ACTIVATE
WM_CHAR
WM_DEADCHAR
WM_GETHOTKEY
WM_HOTKEY
WM_KEYDOWN
WM_KEYUP
WM_KILLFOCUS
WM_SETFOCUS
WM_SETHOTKEY
WM_SYSCHAR
WM_SYSDEADCHAR
WM_SYSKEYDOWN
WM_SYSKEYUP


10.16.2.1 - Сообщение WM_ACTIVATE

Сообщение WM_ACTIVATE отправляется, когда активизируется или деактивизируется окно. Это сообщение посылается сначала оконной процедуре деактивизируемого окна верхнего уровня; затем оно посылается оконной процедуре активизируемого окна верхнего уровня.

Синтаксис

WM_ACTIVATE
fActive = LOWORD(wParam);		// флажок активизации
fMinimized = (BOOL) HIWORD(wParam);	// флажок минимизации
hwndPrevious = (HWND) lParam;		// дескриптор окна

Параметры
fActive
Значение младшего слова wParam. Определяет, активизируется ли окно или деактивизируется. Этот параметр может быть одним из следующих значений:

  • WA_ACTIVE - Активизация некоторым другим методом, чем щелчок клавишей мыши (например, вызовом к функции SetActiveWindow или при помощи использования интерфейса клавиатуры, чтобы выбрать окно).
  • WA_CLICKACTIVE - Активизация при помощи щелчка мыши.
  • WA_INACTIVE - Деактивизация.

fMinimized
Значение старшего слова wParam. Определяет свернутое состояние окна, активизируемого или деактивизируемого. Значение отличное от нуля указывает, что окно свернуто (минимизировано).

hwndPrevious
Значение lParam. Идентифицирует окно, которое активизированное или деактивизированное, что зависит от значения параметра fActive. Если значение fActive - WA_INACTIVE, hwndPrevious - дескриптор активизированного окна. Если значение fActive - WA_ACTIVE или WA_CLICKACTIVE, hwndPrevious - дескриптор дезактивируемого окна. Этот дескриптор может быть ПУСТО (NULL).

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

Замечания
Если окно активизировано щелчком клавиши мыши, оно принимает также сообщение WM_MOUSEACTIVATE.

Смотри также: DefWindowProc, SetActiveWindow, WM_MOUSEACTIVATE, WM_NCACTIVATE

Размещение и совместимость WM_ACTIVATE

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


10.16.2.2 - Сообщение WM_CHAR

Сообщение WM_CHAR посылается окну с фокусом клавиатуры тогда, когда функцией TranslateMessage транслируется сообщение WM_KEYDOWN. WM_CHAR содержит код буквы клавиши, которая была нажата.

Синтаксис

WM_CHAR
chCharCode = (TCHAR) wParam;	// код буквы
lKeyData = lParam;		// данные на клавишу

Параметры
chCharCode
Значение wParam. Определяет код буквы клавиши.
lKeyData
Значение lParam. Определяет счет повторений, скэн-код, флажок дополнительной клавиши, контекстный код, флажок предыдущего состояния клавиши и флажок переходного состояния, как показано в следующем списке:

  • 0-15 - Определяет счет повторений. Значение равно числу повторений нажатия клавиши в результате того, что пользователь удерживает клавишу нажатой.
  • 16-23 - Определяет скэн-код. Значение зависит от фирмы - изготовителя комплектного оборудования (OEM).
  • 24 - Определяет, является ли клавиша дополнительной клавишей, типа правосторонних клавиш ALT и CTRL, которые появляются на усовершенствованной 101- или 102-клавишной клавиатуре. Значение равно 1, если это дополнительная клавиша; иначе, оно равно 0.
  • 25-28 - Зарезервировано; не используется.
  • 29 - Определяет контекстный код. Значение рано 1, если клавиша ALT удерживается, в то время как клавиша нажата; иначе, значение равно 0.
  • 30 - Определяет предыдущее состояние клавиши. Значение равно 1, если клавиша была нажата перед посылкой сообщения или оно равно 0, если клавиша была не нажата.
  • 31 - Определяет переходное состояние. Значение равно 1, если клавиша отпускается или оно равно 0, если клавиша нажимается.

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

Замечания
Поскольку не имеется обязательного соответствия один к одному между нажатыми клавишами и сгенерированными символьными сообщениями, информация в старшем слове параметра lKeyData вообще-то бесполезна для прикладных программ. Информация в старшем слове применяется только к самому последнему сообщению WM_KEYDOWN, которое предшествует регистрации сообщения WM_CHAR.
Для усовершенствованных 101- и 102-клавишных клавиатур, дополнительными клавишами являются правая ALT и правая CTRLINS, DEL, HOME, END, PAGE UP, PAGE DOWN и клавиши курсора в группах слева от цифровой клавиатуры; делитель (/) и клавиши ENTER в цифровой клавиатуре. Некоторые другие клавиатуры могут поддерживать бит дополнительной клавиши в параметре lKeyData.

Смотри также
TranslateMessage, WM_KEYDOWN

Размещение и совместимость WM_CHAR

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


10.16.2.3 - Сообщение WM_DEADCHAR

Синтаксис

WM_DEADCHAR
chCharCode = (TCHAR) wParam;    		// код буквы
lKeyData = lParam;              		// данные для клавиши

Сообщение WM_DEADCHAR посылается окну с фокусом клавиатуры тогда, когда функцией TranslateMessage транслируется сообщение WM_KEYUP. WM_DEADCHAR определяет код буквы, сгенерированный мертвой клавишей. Мертвая клавиша - клавиша, которая генерирует символ, типа умлаута (две точки над буквой), который объединяется с другим символом, чтобы формировать составной символ. Например, символ O - умлаут (O) сгенерирован при помощи ввода с клавиатуры мертвой клавиши для символа умлаута, а затем ввода клавиши O.

Параметры
chCharCode
Значение wParam>. Определяет код символа, сгенерированный мертвой клавишей.
lKeyData
Значение lParam. Определяет счет повторений, скэн-код, флажок дополнительной клавиши, контекстный код, флажок предыдущего состояния клавиши и флажок переходного состояния, как показано в следующем списке:

  • 0-15 - Определяет счет повторений. Значение равно числу повторений нажатия клавиши в результате того, что пользователь удерживает клавишу нажатой.
  • 16-23 - Определяет скэн-код. Значение зависит от фирмы - изготовителя комплектного оборудования (OEM).
  • 24 - Определяет, является ли клавиша дополнительной клавишей, типа правосторонних клавиш ALT и CTRL, которые появляются на усовершенствованной 101- или 102-клавишной клавиатуре. Значение равно 1, если это дополнительная клавиша; иначе, оно равно 0.
  • 25-28 - Зарезервировано; не используется.
  • 29 - Определяет контекстный код. Значение равно 1, если клавиша ALT удерживается, в то время как клавиша нажата; иначе, значение равно 0.
  • 30 - Определяет предыдущее состояние клавиши. Значение равно 1, если клавиша была нажата перед посылкой сообщения или оно равно 0, если клавиша была не нажата.
  • 31 - Определяет переходное состояние. Значение равно 1, если клавиша отпускается или оно равно 0, если клавиша нажимается.

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

Замечания
Сообщение WM_DEADCHAR обычно используется прикладными программами, чтобы дать пользователю обратную связь о каждой нажатой клавише. Например, прикладная программа может отображать знак ударения в текущей позиции символа без перемещения каретки.
Поскольку не имеется обязательного соответствия один к одному между нажатыми клавишами и сгенерированными символьными сообщениями, информация в старшем слове параметра lKeyData вообще-то бесполезна для прикладных программ. Информация в старшем слове применяется только к самому последнему сообщению WM_KEYDOWN, которое предшествует посылке сообщения WM_DEADCHAR.
Для усовершенствованных 101- и 102-клавишных клавиатур, дополнительными клавишами являются - правая ALT и правая CTRL в основной части клавиатуры; INS, DEL, HOME, END, PAGE UP, PAGE DOWN и клавиши курсора в группах слева от цифровой клавиатуры; делитель (/) и клавиши ENTER в цифровой клавиатуре. Некоторые другие клавиатуры могут поддерживать бит дополнительной клавиши в параметре lKeyData.

Смотри также
TranslateMessage, WM_KEYDOWN, WM_KEYUP, WM_SYSDEADCHAR

Размещение и совместимость WM_DEADCHAR

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			-
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


10.16.2.4 - Сообщение WM_GETHOTKEY

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

Синтаксис

WM_GETHOTKEY
wParam = 0; 	// не используется; должно быть нуль
lParam = 0; 	// не используется; должно быть нуль

Параметры
У этого сообщения нет параметров.

Возвращаемые значения
Величина возвращаемого значения - код виртуальной клавиши и модификаторы для комбинации "горячая" клавиша, или ПУСТО (NULL), если никакая комбинация "горячая" клавиша не связана с окном. Код виртуальной клавиши находится в младшем байте величины возвращаемого значения, а модификаторы находятся в старшем байте. Модификаторы могут быть комбинацией следующих флажков:

  • HOTKEYF_ALT - Клавиша ALT
  • HOTKEYF_CONTROL - Клавиша CTRL
  • HOTKEYF_EXT - Расширенная клавиша
  • HOTKEYF_SHIFT - Клавиша SHIFT

Замечания
Эти комбинации "горячая" клавиша не связаны с комбинациями "горячая" клавиша, которые устанавливаются при помощи функции RegisterHotKey.

Смотри также: RegisterHotKey, WM_SETHOTKEY

Размещение и совместимость WM_GETHOTKEY

Windows NT				Да
Win95					Да
Win32s					Нет
Импортируемая библиотека			-
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


10.16.2.5 - Сообщение WM_HOTKEY

Сообщение WM_HOTKEY посылается тогда, когда пользователь нажимает комбинацию "горячая" клавиша, зарегистрированную функцией RegisterHotKey(). Сообщение помещается наверху очереди сообщений, связанной с потоком, который зарегистрировал комбинацию "горячая" клавиша.

Синтаксис

WM_HOTKEY
idHotKey = (int) wParam;		// идентификатор комбинации "горячая" клавиша
fuModifiers = (UINT) LOWORD(lParam);	// флажки модификаторы клавиш
uVirtKey = (UINT) HIWORD(lParam);	// код виртуальной клавиши

Параметры
idHotKey
Значение wParam. Определяет идентификатор комбинации "горячая" клавиша, которая генерировала сообщение. Если сообщение было создано комбинацией "горячая" клавиша, которая определена системой, параметр idHotKey будет одним из следующих значений:

  • IDHOT_SNAPDESKTOP - Была нажата комбинация "горячая клавиша" делающая "моментальный снимок рабочего стола".
  • IDHOT_SNAPWINDOW - Была нажата комбинация "горячая клавиша" делающая "моментальный снимок окна".

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

  • MOD_ALT - Любая клавиша ALT удерживалась нажатой.
  • MOD_CONTROL - Любая клавиша CTRL удерживалась нажатой.
  • MOD_SHIFT - Любая клавиша SHIFT удерживалась нажатой.
  • MOD_WIN - Любая клавиша WINDOWS удерживалась нажатой. Эти клавиши появляются только на клавиатуре Microsoft Ergonomic и помечены эмблемой Microsoft Windows.

uVirtKey
Определяет код виртуальной клавиши комбинации "горячая" клавиша.

Замечания
Сообщение WM_HOTKEY не связано с сообщениями WM_GETHOTKEY и WM_SETHOTKEY комбинаций "горячая" клавиша. Сообщение WM_HOTKEY отправляется для общих комбинаций "горячая" клавиша, в то время как сообщения WM_SET\GETHOTKEY касаются комбинаций "горячая" клавиша активизации окна.

Смотри также: RegisterHotKey, WM_GETHOTKEY, WM_SETHOTKEY

Размещение и совместимость WM_HOTKEY:

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


10.16.2.6 - Сообщение WM_KEYDOWN

Сообщение WM_KEYDOWN посылается окну с фокусом клавиатуры тогда, когда нажата несистемная клавиша. Несистемная клавиша является клавишей, которая нажимается, когда клавиша ALT не нажата.

Синтаксис

WM_KEYDOWN
nVirtKey = (int) wParam;	// код виртуальной клавиши
lKeyData = lParam;		// данные на клавишу

Параметры
nVirtKey
Значение wParam. Определяет код виртуальной клавиши для несистемной клавиши.
lKeyData
Значение lParam. Определяет счет повторений, скэн-код, флажок дополнительной клавиши, контекстный код, флажок предыдущего состояния клавиши и флажок переходного состояния, как показано в следующем списке:

  • 0-15 - Определяет счет повторений. Значение равно числу повторений нажатия клавиши в результате того, что пользователь удерживает клавишу нажатой.
  • 16-23 - Определяет скэн-код. Значение зависит от фирмы - изготовителя комплектного оборудования (OEM).
  • 24 - Определяет, является ли клавиша дополнительной клавишей, типа правосторонних клавиш ALT и CTRL, которые появляются на усовершенствованной 101- или 102-клавишной клавиатуре. Значение равно 1, если это дополнительная клавиша; иначе, оно равно 0.
  • 25-28 - Зарезервировано; не используется.
  • 29 - Определяет контекстный код. Для сообщения WM_KEYDOWN это значение всегда 0.
  • 30 - Определяет предыдущее состояние клавиши. Значение равно 1, если клавиша была нажата перед посылкой сообщения или оно равно 0, если клавиша была не нажата.
  • 31 - Определяет переходное состояние. Для сообщения WM_KEYDOWN это значение всегда 0.

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

Действие по умолчанию
Если нажата клавиша F10, функция DefWindowProc устанавливает внутренний флажок. Когда DefWindowProc принимает сообщение WM_KEYUP, функция проверяет, установлен ли внутренний флажок и, если это так, посылает сообщение WM_SYSCOMMAND окну верхнего уровня. Параметр wParam сообщения устанавливается в SC_KEYMENU.

Замечания
Благодаря функции автоповтора, до посылки сообщения WM_KEYUP может быть послано больше чем одно сообщение WM_KEYDOWN. Предыдущее состояние клавиши (бит 30) может быть использовано, чтобы установить, указывает ли сообщение WM_KEYDOWN первое нажатие или повторное нажатие.
Для усовершенствованных 101- и 102-клавишных клавиатур, дополнительными клавишами являются правая ALT и правая CTRL в основной части клавиатуры; INS, DEL, HOME, END, PAGE UP, PAGE DOWN и клавиши курсора в группах слева от цифровой клавиатуры; и делитель (/) и клавиши ENTER в цифровой клавиатуре. Некоторые другие клавиатуры могут поддерживать бит дополнительной клавиши в параметре lKeyData.

Смотри также
DefWindowProc, WM_CHAR, WM_KEYUP, WM_SYSCOMMAND

Размещение и совместимость WM_KEYDOWN

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


10.16.2.7 - Сообщение WM_KEYUP

Сообщение WM_KEYUP посылается окну с фокусом клавиатуры тогда, когда отпущена несистемная клавиша. Несистемная клавиша - это клавиша, которая нажата, когда клавиша ALT не нажата или клавиша клавиатуры, которая нажимается тогда, когда окно имеет фокус клавиатуры.

Синтаксис

WM_KEYUP
nVirtKey = (int) wParam;	// код виртуальной клавиши
lKeyData = lParam;		// данные на клавишу

Параметры
nVirtKey
Значение wParam. Определяет код виртуальной клавиши для несистемной клавиши.
lKeyData
Значение lParam. Определяет счет повторений, скэн-код, флажок дополнительной клавиши, контекстный код, флажок предыдущего состояния клавиши и флажок переходного состояния, как показано в следующем списке:

  • 0-15 - Определяет счет повторений. Значение равно числу повторений нажатия клавиши в результате того, что пользователь удерживает клавишу нажатой. Для сообщения WM_KEYUP счет повторений равен всегда одному.
  • 16-23 - Определяет скэн-код. Значение зависит от фирмы - изготовителя комплектного оборудования (OEM).
  • 24 - Определяет, является ли клавиша расширенной клавишей, типа правосторонних клавиш ALT и CTRL, которые появляются на усовершенствованной 101- или 102-клавишной клавиатуре. Значение равно 1, если это дополнительная клавиша; иначе, оно равно 0.
  • 25-28 - Зарезервировано; не используется.
  • 29 - Определяет контекстный код. Для сообщения WM_KEYUP это значение всегда 0.
  • 30 - Определяет предыдущее состояние клавиши. Для сообщения WM_KEYUP это значение всегда 1.
  • 31 - Определяет переходное состояние. Для сообщения WM_KEYUP это значение всегда 1.

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

Действие по умолчанию
Если клавиша F10 или ALT была отпущена, функция DefWindowProc посылает сообщение WM_SYSCOMMAND окну верхнего уровня. Параметр wParam сообщения устанавливается в SC_KEYMENU.

Замечания
Для усовершенствованных 101- и 102-клавишных клавиатур, дополнительными клавишами являются - правая ALT и правая CTRL в основной части клавиатуры; INS, DEL, HOME, END, PAGE UP, PAGE DOWN и клавиши курсора в группах слева от цифровой клавиатуры; делитель (/) и клавиши ENTER в цифровой клавиатуре. Другие клавиатуры могут поддерживать бит дополнительной клавиши в параметре lKeyData.

Смотри также: DefWindowProc, WM_KEYDOWN, WM_SYSCOMMAND

Размещение и совместимость WM_KEYUP

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


10.16.2.8 - Сообщение WM_KILLFOCUS

Сообщение WM_KILLFOCUS отправляется окну немедленно перед тем, как оно теряет фокус клавиатуры.

Синтаксис

WM_KILLFOCUS
hwndGetFocus = (HWND) wParam; // дескриптор окна, принимающего фокус

Параметры
hwndGetFocus
Значение wParam. Идентифицирует окно, которое принимает фокус клавиатуры (может быть значением ПУСТО (NULL)).

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

Замечания
Если прикладная программа отображает каретку, в этот момент каретка должна быть разрушена.

Смотри также: SetFocus, WM_SETFOCUS

Размещение и совместимость WM_KILLFOCUS

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


10.16.2.9 - Сообщение WM_SETFOCUS

Сообщение WM_SETFOCUS посылается окну после того, как оно получило фокус клавиатуры.

Синтаксис

WM_SETFOCUS
hwndLoseFocus = (HWND) wParam;	// дескриптор окна, теряющего фокус

Параметры
hwndLoseFocus
Значение wParam. Идентифицирует окно, которое потеряло фокус клавиатуры (может быть значением ПУСТО (NULL)).

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

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

Смотри также: SetFocus, WM_KILLFOCUS

Размещение и совместимость WM_SETFOCUS

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


10.16.2.10 - Сообщение WM_SETHOTKEY

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

Синтаксис

WM_SETHOTKEY
wParam = (WPARAM) MAKEWORD (vkey, modifiers)
    // код виртуальной клавиши и
    // модификаторы горячих клавиш
lParam = 0;	// не используется, должно быть нуль

Параметры
vkey
Значение wParam. Определяет код виртуальной клавиши и модификаторы комбинаций "горячая" клавиша, которые связаны с окном. Код виртуальной клавиши находится в младшем байте параметра, а флажки модификатора находятся в старшем байте. Установка этого параметра в значение ПУСТО (NULL) удаляет комбинацию "горячая" клавиша, связанную с окном. Байт модификатора может быть комбинацией следующих флажков:

  • HOTKEYF_ALT - Клавиша ALT
  • HOTKEYF_CONTROL - Клавиша CTRL
  • HOTKEYF_EXT - Расширенная клавиша
  • HOTKEYF_SHIFT - Клавиша SHIFT

Возвращаемые значения
Величина возвращаемого значения является одной из ниже перечисленных:

  • -1 - Функция потерпела неудачу - комбинация "горячая" клавиша является недопустимой.
  • 0 - Функция потерпела неудачу - окно является недопустимым.
  • 1 - Функция завершила свою работу успешно, и ни у какого другого окна нет той же самой комбинации "горячая" клавиша.
  • 2 - Функция завершила свою работу успешно, но другое окно уже имеет ту же самую комбинацию "горячая" клавиша.

Замечания
Комбинация "горячая" клавиша не может быть связана с дочерним окном.
VK_ESCAPE, VK_SPACE и VK_TAB - недопустимые комбинации "горячая" клавиша.
Когда пользователь нажимает комбинацию "горячая" клавиша, система генерирует сообщение WM_SYSCOMMAND с wParam равным SC_HOTKEY.
Окно может иметь только одну комбинацию "горячая" клавиша. Если окно уже связано с комбинацией "горячая" клавиша, новая "горячая" клавиша заменяет старую. Если больше чем одно окно связаны с той же самой комбинацией "горячая" клавиша, окно, которое активизировано этой комбинацией, является выбранным наудачу.
Эти комбинации "горячая" клавиша несвязанны с "горячими" клавишами установленными при помощи RegisterHotKey.

Смотри также
RegisterHotKey, WM_GETHOTKEY, WM_SYSCOMMAND

Размещение и совместимость WM_SETHOTKEY

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


10.16.2.11 - Сообщение WM_SYSCHAR

Сообщение WM_SYSCHAR посылается окну с фокусом клавиатуры тогда, когда сообщение WM_SYSKEYDOWN оттранслировано функцией TranslateMessage. Оно определяет код буквы системной клавиши - то есть клавиши знака, которая была нажата одновременно с клавишей ALT.

Синтаксис

WM_SYSCHAR
chCharCode = (TCHAR) wParam;	// код буквы
lKeyData = lParam;		// данные на клавишу

Параметры
chCharCode
Значение wParam. Определяет код буквы клавиши меню окна.
lKeyData
Значение lParam. Определяет счет повторений, скэн-код, флажок дополнительной клавиши, контекстный код, флажок предыдущего состояния клавиши и флажок переходного состояния, как показано в следующем списке:

  • 0-15 - Определяет счет повторений. Значение равно числу повторений нажатия клавиши в результате того, что пользователь удерживает клавишу нажатой.
  • 16-23 - Определяет скэн-код. Значение зависит от фирмы - изготовителя комплектного оборудования (OEM).
  • 24 - Определяет, является ли клавиша дополнительной клавишей, типа правосторонних клавиш ALT и CTRL, которые появляются на усовершенствованной 101- или 102-клавишной клавиатуре. Значение равно 1, если это дополнительная клавиша; иначе, оно равно 0.
  • 25-28 - Зарезервировано; не используется.
  • 29 - Определяет контекстный код. Значение равно 1, если клавиша ALT удерживается, в то время как клавиша нажата; иначе, значение равно 0.
  • 30 - Определяет предыдущее состояние клавиши. Значение равно 1, если клавиша была нажата перед посылкой сообщения или оно равно 0, если клавиша была не нажата.
  • 31 - Определяет переходное состояние. Значение равно 1, если клавиша отпускается или оно равно 0, если клавиша нажимается.

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

Замечания
Когда контекстный код нулевой, сообщение может быть послано в функцию TranslateAccelerator, которая обработает его, как если бы это было стандартное клавишное сообщение вместо системного сообщения символьной клавиши. Это позволяет клавишам - ускорителям быть использованным с активным окном, даже если активное окно не имеет фокуса клавиатуры.
Для усовершенствованных 101- и 102-клавишных клавиатур, дополнительными клавишами являются - правая ALT и правая CTRL в основной части клавиатуры; INS, DEL, HOME, END, PAGE UP, PAGE DOWN и клавиши курсора в группах слева от цифровой клавиатуры; клавиша PRINT SCRN; клавиша BREAK; клавиша NUMLOCK; и делитель (/), и клавиши ENTER в цифровой клавиатуре. Некоторые другие клавиатуры могут поддерживать бит дополнительной клавиши в параметре lKeyData.

Смотри также
TranslateAccelerator, TranslateMessage, WM_SYSKEYDOWN

Размещение и совместимость WM_SYSCHAR

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


10.16.2.12 - Сообщение WM_SYSDEADCHAR

Сообщение WM_SYSDEADCHAR отправляется окну с фокусом клавиатуры, когда сообщение WM_SYSKEYDOWN оттранслировано функцией TranslateMessage. WM_SYSDEADCHAR определяет код буквы системной мертвой клавиши, то есть мертвая клавиша, которая нажата при удержании нажатой клавиши ALT.

Синтаксис

WM_SYSDEADCHAR
chCharCode = (TCHAR) wParam;	// код буквы
lKeyData = lParam;		// данные для клавиши

Параметры
chCharCode
Значение wParam. Определяет код буквы, сгенерированный системной мертвой клавишей, то есть мертвой клавишей, которая нажата при удержании нажатой клавиши ALT.
lKeyData
Значение lParam. Определяет счет повторений, скэн-код, флажок дополнительной клавиши, контекстный код, флажок предыдущего состояния клавиши и флажок переходного состояния, как показано в следующем списке:

  • 0-15 - Определяет счет повторений. Значение равно числу повторений нажатия клавиши в результате того, что пользователь удерживает клавишу нажатой.
  • 16-23 - Определяет скэн-код. Значение зависит от фирмы - изготовителя комплектного оборудования (OEM).
  • 24 - Определяет, является ли клавиша дополнительной клавишей, типа правосторонних клавиш ALT и CTRL, которые появляются на усовершенствованной 101- или 102-клавишной клавиатуре. Значение равно 1, если это дополнительная клавиша; иначе, оно равно 0.
  • 25-28 - Зарезервировано; не используется.
  • 29 - Определяет контекстный код. Значение равно 1, если клавиша ALT удерживается, в то время как клавиша нажата; иначе, значение равно 0.
  • 30 - Определяет предыдущее состояние клавиши. Значение равно 1, если клавиша была нажата перед посылкой сообщения или оно равно 0, если клавиша была не нажата.
  • 31 - Определяет переходное состояние. Значение равно 1, если клавиша отпускается или оно равно 0, если клавиша нажимается.

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

Замечания
Для усовершенствованных 101- и 102-клавишных клавиатур, дополнительными клавишами являются - правая ALT и правая CTRL в основной части клавиатуры; INS, DEL, HOME, END, PAGE UP, PAGE DOWN и клавиши курсора в группах слева от цифровой клавиатуры; и делитель (/) и клавиши ENTER в цифровой клавиатуре. Некоторые другие клавиатуры могут поддерживать бит дополнительной клавиши в параметре lKeyData.

Смотри также: TranslateMessage, WM_DEADCHAR, WM_SYSKEYDOWN

Размещение и совместимость WM_SYSDEADCHAR

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


10.16.2.13 - Сообщение WM_SYSKEYDOWN

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

Синтаксис

WM_SYSKEYDOWN
nVirtKey = (int) wParam;	// код виртуальной клавиши
lKeyData = lParam;	// данные на клавишу

Параметры
nVirtKey
Значение wParam. Определяет виртуальной код нажимаемой клавиши.
lKeyData
Значение lParam. Определяет счет повторений, скэн-код, флажок дополнительной клавиши, контекстный код, флажок предыдущего состояния клавиши и флажок переходного состояния, как показано в следующем списке:

  • 0-15 - Определяет счет повторений. Значение равно числу повторений нажатия клавиши в результате того, что пользователь удерживает клавишу нажатой.
  • 16-23 - Определяет скэн-код. Значение зависит от фирмы - изготовителя комплектного оборудования (OEM).
  • 24 - Определяет, является ли клавиша дополнительной клавишей, типа правосторонних клавиш ALT и CTRL, которые появляются на усовершенствованной 101- или 102-клавишной клавиатуре. Значение равно 1, если это дополнительная клавиша; иначе, оно равно 0.
  • 25-28 - Зарезервировано; не используется.
  • 29 - Определяет контекстный код. Значение является 1, если клавиша ALT является нажатой, в то время, когда нажимается символьная клавиша; оно является 0, если сообщение WM_SYSKEYDOWN посылается активному окну, потому что никакое окно не имеет фокуса клавиатуры.
  • 30 - Определяет предыдущее состояние клавиши. Значение является 1, если клавиша нажимается перед оправкой сообщения, или оно равно 0, если клавиша не нажимается.
  • 31 - Определяет переходное состояние. Для сообщения WM_SYSKEYDOWN это значение всегда 0.

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

Действие по умолчанию
Функция DefWindowProc проверяет данную клавишу и генерирует сообщение WM_SYSCOMMAND, если клавиша является или TAB или ENTER.

Замечания
Когда контекстный код нулевой, сообщение может быть послано в функцию TranslateAccelerator, которая обработает его, как если бы это было нормальное клавишное сообщение вместо системного сообщения символьной клавиши. Это позволяет клавишам - ускорителям быть использованными с активным окном, даже если активное окно не имеет фокуса клавиатуры.
Из-за функции автоповтора, до посылки сообщения WM_SYSKEYUP может быть послано больше чем одно сообщение WM_SYSKEYDOWN. Предыдущее состояние клавиши (бит 30) может быть использован, чтобы установить, указывает ли сообщение WM_SYSKEYDOWN первое нажатие или повторное нажатие.
Для усовершенствованных 101- и 102-клавишных клавиатур, дополнительными клавишами являются - правая ALT и правая CTRL в основной части клавиатуры; INS, DEL, HOME, END, PAGE UP, PAGE DOWN и клавиши курсора в группах слева от цифровой клавиатуры; и делитель (/) и клавиши ENTER в цифровой клавиатуре. Некоторые другие клавиатуры могут поддерживать бит дополнительной клавиши в параметре lKeyData.

Смотри также: DefWindowProc, TranslateAccelerator, WM_SYSCOMMAND, WM_SYSKEYUP

Размещение и совместимость WM_SYSKEYDOWN

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


10.16.2.14 - Сообщение WM_SYSKEYUP

Сообщение WM_SYSKEYUP посылается окну с фокусом клавиатуры тогда, когда пользователь отпускает клавишу, которая была нажата, в то время когда удерживалась нажатой клавиша ALT. Это происходит также тогда, когда никакое окно в настоящее время не имеет фокуса клавиатуры; в этом случае, сообщение WM_SYSKEYUP отправляется активному окну. Окно, которое принимает сообщение, может делать различие между этими двумя ситуациями, проверяя контекстный код в параметре lKeyData.

Синтаксис

WM_SYSKEYUP
nVirtKey = (int) wParam;	// код виртуальной клавиши
lKeyData = lParam;		// данные на клавишу

Параметры
nVirtKey
Значение wParam. Определяет код виртуальной клавиши, которая была отпущена.
lKeyData
Значение lParam. Определяет счет повторений, скэн-код, флажок дополнительной клавиши, контекстный код, флажок предыдущего состояния клавиши и флажок переходного состояния, как показано в следующем списке:

  • 0-15 - Определяет счет повторений. Значение равно числу повторений нажатия клавиши в результате того, что пользователь удерживает клавишу нажатой. Для сообщения WM_SYSKEYUP счет повторений всегда равен единице.
  • 16-23 - Определяет скэн-код. Значение зависит от фирмы - изготовителя комплектного оборудования (OEM).
  • 24 - Определяет, является ли клавиша дополнительной клавишей, типа правосторонних клавиш ALT и CTRL, которые применяются на усовершенствованных 101- или 102-клавишных клавиатурах. Значение равно 1, если это дополнительная клавиша; иначе, оно равно 0.
  • 25-28 - Зарезервировано; не используется.
  • 29 - Определяет контекстный код. Значение равно 1, если клавиша ALT нажимается, в то время как символьная клавиша отпускается; оно равно 0, если сообщение WM_SYSKEYDOWN посылается активному окну, потому что никакое окно не имеет фокуса клавиатуры.
  • 30 - Определяет предыдущее состояние клавиши. Для сообщения WM_SYSKEYUP это значение всегда 1.
  • 31 - Определяет переходное состояние. Для сообщения WM_SYSKEYUP это значение всегда 1.

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

Действие по умолчанию
Если клавиша F10 или ALT была отпущена, функция DefWindowProc отправляет сообщение WM_SYSCOMMAND окну верхнего уровня. Параметр wParam сообщения устанавливается в SC_KEYMENU.

Замечания
Когда контекстный код нулевой, сообщение может быть послано в функцию TranslateAccelerator, которая обработает его, как если бы оно было нормальное клавишное сообщение вместо системного сообщения символьной клавиши. Это позволяет клавишам - ускорителям быть использованными с активным окном, даже если активное окно не имеет фокуса клавиатуры.
Для усовершенствованных 101- и 102-клавишных клавиатур, дополнительными клавишами являются - правая ALT и правая CTRL в основной части клавиатуры; INS, DEL, HOME, END, PAGE UP, PAGE DOWN и клавиши курсора в группах слева от цифровой клавиатуры; делитель (/) и клавиши ENTER в цифровой клавиатуре. Другие клавиатуры могут поддерживать бит дополнительной клавиши в параметре lKeyData.
Для не американских усовершенствованных 102-клавишных клавиатур, правая клавиша ALT обрабатывается как клавиша CTRL + ALT. Следующая таблица показывает последовательность сообщений, которые появляются в результате того, когда пользователь нажимает и отпускает эту клавишу:

Сообщение	Код виртуальной клавиши
WM_KEYDOWN	VK_CONTROL
WM_KEYDOWN	VK_MENU
WM_KEYUP	VK_CONTROL
WM_SYSKEYUP	VK_MENU

Смотри также: DefWindowProc, TranslateAccelerator, WM_SYSCOMMAND, WM_SYSKEYDOWN

Размещение и совместимость WM_SYSKEYUP

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется
Предыдущий Шаг


Глава 5 - Курсоры

Курсор (cursor) - маленькое изображение, расположением которого на экране управляет устройство указания позиции, типа мыши, пера, или шарового манипулятора (trackball). В остальной части от этого краткого обзора, термин мышь (mouse) относится к любому устройству управления позицией курсора.

Когда пользователь перемещает мышь, Microsoft ® Windows ® соответственно перемещает курсор. Функции курсора Microsoft Win32 ® дают возможность прикладным программам создавать, загружать, отображать, перемещать, ограничивать и уничтожать курсоры.

Следующий Шаг


5.1 - Об курсорах

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

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

Прикладная программа может использовать функцию GetIconInfo, чтобы изъять информацию о текущем изображении курсора и может рисовать курсор на экране, используя функцию DrawIconEx. Чтобы нарисовать заданное по умолчанию изображение стандартного курсора при обращении к функции DrawIconEx определите флажок DI_COMPAT. Если вы не определите флажок DI_COMPAT, DrawIconEx рисует стандартный курсор, использующий изображение, которое определил пользователь.

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

2_1.gif (764 b)

Курсоры могут быть или одноцветными или цветными, и или статическими или "живыми". Тип курсора, используемого в отдельной компьютерной системе, зависит от системного дисплея. Старые дисплеи типа VGA не поддерживают цветные или "живые" указатели, однако новые дисплеи (чьи драйверы изображения используют механизм DIB (ФОРМАТ РАСТРОВОГО ИЗОБРАЖЕНИЯ)) поддерживают их.

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


5.2 - Острие (Hot Spot)

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

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


5.3 - Мышь и курсор

Windows отражает движение мыши, перемещая соответственно курсор на экране. Когда курсор перемешается над различными частями окон или в различных окнах, Windows (или прикладная программа) изменяет вид курсора. Например, когда курсор пересекает границу окна, Windows изменяет курсор в двунаправленную стрелку.

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


5.4 - Создание курсора

Поскольку стандартные курсоры предопределены, нет необходимости в их создании. Чтобы использовать стандартный курсор, прикладная программа извлекает информацию о дескрипторе курсора, используя функцию LoadCursor или LoadImage. Дескриптор курсора (cursor handle) - уникальное значение типа HCURSOR, которое идентифицирует стандартный или пользовательский курсор.

Чтобы создать пользовательский курсор для прикладной программы, Вы должны как обычно использовать программу работы с графикой и включить курсор как ресурс в файле определения ресурса приложения. В период выполнения программы, вызовите функцию LoadCursor, чтобы извлечь информацию о дескрипторе курсора. Ресурсы курсора содержат данные для нескольких различных устройств отображения. Функция LoadCursor автоматически выбирает наиболее соответствующие данные для текущего устройства отображения. Чтобы загрузить курсор непосредственно из .CUR или .ANI файла, используйте функцию LoadCursorFromFile.

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

Прикладные программы должны исполнять пользовательские курсоры как ресурсы и использовать функции LoadCursor, LoadCursorFromFile или LoadImage, а не курсор созданный во время выполнения программы. Использование ресурсов курсора освобождает от зависимости от устройства, упрощает определение местонахождения и дает возможность прикладным программам совместно использовать разработанные курсоры.

Функция CreateIconFromResourceEx дает возможность прикладной программе создать пиктограммы и курсоры, основанные на данных ресурса. CreateIconFromResourceEx создает курсор, основанный на двоичных данных ресурса из других исполняемых (.EXE) файлов или динамически подключаемых библиотек (DLLs). Этому должны предшествовать обращения к функции LookupIconIdFromDirectoryEx, также как и к нескольким функциям ресурса. Функция LookupIconIdFromDirectoryEx идентифицирует наиболее соответствующие данные курсора для текущего устройства отображения. Для получения дополнительной информации относительно функций ресурса, см. статью Ресурсы.


5.5 - Расположение и вид курсора

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

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

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

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


5.6 - Курсор класса окна

Когда Вы регистрируете класс окна, используя функцию RegisterClass, вы можете назначить ею заданный по умолчанию курсор, известный как курсор класса. После того, как прикладная программа регистрирует класс окна, каждое окно этого класса будет иметь заданный курсор класса (class cursor).

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


5.7 - Ограничение свободы движения курсора

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

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


5.8 - Разрушение курсора

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

Функция DestroyCursor не имеет никакого влияния на общедоступный курсор; то есть курсор, который был загружен при помощи использования флажка LR_SHARED функции LoadImage. Общедоступный курсор допустим, пока модуль, из которого он был загружен, остается в памяти.


5.9 - Дублирование курсора

Функция CopyCursor копирует дескриптор курсора. Это дает возможность прикладной программе или коду DLL извлечь информацию о дескрипторе курсора, принадлежащего другому модулю. Затем, если другой модуль освобождается, модуль, который скопировал курсор, будет все еще получать возможность, чтобы использовать рисунок курсора.

Для информации относительно того, как добавлять, удалять, или заменять ресурсы курсора в исполняемых файлах, см. раздел Ресурсы.


5.10 Использование курсоров

Создание курсора
Отображение курсора
Ограничение курсора
Использование функций курсора для создания мышеловки (mousetrap)
Использование клавиатуры для перемещения курсора


5.10.1 - Создание курсора

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

HINSTANCE hinst;           	 		// дескриптор текущего экземпляра программы
HCURSOR hCurs1, hCurs2;    			// дескрипторы курсоров
                    // создание стандартного курсора в форме песочных часов
hCurs1 = LoadCursor(NULL, IDC_WAIT);
                    // создание индивидуального курсора, основанного на ресурсе
hCurs2 = LoadCursor(hinst, MAKEINTRESOURCE(240));

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

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

HINSTANCE hinst;           			// дескриптор текущего экземпляра
HCURSOR hCurs1, hCurs2;     		// дескрипторы курсора
HCURSOR hCurs3;             		// дескриптор курсора
// битовая маска AND для Yin - курсора
// Примечание переводчика: Термин Инь (Yin) происходит из китайской философии, в которой он
// обозначает темное, женское начало. В этом примере он означает растровый рисунок курсора, в
котором его изображение представлено черными пикселями
BYTE ANDmaskCursor[] =
{
    0xFF, 0xFC, 0x3F, 0xFF,   // строка1
    0xFF, 0xC0, 0x1F, 0xFF,   // строка 2
    0xFF, 0x00, 0x3F, 0xFF,   // строка 3
    0xFE, 0x00, 0xFF, 0xFF,   // строка 4

    0xF7, 0x01, 0xFF, 0xFF,   // строка 5
    0xF0, 0x03, 0xFF, 0xFF,   // строка 6
    0xF0, 0x03, 0xFF, 0xFF,   // строка 7
    0xE0, 0x07, 0xFF, 0xFF,   // строка 8

    0xC0, 0x07, 0xFF, 0xFF,   // строка 9
    0xC0, 0x0F, 0xFF, 0xFF,   // строка 10
    0x80, 0x0F, 0xFF, 0xFF,   // строка 11
    0x80, 0x0F, 0xFF, 0xFF,   // строка 12

    0x80, 0x07, 0xFF, 0xFF,   // строка 13
    0x00, 0x07, 0xFF, 0xFF,   // строка 14
    0x00, 0x03, 0xFF, 0xFF,   // строка 15
    0x00, 0x00, 0xFF, 0xFF,   // строка 16

    0x00, 0x00, 0x7F, 0xFF,   // строка 17
    0x00, 0x00, 0x1F, 0xFF,   // строка 18
    0x00, 0x00, 0x0F, 0xFF,   // строка 19
    0x80, 0x00, 0x0F, 0xFF,   // строка 20

    0x80, 0x00, 0x07, 0xFF,   // строка 21
    0x80, 0x00, 0x07, 0xFF,   // строка 22
    0xC0, 0x00, 0x07, 0xFF,   // строка 23
    0xC0, 0x00, 0x0F, 0xFF,   // строка 24

    0xE0, 0x00, 0x0F, 0xFF,   // строка 25
    0xF0, 0x00, 0x1F, 0xFF,   // строка 26
    0xF0, 0x00, 0x1F, 0xFF,   // строка 27
    0xF8, 0x00, 0x3F, 0xFF,   // строка 28

    0xFE, 0x00, 0x7F, 0xFF,   // строка 29
    0xFF, 0x00, 0xFF, 0xFF,   // строка 30
    0xFF, 0xC3, 0xFF, 0xFF,   // строка 31
    0xFF, 0xFF, 0xFF, 0xFF    // строка 32
};

// битовая маска XOR для Yin - курсора

BYTE XORmaskCursor[] =
{
    0x00, 0x00, 0x00, 0x00,   // строка 1
    0x00, 0x03, 0xC0, 0x00,   // строка 2
    0x00, 0x3F, 0x00, 0x00,   // строка 3
    0x00, 0xFE, 0x00, 0x00,   // строка 4

    0x0E, 0xFC, 0x00, 0x00,   // строка 5
    0x07, 0xF8, 0x00, 0x00,   // строка 6
    0x07, 0xF8, 0x00, 0x00,   // строка 7
    0x0F, 0xF0, 0x00, 0x00,   // строка 8

    0x1F, 0xF0, 0x00, 0x00,   // строка 9
    0x1F, 0xE0, 0x00, 0x00,   // строка 10
    0x3F, 0xE0, 0x00, 0x00,   // строка 11
    0x3F, 0xE0, 0x00, 0x00,   // строка 12

    0x3F, 0xF0, 0x00, 0x00,   // строка 13
    0x7F, 0xF0, 0x00, 0x00,   // строка 14
    0x7F, 0xF8, 0x00, 0x00,   // строка 15
    0x7F, 0xFC, 0x00, 0x00,   // строка 16

    0x7F, 0xFF, 0x00, 0x00,   // строка 17
    0x7F, 0xFF, 0x80, 0x00,   // строка 18
    0x7F, 0xFF, 0xE0, 0x00,   // строка 19
    0x3F, 0xFF, 0xE0, 0x00,   // строка 20

    0x3F, 0xC7, 0xF0, 0x00,   // строка 21
    0x3F, 0x83, 0xF0, 0x00,   // строка 22
    0x1F, 0x83, 0xF0, 0x00,   // строка 23
    0x1F, 0x83, 0xE0, 0x00,   // строка 24

    0x0F, 0xC7, 0xE0, 0x00,   // строка 25
    0x07, 0xFF, 0xC0, 0x00,   // строка 26
    0x07, 0xFF, 0xC0, 0x00,   // строка 27
    0x01, 0xFF, 0x80, 0x00,   // строка 28

    0x00, 0xFF, 0x00, 0x00,   // строка 29
    0x00, 0x3C, 0x00, 0x00,   // строка 30
    0x00, 0x00, 0x00, 0x00,   // строка 31
    0x00, 0x00, 0x00, 0x00    // строка 32
};

// создание пользовательского курсора в период выполнения.

hCurs3 = CreateCursor(
    hinst,	// экземпляр приложения
    19,	// горизонтальная позиция острия
    2,	// вертикальная позиция острия
    32,	// ширина курсора
    32,	// высота курсора
    ANDmaskCursor,	// битовая маска AND
    XORmaskCursor );	// битовая маска XOR

Чтобы создать курсор, CreateCursor применяет следующую таблицу истинности для битовых масок AND и XOR.

Битовая маска AND 	Битовая маска XOR 	Отображение
0			0			Черный цвет
0			1			Белый цвет
1			0			Цвет экрана
1			1			Цвет обратный экранному

За более полной информацией обратись к статье Битовые маски.

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


5.10.2 - Отображение курсора

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

WNDCLASS  wc;
//заполнение структуры класса окна параметрами, которые описывают главное окно.

style = NULL;                        		// стиль(и) класса
wc.lpfnWndProc = (WNDPROC) MainWndProc; 		// оконная процедура
wc.cbClsExtra = 0;           			// дополнительных данных в классе нет
wc.cbWndExtra = 0;           			// дополнительных данных для окна нет
wc.hInstance = hinst;        			// приложение, которое владеет классом
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);     	// иконка класса
wc.hCursor = LoadCursor(hinst, MAKEINTRESOURCE(230)); 	// курсор класса
wc.hbrBackground = GetStockObject(WHITE_BRUSH); 	// фон класса
wc.lpszMenuName =  "GenericMenu";               	// меню класса
wc.lpszClassName = "GenericWClass"              	// имя класса
                        // регистрация класса окна.
return RegisterClass(&wc);

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

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

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

case WM_SETCURSOR:

    // Если окно свернуто рисуется курсор hCurs3.
    // Если окно не свернуто, рисуется курсор
    // по умолчанию (курсор класса).
    if (IsIconic(hwnd))
    {
        SetCursor(hCurs3);
        break;
    }

Когда окно не свернуто, Windows отображает курсор класса.

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

// изменение курсора класса окна, представляемого hwnd
SetClassLong(hwnd,    		// дескриптор окна
    GCL_HCURSOR,      		// изменяемый курсор
    (LONG) hCurs2);   		// новый курсор

За более подробной информацией, обратитесь к статьям Классы окна и Информация вводимая от Мыши.


5.10.3 - Ограничение свободы перемещения курсора

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

RECT rcClip;           	// новая область для ClipCursor
RECT rcOldClip;        	// предыдущая область для ClipCursor
// Запись области, в которой курсор может перемещаться.
GetClipCursor(&rcOldClip);
// Получение габаритов окна приложения.
GetWindowRect(hwnd, &rcClip);
// Ограничение перемещения курсора в окне приложения.
ClipCursor(&rcClip);
//
// Обработка вводимой информации от ограниченного в перемещении курсора.
//
// Возвращение курсора в его предыдущую область.
ClipCursor(&rcOldClip);

Поскольку в системе имеется только один курсор, доступный одновременно, прикладная программа, которая ограничила перемещение курсора, должна восстановить курсор перед отказом от управления им в другом окне.


5.10.4 - Использование функций курсора для создания "мышеловки"

В примере ниже используются функции SetCursorPos, GetCursorPos, CreateCursor, LoadCursor и SetCursor для создания простой "мышеловки". В нем используются также функции курсора и таймера для отслеживания позиции курсора каждые 10 секунд. Если позиция курсора не изменялась за последние 10 секунд, а главное окно прикладной программы свернуто, прикладная программа изменяет курсор и перемещает его в пиктограмму "мышеловки".

Пример для простой "мышеловки" включается в Пиктограммы (Icons). В нем используются функции LoadCursor и LoadIcon вместо более аппаратно-зависимых функций CreateCursor и CreateIcon.

HICON hIcon1;               	// дескрипторы иконки
POINT ptOld;                	// предыдущее расположение курсора
HCURSOR hCurs1;             	// дескриптор курсора

// Ниже следующие битовые маски курсора определены в примере кода,
// который появлялся ранее в этом разделе.
// битовая маска AND  и XOR для Yin курсора

BYTE ANDmaskCursor[] = ...
BYTE XORmaskCursor[] = ...

// битовая маска AND Yang пиктограммы
//Прим. Переводчика:Термин Янь (Yang) происходит из китайской философии, в которой он обозначает
//светлое, мужское начало. В этом примере он означает растровый рисунок курсора, в котором его
//изображение представлено белыми пикселями.

BYTE ANDmaskIcon[] = {
    0xFF, 0xFF, 0xFF, 0xFF,  // строка 1
    0xFF, 0xFF, 0xC3, 0xFF,  // строка 2
    0xFF, 0xFF, 0x00, 0xFF,  // строка 3
    0xFF, 0xFE, 0x00, 0x7F,  // строка 4

    0xFF, 0xFC, 0x00, 0x1F,  // строка 5
    0xFF, 0xF8, 0x00, 0x0F,  // строка 6
    0xFF, 0xF8, 0x00, 0x0F,  // строка 7
    0xFF, 0xF0, 0x00, 0x07,  // строка 8

    0xFF, 0xF0, 0x00, 0x03,  // строка 9
    0xFF, 0xE0, 0x00, 0x03,  // строка 10
    0xFF, 0xE0, 0x00, 0x01,  // строка 11
    0xFF, 0xE0, 0x00, 0x01,  // строка 12

    0xFF, 0xF0, 0x00, 0x01,  // строка 13
    0xFF, 0xF0, 0x00, 0x00,  // строка 14
    0xFF, 0xF8, 0x00, 0x00,  // строка 15
    0xFF, 0xFC, 0x00, 0x00,  // строка 16

    0xFF, 0xFF, 0x00, 0x00,  // строка 17
    0xFF, 0xFF, 0x80, 0x00,  // строка 18
    0xFF, 0xFF, 0xE0, 0x00,  // строка 19
    0xFF, 0xFF, 0xE0, 0x01,  // строка 20

    0xFF, 0xFF, 0xF0, 0x01,  // строка 21
    0xFF, 0xFF, 0xF0, 0x01,  // строка 22
    0xFF, 0xFF, 0xF0, 0x03,  // строка 23
    0xFF, 0xFF, 0xE0, 0x03,  // строка 24

    0xFF, 0xFF, 0xE0, 0x07,  // строка 25
    0xFF, 0xFF, 0xC0, 0x0F,  // строка 26
    0xFF, 0xFF, 0xC0, 0x0F,  // строка 27
    0xFF, 0xFF, 0x80, 0x1F,  // строка 28

    0xFF, 0xFF, 0x00, 0x7F,  // строка 29
    0xFF, 0xFC, 0x00, 0xFF,  // строка 30
    0xFF, 0xF8, 0x03, 0xFF,  // строка 31
    0xFF, 0xFC, 0x3F, 0xFF}; // строка 32

    // битовая маска XOR Yang иконки

BYTE XORmaskIcon[] = {
    0x00, 0x00, 0x00, 0x00,  // строка 1
    0x00, 0x00, 0x00, 0x00,  // строка 2
    0x00, 0x00, 0x00, 0x00,  // строка 3
    0x00, 0x00, 0x00, 0x00,  // строка 4

    0x00, 0x00, 0x00, 0x00,  // строка 5
    0x00, 0x00, 0x00, 0x00,  // строка 6
    0x00, 0x00, 0x00, 0x00,  // строка 7
    0x00, 0x00, 0x38, 0x00,  // строка 8

    0x00, 0x00, 0x7C, 0x00,  // строка 9
    0x00, 0x00, 0x7C, 0x00,  // строка 10
    0x00, 0x00, 0x7C, 0x00,  // строка 11
    0x00, 0x00, 0x38, 0x00,  // строка 12

    0x00, 0x00, 0x00, 0x00,  // строка 13
    0x00, 0x00, 0x00, 0x00,  // строка 14
    0x00, 0x00, 0x00, 0x00,  // строка 15
    0x00, 0x00, 0x00, 0x00,  // строка 16

    0x00, 0x00, 0x00, 0x00,  // строка 17
    0x00, 0x00, 0x00, 0x00,  // строка 18
    0x00, 0x00, 0x00, 0x00,  // строка 19
    0x00, 0x00, 0x00, 0x00,  // строка 20

    0x00, 0x00, 0x00, 0x00,  // строка 21
    0x00, 0x00, 0x00, 0x00,  // строка 22
    0x00, 0x00, 0x00, 0x00,  // строка 23
    0x00, 0x00, 0x00, 0x00,  // строка 24

    0x00, 0x00, 0x00, 0x00,  // строка 25
    0x00, 0x00, 0x00, 0x00,  // строка 26
    0x00, 0x00, 0x00, 0x00,  // строка 27
    0x00, 0x00, 0x00, 0x00,  // строка 28

    0x00, 0x00, 0x00, 0x00,  // строка 29
    0x00, 0x00, 0x00, 0x00,  // строка 30
    0x00, 0x00, 0x00, 0x00,  // строка 31
    0x00, 0x00, 0x00, 0x00}; // строка 32

hIcon1 = CreateIcon(
    hinst,	// дескриптор экземпляра приложения
    32,	// ширина иконки
    32,	// высота иконки
    1,	// число плоскостей XOR
    1,	// число битов на пиксель
    ANDmaskIcon,	// битовая маска AND
    XORmaskIcon);	// битовая маска XOR

hCurs1 = CreateCursor(
    hinst,	// дескриптор экземпляра приложения
    19,	// горизонтальная позиция острия
    2,	// вертикальная позиция острия
    32,	// ширина курсора
    32,	// высота курсора
    ANDmaskCursor,	// битовая маска AND
    XORmaskCursor);	// битовая маска XOR

// Заполнение полей структуры класса окна

WNDCLASS  wc;

wc.hIcon = hIcon1;				// иконка класса
wc.hCursor = LoadCursor(NULL, IDC_ARROW); 	// курсор класса

//
// регистрация класса окна и выполнение других инициализаций программы
//
//
// установка таймера для "мышеловки".

GetCursorPos(&ptOld);

SetTimer(hwnd, IDT_CURSOR, 10000, (TIMERPROC) NULL);

LONG APIENTRY MainWndProc(
    HWND hwnd,	// дескриптор окна
    UINT message,	// тип сообщения
    UINT wParam,	// дополнительная информация
    LONG lParam)	// дополнительная информация
{
    HDC hdc;	// дескриптор контекста устройства
    POINT pt;	// текущее расположение курсора
    RECT rc;	// превращенное в иконку расположение окна

    switch (message)
    {
        //
        // обработка других сообщений.
        //

    case WM_TIMER:

        // если окно свернуто, сравниваем
        // текущее положение курсора за 10 секунд до этого
        // момента. Если позиция курсора не изменялась,
        // перемещаем курсор в иконку.
        if (IsIconic(hwnd))
        {
            GetCursorPos(&pt);
            if ((pt.x == ptOld.x) && (pt.y == ptOld.y))
            {
                GetWindowRect(hwnd, &rc);
                SetCursorPos(rc.left + 20, rc.top + 4);

                // заметьте, что дополнительные константы
                // (20 и 4) значения, определяемые программой
                // для выравнивания yin-образного курсора
                // и yang-образной иконки.

            }
            else
            {
                ptOld.x = pt.x;
                ptOld.y = pt.y;
            }
        }
        return 0;

    case WM_SETCURSOR:
        // если окно свернуто, рисуется hCurs1.
        // если окно не свернуто, рисуется курсор по умолчанию
        // (курсор класса).

        if (IsIconic(hwnd))
        {
            SetCursor(hCurs1);
            break;
        }

    case WM_DESTROY:
        // разрушаем таймер

        KillTimer(hwnd, IDT_CURSOR);
        PostQuitMessage(0);
        break;
    }
}


5.10.5 - Использование клавиатуры для перемещения курсора

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

HCURSOR hCurs1, hCurs2;    			// дескриптор курсора
POINT pt;                  			// расположение курсора
RECT rc;                   			// координаты рабочей области
static int repeat = 1;     			// счетчик повтора нажатий клавиши

//
// Другие объявления и инициализация.
//

switch (message)
{
//
// Обработка других сообщений.
//
    case WM_KEYDOWN:

        if (wParam != VK_LEFT && wParam != VK_RIGHT &&
        wParam != VK_UP && wParam != VK_DOWN)
        {
            break;
        }

        GetCursorPos(&pt);

        // Преобразование экранных координат в рабочие координаты.

        ScreenToClient(hwnd, &pt);

        switch (wParam)
        {
        // Отображение перемещения курсора, когда
        // нажата клавиша курсора.

            case VK_LEFT:	// стрелка влево
                pt.x -= repeat;
                break;

            case VK_RIGHT:	// стрелка вправо
                pt.x += repeat;
                break;

            case VK_UP:	// стрелка вверх
                pt.y -= repeat;
                break;

            case VK_DOWN:	// стрелка вниз
                pt.y += repeat;
                break;

            default:
                return NULL;

        }

        repeat++;	// счетчик увеличения числа повторов на единицу
            // Сохранение курсора в рабочей области.

        GetClientRect(hwnd, &rc);

        if (pt.x >= rc.right)
        {
            pt.x = rc.right - 1;
        }
        else
        {
            if (pt.x < rc.left)
            {
                pt.x = rc.left;
            }
        }

        if (pt.y >= rc.bottom)
            pt.y = rc.bottom - 1;
        else
            if (pt.y < rc.top)
                pt.y = rc.top;

        // Преобразование рабочих координат в экранные координаты.

        ClientToScreen(hwnd, &pt);
        SetCursorPos(pt.x, pt.y);
        break;

    case WM_KEYUP:

        repeat = 1;	// очистка счетчика повторений
        break;
}


5.11 - Справочник по Курсору

Следующие функции и сообщения связаны с курсорами.


5.11.1 - Функции курсора

Ниже следуют функции, используемые с курсорами:
ClipCursor
CopyCursor
CreateCursor
DestroyCursor
GetClipCursor
GetCursor
GetCursorPos
LoadCursor
LoadCursorFromFile
SetCursor
SetCursorPos
SetSystemCursor
ShowCursor


5.11.1.1 - Функция ClipCursor

(ОграничениеКурсора)

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

Синтаксис

BOOL ClipCursor
(
    CONST RECT *lpRect 	// указатель на структуру прямоугольника
);

Параметры
lpRect
Указывает на структуру RECT, которая содержит экранные координаты левого верхнего и нижнего правого углов прямоугольника ограничения. Если этот параметр значение ПУСТО (NULL), курсор свободен для передвижения в любое место экрана.

Возвращаемые значения
Если функция завершилась успешно, возвращается значение отличное от нуля.
Если функция потерпела неудачу, возвращаемое значение - ноль. Чтобы получить расширенные данные об ошибках, обратитесь к функции GetLastError.

Замечания
Курсор - общедоступный ресурс. Если прикладная программа ограничивает курсор, она должна освободить курсор, используя ClipCursor перед отказом от управления им в другой прикладной программе.
Вызываемый процесс должен иметь доступ WINSTA_WRITEATTRIBUTES к месту окна.

Смотри также
GetClipCursor, GetCursorPos, RECT, SetCursorPos

Размещение и совместимость ClipCursor

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


5.11.1.2 - Функция CopyCursor

(КопированиеКурсора)

Функция CopyCursor копирует курсор.

Синтаксис

HCURSOR CopyCursor
(
    HCURSOR pcur 	// дескриптор копируемого курсора
);

Параметры
pcur
Идентификатор копируемого курсора.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - дескриптор дубликата курсора.
Если функция не выполняет задачу, возвращаемое значение ПУСТО (NULL). Чтобы получить расширенные данные об ошибках, вызовите GetLastError.

Замечания
Функция CopyCursor дает возможность прикладной программе или динамически подключаемой библиотеке (DLL) получить дескриптор образца курсора, принадлежащий другому модулю. И даже тогда, когда другой модуль освобождается, прикладная программа все еще способна использовать этот образец курсора.

Смотри также
CopyIcon, GetCursor, SetCursor, ShowCursor

Размещение и совместимость CopyCursor

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


5.11.1.3 - Функция CreateCursor

(СоздатьКурсор)

Функция CreateCursor создает курсор, имеющий заданный размер, битовые шаблоны и острие.

Синтаксис

HCURSOR CreateCursor
(
    HINSTANCE hInst,	// дескриптор экземпляра программы
    int xHotSpot,		// позиция острия по горизонтали
    int yHotSpot,		// позиция острия по вертикали
    int nWidth,		// ширина курсора
    int nHeight,		// высота курсора
    CONST VOID *pvANDPlane,	// указатель на массив битовой маски AND
    CONST VOID *pvXORPlane 	// указатель на массив битовой маски XOR
);

Параметры
hInst
Идентифицирует текущий образец прикладной программы, создающей курсор.
xHotSpot
Определяет горизонтальную позицию острия курсора.
yHotSpot
Определяет вертикальную позицию острия курсора.
nWidth
Устанавливает ширину курсора в пискелях.
nHeight
Устанавливает высоту курсора в пискелях.
pvANDplane
Указывает на массив байтов, который содержит битовые значения битовой маски AND для курсора, как в аппаратно-зависимом одноцветном точечном рисунке.
pvXORplane
Указывает на массив байтов, который содержит битовые значения битовой маски XOR для курсора, как в аппаратно-зависимом одноцветном точечном рисунке.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение идентифицирует курсор.
Если функция не выполняет задачу, возвращаемое значение ПУСТО (NULL). Чтобы получить расширенные данные об ошибках, вызовите GetLastError.

Замечания
Параметры nWidth и nHeight должны установить ширину и высоту, которые поддерживаются текущим драйвером дисплея, потому что система не может создать курсоры других размеров. Чтобы определить ширину и высоту, поддерживаемую драйвером дисплея, используйте функцию GetSystemMetrics, установив значение SM_CXCURSOR или SM_CYCURSOR.
Перед закрытием, приложение должно вызвать функцию DestroyCursor, чтобы освободить любые ресурсы системы, связанные с курсором.

Смотри также
CreateIcon, DestroyCursor, GetModuleHandle, GetSystemMetrics, SetCursor

Размещение и совместимость CreateCursor

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


5.11.1.4 - Функция DestroyCursor

(РазрушитьКурсор)

Функция DestroyCursor уничтожает курсор, созданный функцией CreateCursor и освобождает любую память занятую курсором. Не используйте эту функцию, чтобы уничтожить курсор, который не был создан функцией CreateCursor.

Синтаксис

BOOL DestroyCursor
(
    HCURSOR hCursor 	// дескриптор курсора, который разрушается
);

Параметры
hCursor
Идентифицирует курсор, который будет разрушен. Курсор не должен быть в использовании.

Возвращаемые значения
Если функция завершилась успешно, возвращается значение отличное от нуля.
Если функция потерпела неудачу, возвращаемое значение - ноль. Чтобы получить расширенные данные об ошибках, обратитесь к функции GetLastError.

Смотри также
CreateCursor

Размещение и совместимость DestroyCursor.

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


5.11.1.5 - Функция GetClipCursor

(ПолучитьОграничениеКурсора)

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

Синтаксис

BOOL GetClipCursor
(
    LPRECT lpRect 	// адрес структуры для прямоугольника
);

Параметры
lpRect
Указывает на структуру RECT, которая принимает экранные координаты прямоугольника ограничения. Структура принимает габариты экрана, если курсор не ограничен в прямоугольнике.

Возвращаемые значения
Если функция завершилась успешно, возвращается значение отличное от нуля.
Если функция потерпела неудачу, возвращаемое значение - ноль. Чтобы получить расширенные данные об ошибках, обратитесь к функции GetLastError.

Замечания
Курсор - общедоступный ресурс. Если прикладная программа ограничивает курсор при помощи функции ClipCursor, она позже должна освободить курсор, используя ClipCursor перед отказом от управления им в другой прикладной программе.
Процесс вызова должен иметь указатель WINSTA_READATTRIBUTES на местоположение окна.

Смотри также
ClipCursor, GetCursorPos, RECT

Размещение и совместимость GetClipCursor

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


5.11.1.6 - Функция GetCursor

(ПолучитьКурсор)

Функция GetCursor извлекает информацию о дескрипторе текущего курсора.

Синтаксис

HCURSOR GetCursor(VOID)

Параметры
У этой функции нет параметров.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - дескриптор текущего курсора.
Если не имеется никакого курсора, возвращаемое значение ПУСТО (NULL).

Смотри также
SetCursor

Размещение и совместимость GetCursor

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


5.11.1.7 - Функция GetCursorPos

(ПолучитьПозициюКурсора)

Функция GetCursorPos извлекает информацию о позиции курсора, в экранных координатах.

Синтаксис

BOOL GetCursorPos
(
    LPPOINT lpPoint 	// адрес структуры, где позиция курсора
);

Параметры
lpPoint
Указывает на структуру POINT, которая принимает экранные координаты курсора.

Возвращаемые значения
Если функция завершилась успешно, возвращается значение отличное от нуля.
Если функция потерпела неудачу, возвращаемое значение - ноль. Чтобы получить расширенные данные об ошибках, обратитесь к функции GetLastError.

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

Смотри также
ClipCursor, POINT, SetCursor, SetCursorPos, ShowCursor

Размещение и совместимость GetCursorPos

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


5.11.1.8 - Функция LoadCursor

(ЗагрузитьКурсор)

Функция LoadCursor загружает заданный ресурс курсора из (.EXE) файла выполняемой программы, связанной с экземпляром прикладной программы.

Синтаксис

HCURSOR LoadCursor
(
    HINSTANCE hInstance,	// дескриптор экземпляра приложения
    LPCTSTR lpCursorName 	// идентификатор названия строки или ресурса курсора
);

Параметры
hInstance
Идентифицирует экземпляр модуля, исполняемый файл которого содержит курсор, который будет загружен.
lpCursorName
Указывает на строку с символом нуля в конце, содержащую имя ресурса курсора, который будет загружен. Или же, этот параметр может состоять из идентификатора ресурса, в младшем слове и нуля в старшем слове. Может также использоваться макрокоманда MAKEINTRESOURCE, чтобы создать это значение.
Чтобы использовать предопределенный курсор Win32, прикладная программа должна установить параметр hInstance в значение ПУСТО (NULL), а параметр lpCursorName в одно из следующих значений:

  • IDC_APPSTARTING - Стандартная стрелка и маленькие песочные часы
  • IDC_ARROW - Стандартная стрелка
  • IDC_CROSS - Перекрестие
  • IDC_IBEAM - I-прямая вертикальная линия для текста
  • IDC_ICON - Только для Windows NT: Пустая иконка
  • IDC_NO - Перечеркнутый круг
  • IDC_SIZE - Только для Windows NT: Четырех направленная стрелка
  • IDC_SIZEALL - Подобно IDC_SIZE
  • IDC_SIZENESW - Двунаправленная стрелка, указывающая северо-восток и юго-запад
  • IDC_SIZENS - Двунаправленная стрелка, указывающая север и юг
  • IDC_SIZENWSE - Двунаправленная стрелка, указывающая северо-запад и юго-восток
  • IDC_SIZEWE - Двунаправленная стрелка, указывающая запад и восток
  • IDC_UPARROW - Вертикальная стрелка
  • IDC_WAIT - Песочные часы

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - дескриптор недавно загруженного курсора.
Если функция не выполняет задачу, возвращаемое значение ПУСТО (NULL). Чтобы получать расширенные данные об ошибках, вызовите GetLastError

Замечания
LoadCursor загружает только ресурс курсора, если он не был загружен; иначе, функция извлекает дескриптор существующего ресурса. Эта функция возвращает допустимое значение дескриптора курсора только тогда, если параметр lpCursorName указывает на ресурс курсора. Если lpCursorName указывает на какой-либо тип ресурса отличающегося от курсора (например, пиктограммы), возвращаемое значение не ПУСТО (NULL), даже притом, что это не правильный дескриптор курсора.
Функция LoadCursor ищет ресурс курсора наиболее соответствующий курсору для текущего устройства отображения. Ресурс курсора может быть цветной или одноцветный точечный рисунок.

Смотри также
LoadImage, MAKEINTRESOURCE, SetCursor, SetCursorPos, ShowCursor

Размещение и совместимость LoadCursor

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


5.11.1.9 - Функция LoadCursorFromFile

(ЗагрузитьКурсорИзФайла)

Функция LoadCursorFromFile создает курсор, основанный на данных, содержащихся в файле. Файл определен его именем или идентификатором курсора системы. Функция возвращает значение дескриптора недавно созданного курсора. Файлы, содержащие данные курсора могут быть или в формате курсора (.CUR) или "живого указателя" (.ANI).

Синтаксис

HCURSOR LoadCursorFromFile
(
    LPCTSTR lpFileName	// указатель на имя файла курсора или
                // на идентификатор системного курсора
);

Параметры
lpFileName
Указывает источник данных файла, которые нужно использовать, чтобы создать курсор. Данные в файле должны быть или в формате .ANI или .CUR.
Если старшее слово LoadCursorFromFile отлично от нуля, это - указатель на строку, которая является полностью составным именем файла, содержащего данные курсора.
Если старшее слово lpszFileName нулевое, младшее слово является идентификатором курсора системы. Затем функция ищет входную точку [Cursors] в файле WIN.INI для файла, связанного с именем этого курсора системы. Имеется список имен курсоров системы и идентификаторов:

Имена Системных Курсоров							Идентификаторы Системных Курсоров
"Arrow" -стрелка								OCR_NORMAL
"IBeam" - I - образная линия						OCR_IBEAM
"Wait" - ждать (песочные часы)						OCR_WAIT
"Crosshair" -крест								OCR_CROSS
"UpArrow" -стрелка вверх							OCR_UP
"Size" -двунаправленная стрелка						OCR_SIZE
"Icon" - пиктограмма							OCR_ICON
"SizeNWSE" - двунаправленная стрелка северо-запад - юго-восток			OCR_SIZENWSE
"SizeNESW" - двунаправленная стрелка северо-восток - юго-запад			OCR_SIZENESW
"SizeWE" -двунаправленная стрелка запад-восток				OCR_SIZEWE
"SizeNS" - - двунаправленная стрелка север-юг					OCR_SIZENS
"SizeAll" -крест из стрелок							OCR_SIZEALL
"No"									OCR_NO
"AppStarting"								OCR_APPSTARTING

Например, если WIN.INI файл содержит следующее:

[Cursors]
    Arrow = "arrow.ani"

Тогда вызывается

LoadCursorFromFile((LPWSTR)OCR_NORMAL),

что заставляет функцию LoadCursorFromFile получить данные курсора из файла ARROW.ANI. Если файл WIN.INI не содержит входной точки для заданного курсора системы, функция не выполняет задачу и возвращает значение ПУСТО (NULL).

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - дескриптор нового курсора.
Если функция не выполняет задачу, возвращаемое значение ПУСТО (NULL). Чтобы получать расширенные данные об ошибках, вызовите функцию GetLastError.
Функция GetLastError может возвратить следующее значение:

  • ERROR_FILE_NOT_FOUND - Невозможно найти заданный файл

Смотри также
LoadCursor, SetCursor, SetSystemCursor

Размещение и совместимость LoadCursorFromFile

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


5.11.1.10 - Функция SetCursor

(УстановитьКурсор)

Функция SetCursor устанавливает форму курсора.

Синтаксис

HCURSOR SetCursor
(
    HCURSOR hCursor 	// дескриптор курсора
);

Параметры
hCursor
Идентифицирует курсор. Курсор, должен быть создан функцией CreateCursor или загружен функцией LoadCursor или LoadImage. Если этот параметр имеет значение ПУСТО (NULL), курсор удаляется с экрана.
Windows 95: ширина и высота курсора должны быть значениями, возвращенными функцией GetSystemMetrics для SM_CXCURSOR и SM_CYCURSOR. Кроме того, битовая глубина резко изображаемого пространства курсора должна соответствовать битовой глубине резко изображаемого пространства дисплея, или курсор должен быть одноцветен.

Возвращаемые значения
Возвращаемое значение - дескриптор предыдущего курсора, если тот имелся.
Если не было никакого предыдущего курсора, возвращаемое значение ПУСТО (NULL).

Замечания
Курсор устанавливается только тогда, если новый курсор отличается от предыдущего курсора; иначе, функция немедленно возвращает значение.
Курсор - общедоступный ресурс. Окно должно устанавливать форму курсора только тогда, когда курсор находится в его рабочей области или когда окно захватило ввод мыши. В системах без мыши, окно должно восстановить предыдущий курсор до того, как курсор оставит рабочую область или до того, как система предоставит управление другому окну.
Если ваша прикладная программа должна установить курсор, в то время когда оно находится в окне, удостоверитесь, что курсор класса в классе определяемого окна установлен в значение ПУСТО (NULL). Если курсор класса не ПУСТО (NULL), система восстанавливает курсор класса, каждый раз, когда перемещается мышь.
Курсор не показывается на экране, если внутренний счетчик отображения курсора - меньше чем нуль. Это происходит тогда, если прикладная программа использует функцию ShowCursor для сокрытия курсора большее количество времени, чем для показа курсора.

Смотри также
CreateCursor, GetCursor, GetSystemMetrics, LoadCursor, LoadImage, SetCursorPos, ShowCursor

Размещение и совместимость SetCursor

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


5.11.1.11 - Функция SetCursorPos

(УстановитьПозициюКурсора)

Функция SetCursorPos перемещает курсор в заданные экранные координаты. Если новые координаты не внутри экранного прямоугольника, установленного самой последней функцией ClipCursor, Windows автоматически корректирует координаты так, чтобы курсор остался внутри прямоугольника.

Синтаксис

BOOL SetCursorPos
(
    int X,	// позиция по горизонтали
    int Y 	// позиция по вертикали
);

Параметры
X
Устанавливает новую x-координату, в экранных координатах, курсора.
Y
Устанавливает новую y-координату, в экранных координатах, курсора.

Возвращаемые значения
Если функция завершилась успешно, возвращается значение отличное от нуля.
Если функция потерпела неудачу, возвращаемое значение - ноль. Чтобы получить расширенные данные об ошибках, обратитесь к функции GetLastError.

Замечания
Курсор - общедоступный ресурс. Окно должно перемещать курсор, только тогда, когда курсор находится в его рабочей области.
Процесс вызова должен иметь указатель WINSTA_WRITEATTRIBUTES местоположение окна.

Смотри также
ClipCursor, GetCursorPos, SetCaretPos, SetCursor, ShowCursor

Размещение и совместимость SetCursorPos

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


5.11.1.12 - Функция SetSystemCursor

(УстановитьСистемныйКурсор)

Функция SetSystemCursor заменяет содержимое системного курсора, заданного идентификатором id содержимым курсора, заданного hcur, и затем уничтожает hcur. Эта функция позволяет прикладной программе настраивать курсоры системы.

Синтаксис

BOOL SetSystemCursor
(
    HCURSOR hcur,	// устанавливает заданный курсор системы в содержимом этого
            //курсора, эатем уничтожает его
    DWORD id	// курсор системы, заданный его идентификатором
);

Параметры
hcur
Дескриптор курсора. Функция заменяет содержимое курсора системы, заданного идентификатором id, содержимым курсора, обработанного при помощи hcur. Затем функция уничтожает hcur, вызывая DestroyCursor (hCursor).
id
Идентификатор курсора системы. Функция заменяет содержимое этого курсора системы содержимым курсора, обработанного при помощи hcur.
Ниже следует список идентификаторов курсоров системы:

  • OCR_NORMAL - Обычный курсор-стрелка
  • OCR_IBEAM - I-образный курсор
  • OCR_WAIT - Курсор в виде больших песочных часов
  • OCR_CROSS - Курсор в виде креста
  • OCR_UP - Курсор стрелка вверх
  • OCR_SIZE - Курсор размера (четырех направленная стрелка)
  • OCR_ICON - Курсор в виде пиктограммы
  • OCR_SIZENWSE - Курсор изменения размера (двунаправленная стрелка СЗ - ЮВ)
  • OCR_SIZENESW - Курсор изменения размера (двунаправленная стрелка СВ - ЮЗ)
  • OCR_SIZEWE - Курсор изменения размера по горизонтали
  • OCR_SIZENS - Курсор изменения размера по вертикали
  • OCR_SIZEALL - Курсор изменения размера по вертикали и горизонтали
  • OCR_SIZENO - Международный символ отсутствия курсора
  • OCR_APPSTARTING - Курсор в виде стрелки с маленькими песочными часами

Возвращаемые значения
Если функция завершилась успешно, возвращается значение отличное от нуля.
Если функция потерпела неудачу, возвращаемое значение - ноль. Чтобы получить расширенные данные об ошибках, обратитесь к функции GetLastError.

Смотри также
DestroyCursor, LoadCursor, LoadCursorFromFile, SetCursor

Размещение и совместимость SetSystemCursor

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


5.11.1.13 - Функция ShowCursor

(ПоказатьКурсор)

Функция ShowCursor отображает или скрывает курсор.

Синтаксис

int ShowCursor
(
    BOOL bShow 	// флажок видимости курсора
);

Параметры
bShow
Определяет, должен ли внутренний счетчик отображения быть увеличен или уменьшен. Если bShow - ИСТИНА (TRUE), счет дисплея увеличивается на единицу. Если bShow - ЛОЖЬ(FALSE), счет дисплея уменьшается на единицу.

Возвращаемые значения
Возвращаемое значение устанавливает новый счетчик отображения.

Замечания
Эта функция устанавливает внутренний счетчик отображения, который определяет, должен ли курсор отображаться. Курсор отображается только тогда, если счетчик отображения больше чем 0 или равен 0. Если инсталлирована мышь, начальное значение счетчика отображения - 0. Если никакая мышь не установлена, начальное значение счетчика отображения -(минус)1.

Смотри также
ClipCursor, GetCursorPos, SetCursor, SetCursorPos

Размещение и совместимость ShowCursor

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


5.11.2 - Сообщения курсора

Следующее сообщение используется курсорами.
WM_SETCURSOR


5.11.2.1 - Сообщение WM_SETCURSOR

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

Синтаксис

WM_SETCURSOR
hwnd = (HWND) wParam;       // дескриптор окна с курсором
nHittest = LOWORD(lParam);  //код местоположения курсора (hit-test code)
wMouseMsg = HIWORD(lParam); // идентификатор сообщения мыши

Параметры
hwnd
Значение wParam. Идентифицирует окно, которое содержит курсор.
nHittest
Значение младшего слова lParam. Определяет код местоположения курсора.
wMouseMsg
Значение старшего слова lParam. Определяет идентификатор сообщения мыши.

Действие по умолчанию
Функция DefWindowProc, перед обработкой, передает сообщение WM_SETCURSOR родительскому окну. Если родительское окно возвращает ИСТИНА (TRUE), дальнейшая обработка останавливается. Передача сообщения родительскому окну дает ему контроль над установкой курсора в дочернем окне. Функция DefWindowProc также использует это сообщение для того, чтобы установить курсор в виде стрелке, если он не в рабочей области, или в виде зарегистрированного курсора класса, если он находится в рабочей области. Если младшее слово параметра lParam - HTERROR, а старшее слово lParam определяет, что одна из кнопок мыши нажата, DefWindowProc вызывает функцию MessageBeep.

Замечания
Старшее слово lParam имеет значение ноль тогда, когда окно вводит режим меню.

Смотри также
DefWindowProc, MessageBeep

Размещение и совместимость WM_SETCURSOR

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется
Предыдущий Шаг


Глава 11 - Меню

Меню (menu) состоит из перечня пунктов меню (menu items). Выбор пункта меню открывает подменю или принуждает прикладную программу выполнить команду.

Следующий Шаг


11.1 - О меню

Этот краткий обзор описывает меню и объясняет, как использовать их в прикладных программах, разработанных при помощи Microsoft Win32 прикладного программного интерфейса (API).


11.2 - Строки меню и меню

Меню выстраивается иерархически. На верхнем уровне иерархии стоит строка горизонтальное меню (menu bar); вертикальные или просто меню (menus) выскакивают вниз из строки меню, а в нижних уровнях – подменю (submenus). Строка меню иногда называется меню верхнего уровня (top-level menu), а меню и подменю также известны как всплывающие меню (pop-up menus).

Пункт меню может или выполнить команду или открыть подменю. Пункт, который выполняет команду, называется командным пунктом (command item) или командой (command).

Пункт в горизонтальном меню почти всегда открывает меню. Строки меню редко содержат командные пункты. Меню, открытое из строки меню выскакивает вниз из нее и иногда называется выскакивающее меню (drop-down menu). Когда выскакивающее меню показывается на экране, оно связано со строкой меню. Пункт меню в строке меню, который открывает выскакивающее меню, называется также именем меню (menu name).

Имена меню в строке меню представляют основные категории команд, которые обеспечивает прикладная программа. Выбор имени меню из строки меню обычно открывает меню, пункты которого соответствуют командам в данной категории. Например, строка меню может содержать имя меню Файл (File) которое, когда выбрано пользователем, активизирует меню с пунктами такими как Создать (New), Открыть (Open) и Сохранить (Save).

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

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


11.3 - Вспомогательное меню

Windows к тому же предоставляет и вспомогательное меню (shortcut menus). Вспомогательное меню не связано со строкой меню; оно может появляться где угодно на экране. Прикладная программа обычно связывает вспомогательное меню с частями окна, такими как рабочая область или с конкретным объектом, типа пиктограммы. По этой причине, эти меню также называются "контекстные меню".

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


11.4 - Меню окна

Меню окна (window menu) (известное также как Системное меню (System menu или Control menu)) - всплывающее меню, определяемое и управляемое почти исключительно операционной системой. Пользователь может открыть меню окна щелчком по пиктограмме программы в области заголовка или щелкая правой кнопкой мыши где-нибудь в области заголовка.

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

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

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


11.5 - Идентификатор справки

С каждой строкой меню, меню, подменю и вспомогательным меню связан 32-разрядный идентификатор справки. Если пользователь нажимает клавишу F1, в то время, когда меню активно, это значение оправляется окну владельцу как часть сообщения WM_HELP. Для получения дополнительной информации о идентификаторах справки, см. главу Справка.


11.6 - Дескрипторы меню

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

Чтобы извлечь данные о дескрипторе строки меню для меню, которое было создано или загружено, используется функция GetMenu. Чтобы извлечь данные о дескрипторе подменю, связанного с пунктом меню, используйте функцию GetSubMenu или GetMenuItemInfo. Чтобы извлечь данные о дескрипторе меню окна, используйте функцию GetSystemMenu.


11.7 - Пункты меню

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


11.7.1 - Командные пункты и пункты, которые открывают подменю

Когда пользователь выбирает командный пункт, Windows отправляет сообщение о команде окну, которое владеет меню. Если командный пункт находится в меню окна, Windows отправляет сообщение WM_SYSCOMMAND. Иначе, она посылает сообщение WM_COMMAND.

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

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

9_1.gif (8360 b)


11.7.2 - Идентификатор пункта меню.

Уникальное, определяемое программой целое число, связанное с каждым пунктом меню, называется идентификатором пункта меню (menu-item identifier). Когда пользователь выбирает командный пункт из меню, Windows отправляет идентификатор пункта окну владельцу как часть сообщения WM_COMMAND. Оконная процедура проверяет идентификатор, чтобы установить источник сообщения и обрабатывает сообщение соответственно. Кроме того, Вы можете определить пункт меню, используя его идентификатор, когда вызываете функции меню; например, чтобы включить или отключить пункт меню.

Идентификатор пункта меню должен быть значением от 0 до 65,535, даже притом, что это - 32-разрядное целое число. Это так потому, что сообщение WM_COMMAND посылает идентификатор пункта меню как младшее слово параметра wParam.

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

Чтобы извлечь данные об идентификаторе пункта меню в заданной позиции, используйте функцию GetMenuItemID или GetMenuItemInfo.


11.7.3 - Позиция пункта меню

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

11_1.gif (8143 b)

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


11.7.4 - Заданные по умолчанию пункты меню

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


11.7.5 - Пункты меню с галочкой и без галочки

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

13_1.gif (9245 b)

Прикладные программы обычно отмечают "галочкой" или снимают отметку "галочкой" в пункте меню, чтобы указать, который из нескольких параметров действует. Например, предположим, что прикладная программа имеет инструментальную панель, которую пользователь может показывать или скрывать при помощи использования команды Toolbar в меню. Когда инструментальная панель скрыта, у пункта меню Toolbar нет отметки "галочкой". Когда пользователь выбирает команду, прикладная программа отмечает "галочкой" пункт меню и показывает инструментальную панель.

Атрибут метки "галочкой " проверяет, отмечен ли пункт меню "галочкой". Вы можете установить атрибут отметки "галочкой " пункта меню при помощи использования функции CheckMenuItem. Вы можете использовать функцию GetMenuState, чтобы установить, отмечен или не отмечен в настоящее время пункт меню "галочкой".

Вместо CheckMenuItem и GetMenuState, Вы можете использовать функции GetMenuItemInfo и SetMenuItemInfo, чтобы извлекать данные и устанавливать наличие отметки "галочкой" в пункте меню.

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

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

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


11.7.6 - Включенные, недоступные и заблокированные пункты меню

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

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

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

Функция EnableMenuItem включает, окрашенный в серый цвет или отключенный пункт меню. Чтобы установить, каким является пункт меню включенным, недоступным или заблокированным, используйте функцию GetMenuItemInfo.

Вместо GetMenuItemInfo, Вы можете использовать также и функцию GetMenuState, чтобы установить включен, недоступен или заблокирован пункт меню.


11.7.7 - Выделенные пункты меню

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


11.8 - Нарисованные пользователем (собственные) пункты меню

Прикладная программа может полностью управлять внешним видом пункта меню при помощи использования нарисованного пользователем (собственного) пункта (owner-drawn item). Нарисованные пользователем пункты требуют, чтобы приложение брало всю ответственность на себя за состояние прорисовки выбора (выделения), "галочки" и снятие отметки "галочкой". Например, если прикладная программа предоставляет меню шрифта, она может прописывать каждый пункт меню при помощи использования соответствующего шрифта; пункт для Латинского шрифта будет прописан латинским, пункт для Курсива будет прописан курсивом и так далее.

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


11.9 - Разделители пунктов меню и переносы строк

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

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

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

Если Вы используете функции AppendMenu, InsertMenu или ModifyMenu, чтобы назначить переносы строк, Вы должны присвоить типовые флажки MF_MENUBREAK или MF_MENUBARBREAK.


11.10 - Доступ к меню с клавиатуры

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


11.10.1 - Стандартный (общепринятый) интерфейс клавиатуры

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

  • Буквенный символ - Выбирает первый пункт меню с заданным символом как клавиша доступа. Если выбранный пункт вызывает меню, меню отображается, а первый пункт выделяется. Иначе, пункт меню выбирается.
  • ALT - Переключает в режим или из режима строки меню.
  • ALT+SPACEBAR - Показывает на экране меню окна.
  • ENTER - Активизирует меню и выбирает его первый пункт, если пункт связан с этим меню. Иначе, это нажатие клавиши выбирает пункт, как будто пользователь отпустил кнопку мыши, в то время когда пункт был выбран.
  • ESC - Выход из режима меню.
  • LEFT ARROW (стрелка влево) - Циклически передвигается к предыдущему пункту меню верхнего уровня. Пункты меню верхнего уровня включают в себя имена меню и меню окна. Если выбранный пункт находится в меню, выбирается предыдущий столбец в меню или предыдущий пункт меню верхнего уровня.
  • RIGHT ARROW (стрелка вправо) - Работает подобно клавише СТРЕЛКА ВЛЕВО, за исключением того, что действует в противоположном направлении. В меню, это нажатие клавиши перемещает вперед на один столбец; когда текущий выбранный пункт находится в крайне правом столбце, выбранным является следующее меню.
  • UP или DOWN ARROWS (стрелки вверх или вниз) - Активизирует меню, когда нажимается на имени меню. Когда нажимается в меню, нажатие клавиши СТРЕЛКА ВВЕРХ выбирает предыдущий пункт; нажатие клавиши СТРЕЛКА ВНИЗ выбирает следующий.


11.10.2 - Клавиши доступа к меню

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

Чтобы создать клавишу доступа для пункта меню, пред любым символом в текстовой строке пункта проставьте амперсанд. Например, текстовая строка "&Move" принуждает Windows подчеркнуть символ "M".


11.10.3 - Быстрые клавиши меню

В дополнение к имеемым клавишам доступа, пункт меню может иметь быструю клавишу, связанную с ним. Быстрая клавиша(сочетание клавиш) отличается от клавиши доступа тем, что меню, чтобы сработать по быстрой клавише, не должно быть активным. К тому же, клавиша доступа всегда связана с пунктом меню, в то время как быстрая клавиша - обычно (но не обязательно) связана с пунктом меню.

Текст, который идентифицирует быструю клавишу, добавляется в текстовую строку пункта меню. Текст клавишной комбинации быстрого вызова появляется справа от названия пункта меню, после наклонной черты влево (обратного слэша) и символа табуляции (\t). Например, "&Close\tAlt+F4" представляет команду Закрыть (Close) с комбинацией клавиш ALT+F4 как быстрой клавиши и с символом "C" как клавишей доступа. Для получения дополнительной информации, см. Ускорители клавиатуры.


11.11 - Создание меню

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


11.12.1 - Ресурсы шаблона меню

Большинство прикладных программ создает меню, используя ресурсы шаблона меню. Шаблон меню (menu template) определяет меню, включая в себя пункты в строке меню и всех меню. За информацией о создании ресурса шаблона меню, см. документацию, включенную в ваши инструментальные средства разработки.

После того, как Вы создадите ресурс шаблона меню и добавите его к исполняемому (.EXE) файлу вашего приложения, Вы можете использовать функцию LoadMenu, чтобы загрузить этот ресурс в память. Эта функция возвращает значение дескриптора меню, который Вы можете затем присваивать окну при помощи использования функции SetMenu.

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


11.12.2 - Шаблон меню в памяти

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

Стандартный шаблон меню состоит из структуры MENUITEMTEMPLATEHEADER, сопровождаемой одной или несколькими структурами MENUITEMTEMPLATE.

Расширенный шаблон меню состоит из структуры MENUEX_TEMPLATE_HEADER, сопровождаемой одной или несколькими структурами MENUEX_TEMPLATE_ITEM.


11.12.3 - Функции создания меню

Используя функции создания меню, Вы можете создавать меню во время выполнения программы или добавлять пункты меню к существующим меню. Вы можете использовать функцию CreateMenu, чтобы создать пустую строку меню и функцию CreatePopupMenu, чтобы создать пустое меню. Чтобы добавлять пункты к меню, используйте функцию InsertMenuItem. Устаревшие функции AppendMenu и InsertMenu все еще поддерживаются, но для новых прикладных программ должна быть использована функция InsertMenuItem.


11.13 - Показ меню на экране

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

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

Устаревшая функция TrackPopupMenu все еще поддерживается, но новые прикладные программы должны использовать функцию TrackPopupMenuEx.


11.14 - Меню класса окна

Вы можете определить заданное по умолчанию меню, называемое меню класса (class menu), когда регистрируете класс окна. Чтобы сделать так, присвойте имя ресурса шаблона меню элементу lpszMenuName структуры WNDCLASS, используемой для регистрации класса.

По умолчанию, каждому окну назначается меню класса для класса окна, так что вам не нужно явно загружать меню и присваивать его каждому окну. Вы можете заменять меню класса, при помощи определения другого дескриптора меню при вызове функции CreateWindowEx. Вы можете также изменить меню окна после того, как оно создано при помощи использования функция SetMenu. Для получения дополнительной информации, см. Классы окна.


11.15 - Разрушение Меню

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


11.16 - Сообщения, используемые меню

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

Когда пользователь активизирует пункт в горизонтальном меню, окно владелец сначала получает сообщение WM_SYSCOMMAND. Это сообщение включает в себя флажок, который указывает, активизировал ли пользователь меню при помощи использования клавиатуры (SC_KEYMENU) или мыши (SC_MOUSEMENU). Для получения дополнительной информации об интерфейсе клавиатуры для меню, см. Доступ к меню через клавиатуру.

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

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

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

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

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


11.17 - Изменения меню

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

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

Устаревшие функции AppendMenu и InsertMenu могут быть также использованы, чтобы добавить пункты меню, но новые прикладные программы должны использовать InsertMenuItem. Функция AppendMenu добавляет в конец пункт меню или подменю; функция InsertMenu вставляет пункт меню в заданной позиции в меню или подменю. Обе функции дают возможность атрибутам пункта меню быть определяемыми, включая в себя в любом случае, включение, блокирование, недоступность, отметку "галочкой или снятие отметки "галочкой" пункта меню.

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

Чтобы извлечь информацию о пункте меню, используйте функцию GetMenuItemInfo. Параметр lpmii указывает на структуру MENUITEMINFO, которая определяет извлекаемые атрибуты и принимает их текущие значения.

Чтобы удалить пункт меню из меню, используйте функцию DeleteMenu или RemoveMenu. Если удаляемый пункт тот, который открывает подменю, DeleteMenu удаляет связанное подменю, сбрасывая дескриптор меню и освобождая память, использованную подменю. Функция RemoveMenu удаляет пункт меню, но если пункт открывает подменю, функция не уничтожает подменю или дескриптор, позволяя подменю многократно использоваться.

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


11.18 - Использование меню

Использование ресурса шаблона меню
Создание вспомогательного (контекстного) меню
Использование точечных рисунков пунктов меню
Создание нарисованных пользователем пунктов меню
Использование пользовательских точечных рисунков "галочки "


11.18.1 - Использование ресурса шаблона меню

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


11.18.1.1 - Расширенный формат шаблона меню

Расширенный формат шаблона меню поддерживает функциональные возможности меню, выполненные для версий Windows 95 и Windows NT 4.0. Подобно ресурсам шаблона меню, использованным с более ранними версиями Windows, расширенные ресурсы шаблона меню имеют тип ресурса RT_MENU. Windows различает два формата ресурса по номеру версии, который является первым элементом заголовка ресурса.

Расширенный шаблон меню состоит из структуры MENUEX_TEMPLATE_HEADER, сопровождаемой еще одной структурой MENUEX_TEMPLATE_ITEM определяющей пункты.


11.18.1.2 - Старый формат шаблона меню

Старый шаблон меню (для версий Windows ранее, чем Windows 95 и Windows NT 4.0) задает меню, но не поддерживает его новые функциональные возможности. Старый ресурс шаблона меню имеет тип ресурса RT_MENU.

Старый шаблон меню состоит из структуры MENUITEMTEMPLATEHEADER, сопровождаемой одним или большим количеством структур MENUITEMTEMPLATE.


11.18.1.3 - Загрузка ресурса шаблона меню

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

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

Чтобы привязать меню к окну, используйте функцию SetMenu, или определите дескриптор меню в параметре hMenu функции CreateWindowEx при создании окна. Другим способом, которым Вы можете привязать меню к окну, является определение шаблона меню, когда Вы регистрируете класс окна; шаблон идентифицирует определяемое меню как меню класса для этого класса окна.

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

Чтобы создать меню класса, включите идентификатор ресурса шаблона меню как член lpszMenuName структуры WNDCLASS, а затем передайте адрес структуры в функцию RegisterClass.


11.18.1.4 - Создание меню класса

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

Ниже следует важная часть заголовочного файла прикладной программы:

// Идентификатор ресурса шаблона меню
#define IDM_MYMENURESOURCE   3

Ниже следует важная часть самого приложения:

HINSTANCE hinst;

int APIENTRY WinMain(hinstance, hPrevInstance, lpCmdLine, nCmdShow)
HINSTANCE hinstance;
HINSTANCE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
{
    MSG msg;		// сообщение
    WNDCLASS wc;		// данные класса окна
    HWND hwnd;		// дескриптор главного окна

    // Создадим класс окна для основного окна.
    // Определим идентификатор ресурса шаблона меню как
    // элемент lpszMenuName структуры WNDCLASS, чтобы
    // создать меню класса.

    wc.style = 0;
    wc.lpfnWndProc = (WNDPROC) MainWndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hinstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName =  MAKEINTRESOURCE(IDM_MYMENURESOURCE);
    wc.lpszClassName = "MainWClass";

    if (!RegisterClass(&wc))
        return FALSE;

    hinst = hinstance;

    // Создадим основное окно. Установим параметр
    // hmenu в значение ПУСТО (NULL) так, чтобы Windows
    // использовал меню класса для окна.

    hwnd = CreateWindow("MainWClass", "Sample Application",
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hinstance,
        NULL);

    if (hwnd == NULL)
        return FALSE;

    // Сделаем окно видимым и передадим сообщение
    // WM_PAINT в оконную процедуру.

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // Запустим главный цикл сообщений.

    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
    UNREFERENCED_PARAMETER(hPrevInstance);
}

LRESULT APIENTRY MainWndProc(hwnd, uMsg, wParam, lParam)
HWND hwnd;
UINT uMsg;
WPARAM wParam;
LPARAM lParam;
{
    switch (uMsg) {
        .
        . // Обработка других сообщений окна.
        .

        case WM_COMMAND:
            // Проверка идентификатора командного пункта меню.
            switch(LOWORD(wParam)) {
                case IDM_FI_OPEN:
                    DoFileOpen();	// определяется программой
                    break;
                case IDM_FI_CLOSE:
                    DoFileClose();	// определяется программой
                    break;
                .
                . // Обработка других команд меню.
                .
                default:
                    break;
            }
            return 0;
        .
        . // Обработка других сообщений окна.
        .

        default:
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return NULL;
}


11.18.2 - Создание вспомогательного (контекстного) меню

Чтобы использовать контекстное меню в прикладной программе, передайте ее дескриптор в функцию TrackPopupMenuEx. Приложение обычно вызывает TrackPopupMenuEx в оконной процедуре в ответ на сгенерированное пользователем сообщение, типа WM_LBUTTONDOWN или WM_KEYDOWN.

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

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

Вы можете определить позицию контекстного меню, предоставляя x- и y-координаты вместе с флажком TPM_CENTERALIGN, TPM_LEFTALIGN или TPM_RIGHTALIGN. Флажок определяет позицию контекстного меню относительно x- и y-координат.

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


11.18.2.1 - Обработка сообщения WM_CONTEXTMENU

Сообщение WM_CONTEXTMENU создается тогда, когда оконная процедура прикладной программы посылает функции DefWindowProc сообщение WM_RBUTTONUP или WM_NCRBUTTONUP. Приложение может обработать это сообщение, чтобы показать на экране контекстное меню, в соответствующей конкретной части экрана. Если прикладная программа не показывает на экране контекстное меню, она должна передать это сообщение в DefWindowProc для обработки по умолчанию.

Ниже следует пример обработки сообщения WM_CONTEXTMENU, как оно может фигурировать в оконной процедуре прикладной программы. Младшие и старшие слова параметра lParam определяют экранную систему координат мыши, когда отпускается правая кнопка мыши. Определяемая программой функция OnContextMenu возвращает значение ИСТИНА (TRUE), если она показывает на экране контекстное меню или ЛОЖЬ (FALSE) если она этого не делает.

case WM_CONTEXTMENU:
    if (!OnContextMenu(hwnd, LOWORD(lParam), HIWORD(lParam)))
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    break;

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

BOOL WINAPI OnContextMenu(HWND hwnd, int x, int y)
{
    RECT rc;		// рабочая область окна
    POINT pt = { x, y };	// место, где был щелчок мышью
    // Получим ограничительный прямоугольник рабочей области.
    GetClientRect(hwnd, &rc);
    // Преобразуем позицию мыши в координаты рабочей области.
    ScreenToClient(hwnd, &pt);
    // Если позиция находится в рабочей области,
    // показать контекстное меню.
    if (PtInRect(&rc, pt)) {
        ClientToScreen(hwnd, &pt);
        DisplayContextMenu(hwnd, pt);
        return TRUE;
    }
    // Возвратить значение ЛОЖЬ (FALSE), если
    // не отображается никакого меню
    return FALSE;
}


11.18.2.2 - Создание контекстного меню Атрибуты Шрифта (Font-Attributes)

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

Здесь шаблон меню для контекстного меню, который дается в файле определения ресурса прикладной программы.

PopupMenu MENU
BEGIN
  POPUP "Dummy Popup"
    BEGIN
      POPUP "Fonts"
        BEGIN
          MENUITEM "Courier",     IDM_FONT_COURIER
          MENUITEM "Times Roman", IDM_FONT_TMSRMN
          MENUITEM "Swiss",       IDM_FONT_SWISS
          MENUITEM "Helvetica",   IDM_FONT_HELV
          MENUITEM "Old English", IDM_FONT_OLDENG
        END
      POPUP "Sizes"
        BEGIN
          MENUITEM "7",  IDM_SIZE_7
          MENUITEM "8",  IDM_SIZE_8
          MENUITEM "9",  IDM_SIZE_9
          MENUITEM "10", IDM_SIZE_10
          MENUITEM "11", IDM_SIZE_11
          MENUITEM "12", IDM_SIZE_12
          MENUITEM "14", IDM_SIZE_14
        END
      POPUP "Styles"
        BEGIN
          MENUITEM "Bold",        IDM_STYLE_BOLD
          MENUITEM "Italic",      IDM_STYLE_ITALIC
          MENUITEM "Strike Out",  IDM_STYLE_SO
          MENUITEM "Superscript", IDM_STYLE_SUPER
          MENUITEM "Subscript",   IDM_STYLE_SUB
        END
    END
 END

Следующий пример дает оконную процедуру и обеспечивающие функции, использованные, чтобы создавать и показывать на экране контекстное меню.

LRESULT APIENTRY MenuWndProc(hwnd, uMsg, wParam, lParam)
HWND hwnd;
UINT uMsg;
WPARAM wParam;
LPARAM lParam;
{
    RECT rc;	// рабочая область
    POINT pt;	// место щелчка мыши
    switch (uMsg) {
        case WM_LBUTTONDOWN:
            // Получим ограничительный прямоугольник рабочей области.
            GetClientRect(hwnd, (LPRECT) &rc);
            // Получим рабочие координаты щелчка мыши.
            pt.x = LOWORD(lParam);
            pt.y = HIWORD(lParam);
            // Если щелчок клавишей мыши произошел
            // внутри рабочей области, выполните определяемую
            // программой функцию, которая показывает на
            // экране контекстное меню.
            if (PtInRect((LPRECT) &rc, pt))
                HandlePopupMenu(hwnd, pt);
            break;
        .
        . // Обработка других сообщений окна.
        .
        default:
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return NULL;
}

VOID APIENTRY HandlePopupMenu(hwnd, pt)
HWND hwnd;
POINT pt;
{
    HMENU hmenu;	// шаблон меню
    HMENU hmenuTrackPopup;	// контекстное меню
    // Загрузите шаблон меню, содержащий контекстное меню из
    // ресурсов прикладной программы.

    hmenu = LoadMenu(hinst, "PopupMenu");
    if (hmenu == NULL) return;

    // Получим первое контекстное меню в шаблоне меню. Это -
    // то меню, которое показывает TrackPopupMenu.

    hmenuTrackPopup = GetSubMenu(hmenu, 0);

    // TrackPopup использует экранную систему координат, чтобы преобразовать
    // координаты щелчка клавишей мыши в экранную систему координат.

    ClientToScreen(hwnd, (LPPOINT) &pt);

    // Прорисовываем и устанавливаем контекстное меню.

    TrackPopupMenu(hmenuTrackPopup, TPM_LEFTALIGN | TPM_LEFTBUTTON,
        pt.x, pt.y, 0, hwnd, NULL);

    // Разрушаем меню.

    DestroyMenu(hmenu);
}


11.18.2.3 - Отображение на экране контекстного меню

Функция, приведенная в следующем примере, показывает на экране контекстное меню.

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

VOID APIENTRY DisplayContextMenu(HWND hwnd, POINT pt)
{
    HMENU hmenu;		// меню верхнего уровня
    HMENU hmenuTrackPopup;	// контекстное меню>

    // Загрузим ресурс меню.

    if ((hmenu = LoadMenu(hinst, "ShortcutExample")) == NULL)
        return;

    // TrackPopupMenu не может показать на экране
    // строку меню, так как получен дескриптор
    // первого контекстного меню

    hmenuTrackPopup = GetSubMenu(hmenu, 0);

    // Покажем контекстное меню. Отследим правую кнопку мыши.

    TrackPopupMenu(hmenuTrackPopup,
        TPM_LEFTALIGN | TPM_RIGHTBUTTON,
        pt.x, pt.y, 0, hwnd, NULL);

    // Разрушим меню.
    DestroyMenu(hmenu);
}


11.18.3 - Использование в пунктах меню точечных рисунков (значков)

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

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


11.18.3.1 - Установка флажка типа значка

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

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

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


11.18.3.2 - Создание точечного рисунка (значка)

Когда Вы устанавливаете флажок типа MFT_BITMAP или MF_BITMAP для пункта меню, Вы должны также определить и дескриптор точечного рисунка (значка), который Windows должен отобразить для пункта меню. Вы можете представить значок как растровый ресурс или создавать точечный рисунок во время выполнения программы. Если Вы используете растровый ресурс, Вы можете использовать функцию LoadBitmap, чтобы загрузить значок и получить его дескриптор.

Чтобы создать значок во время выполнения программы, используйте функции графического интерфейса устройства (GDI). GDI предоставляет несколько способов, чтобы создать значок во время выполнения программы, но разработчики обычно используют следующий метод:

  1. Использовать функцию CreateCompatibleDC, чтобы создать контекст устройства, совместимый с контекстом устройства, использованным основным окном прикладной программы.
  2. Использовать функцию CreateCompatibleBitmap, чтобы создать значок, совместимый с основным окном прикладной программы или использовать функцию CreateBitmap, чтобы создать одноцветный значок.
  3. Использовать функцию SelectObject, чтобы выбрать значок в совместимом контексте устройства.
  4. Использовать рисующие функции GDI, типа Ellipse (Эллипс) и LineTo (Линия), чтобы нарисовать изображение в значок.

Для получения дополнительной информации, см. статью Точечные рисунки.


11.18.3.3 - Добавление меню Линии и Диаграммы

Нижеследующий пример кода показывает, как создать меню, которое содержит значки пунктов меню. Он создает два меню. Первое - меню Chart (Диаграммы), которое содержит три значка пунктов меню: круговая диаграмма, линейная диаграмма и гистограмма. Пример показывает, как загрузить эти значки из файла ресурса прикладной программы, а затем использовать функции CreatePopupMenu и AppendMenu, чтобы создать меню и пункты меню.

Второе меню - меню Lines (Линии). Оно содержит значки, показывая типы линий, предоставляемые предопределенным пером в Windows. Значки типа линий созданы во время выполнения программы при помощи использования функций GDI.

Здесь определения растровых ресурсов в файле определения ресурса прикладной программы.

PIE BITMAP pie.bmp
LINE BITMAP line.bmp
BAR BITMAP bar.bmp

Здесь находятся необходимые части заголовочного файла прикладной программы.

// Идентификаторы пункта меню

#define IDM_SOLID       PS_SOLID
#define IDM_DASH        PS_DASH
#define IDM_DASHDOT     PS_DASHDOT
#define IDM_DASHDOTDOT  PS_DASHDOTDOT

#define IDM_PIE  1
#define IDM_LINE 2
#define IDM_BAR  3

// Флажки типов линий

#define SOLID       0
#define DOT         1
#define DASH        2
#define DASHDOT     3
#define DASHDOTDOT  4

// Счет перьев

#define CPENS 5

// Флажки типа диаграммы

#define PIE  1

#define LINE 2
#define BAR  3

// Прототипы функций

LRESULT APIENTRY MainWndProc(HWND, UINT, WPARAM, LPARAM);
VOID MakeChartMenu(HWND);
VOID MakeLineMenu(HWND, HPEN, HBITMAP);

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

LRESULT APIENTRY MainWndProc(hwnd, uMsg, wParam, lParam)
HWND hwnd;
UINT uMsg;
WPARAM wParam;
LPARAM lParam;
{
    static HPEN hpen[CPENS];
    static HBITMAP hbmp[CPENS];
    int i;

    switch (uMsg) {
        case WM_CREATE:

            // Создадим меню Chart и Line
            MakeChartMenu(hwnd);
            MakeLineMenu(hwnd, hpen, hbmp);
            return 0;

            .
            . // Обработаем другие сообщения окна.
            .

        case WM_DESTROY:

            for (i = 0; i < CPENS; i++) {
                DeleteObject(hbmp[i]);
                DeleteObject(hpen[i]);
            }

            PostQuitMessage(0);
            break;

        default:
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return NULL;
}

VOID MakeChartMenu(hwnd)
HWND hwnd;		// дескриптор окна владельца
{
    HBITMAP hbmpPie;		// дескриптор значка круговой диаграммы
    HBITMAP hbmpLine;		// дескриптор значка линейной диаграммы
    HBITMAP hbmpBar;		// дескриптор значка гистограммы
    HMENU hmenuMain;		// дескриптор главного меню
    HMENU hmenuChart;		// дескриптор меню Chart (диаграммы)

    // Загрузим значки круговой, линейной диаграммы и
    // гистограммы из файла определения ресурса.

    hbmpPie = LoadBitmap(hinst, MAKEINTRESOURCE(PIE));
    hbmpLine = LoadBitmap(hinst, MAKEINTRESOURCE(LINE));
    hbmpBar = LoadBitmap(hinst, MAKEINTRESOURCE(BAR));

    // Создадим меню Chart и добавим его к строке меню.
    // Добавим в конец к меню Диаграммы пункты меню Круговая,
    // Линейная и Гистограмма.

    hmenuMain = GetMenu(hwnd);
    hmenuChart = CreatePopupMenu();
    AppendMenu(hmenuMain, MF_STRING | MF_POPUP, (UINT) hmenuChart,"Chart");
    AppendMenu(hmenuChart, MF_BITMAP, IDM_PIE, (LPCTSTR) hbmpPie);
    AppendMenu(hmenuChart, MF_BITMAP, IDM_LINE, (LPCTSTR) hbmpLine);
    AppendMenu(hmenuChart, MF_BITMAP, IDM_BAR, (LPCTSTR) hbmpBar);

return;
}

VOID MakeLineMenu(hwnd, phpen, phbmp)
HWND hwnd;
HPEN *phpen;
HBITMAP *phbmp;
{
    HMENU hmenuLines;		// дескриптор меню Линии
    HMENU hmenu;		// дескриптор главного меню
    COLORREF crMenuClr;	// цвет фона пункта меню
    HBRUSH hbrBackground;	// дескриптор кисти фона
    HBRUSH hbrOld;		// дескриптор предыдущей кисти
    LONG lCheckXY;		// размеры значка-метки типа «галочки»
    WORD wLineX;		// ширина значка линии
    WORD wLineY;		// высота значка линии
    HDC hdcMain;		// дескриптор контекста устройства (DC) окна
    HDC hdcLines;		// дескриптор совместимого DC
    HBITMAP hbmpOld;		// дескриптор предыдущего значка
    int i;			// цикл счетчика

    // Создадим меню Lines. Добавьте его к строке меню

    hmenu = GetMenu(hwnd);

    hmenuLines = CreatePopupMenu();
    AppendMenu(hmenu, MF_STRING | MF_POPUP, (UINT) hmenuLines, "&Lines");

    // Создадим кисть для цвета фона пункта меню.

    crMenuClr = GetSysColor(COLOR_MENU);
    hbrBackground = CreateSolidBrush(crMenuClr);

    // Создадим совместимый контекст устройства значков линий,
    // а затем выберем фоновую кисть в нем.

    hdcMain = GetDC(hwnd);
    hdcLines = CreateCompatibleDC(hdcMain);

    hbrOld = SelectObject(hdcLines, hbrBackground);

    // Получим габариты значка "галочки ". Ширина
    // значка линии будет в пять раз шире значка "галочки".

    lCheckXY = GetMenuCheckMarkDimensions();
    wLineX = LOWORD(lCheckXY) * (WORD) 5;
    wLineY = HIWORD(lCheckXY);

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

    for (i = 0; i < CPENS; i++) {
        phbmp[i] = CreateCompatibleBitmap(hdcMain, wLineX, wLineY);
        if (i == 0)
            hbmpOld = SelectObject(hdcLines, phbmp[i]);
        else
            SelectObject(hdcLines, phbmp[i]);
        ExtFloodFill(hdcLines, 0, 0, crMenuClr, FLOODFILLBORDER);
    }

    // Создаем перья.

    phpen[0] = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
    phpen[1] = CreatePen(PS_DOT, 1, RGB(0, 0, 0));
    phpen[2] = CreatePen(PS_DASH, 1, RGB(0, 0, 0));
    phpen[3] = CreatePen(PS_DASHDOT, 1, RGB(0, 0, 0));
    phpen[4] = CreatePen(PS_DASHDOTDOT, 1, RGB(0, 0, 0));

    // Выберем перо и значок в совместимом контексте устройства,
    // проведем линию в значке, а затем добавим в конец значок
    // как пункт в меню Lines.

    for (i = 0; i < CPENS; i++) {
        SelectObject(hdcLines, phbmp[i]);
        SelectObject(hdcLines, phpen[i]);
        MoveToEx(hdcLines, 0, wLineY / 2, NULL);
        LineTo(hdcLines, wLineX, wLineY / 2);

        AppendMenu(hmenuLines, MF_BITMAP, i + 1, (LPCTSTR) phbmp[i]);
    }

    // Освободим контекст устройства основного окна, и уничтожим
    // совместимый контекст устройства. А также, уничтожим кисть фона.

    ReleaseDC(hwnd, hdcMain);
    SelectObject(hdcLines, hbrOld);
    DeleteObject(hbrBackground);
    SelectObject(hdcLines, hbmpOld);
    DeleteDC(hdcLines);

    return;
}


11.18.3.4 - Пример значков пунктов меню

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

Первое меню содержит пункты меню, которые показывают каждую из трех типов диаграмм: круговую, линейную и гистограмму. Значки для этих пунктов меню определены как ресурсы и загружаются при помощи использования функции LoadBitmap. С этим меню, в горизонтальном меню, связано имя меню "Chart" (Диаграммы).

Второе меню содержит пункты меню, которые показывают каждый из пяти типов линии, использованных с функцией CreatePen: PS_SOLID, PS_DASH, PS_DOT, PS_DASHDOT и PS_DASHDOTDOT. Прикладная программа создает значки для этих пунктов меню во время выполнения программы, используя, рисующие функции GDI. С этим меню, в горизонтальном меню, связано имя меню "Lines" (Линии).

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

Ниже следуют необходимые части заголовочного файла приложения.

// Идентификаторы пунктов меню

#define IDM_PIE		1
#define IDM_LINE		2
#define IDM_BAR		3
#define IDM_SOLID		4
#define IDM_DASH		5
#define IDM_DASHDOT	6
#define IDM_DASHDOTDOT	7

// Число пунктов в меню Chart и Lines

#define C_LINES		5
#define C_CHARTS		3

// Идентификаторы ресурса значков

#define IDB_PIE		1
#define IDB_LINE		2
#define IDB_BAR		3

// Размеры значков линий

#define CX_LINEBMP		40
#define CY_LINEBMP		10

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

LRESULT CALLBACK MainWindowProc(
    HWND hwnd,
    UINT uMsg,
    WPARAM wParam,
    LPARAM lParam
    )
{
    static HBITMAP aHbmLines[C_LINES];
    static HBITMAP aHbmChart[C_CHARTS];
    int i;

    switch (uMsg) {

        case WM_CREATE:

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

            LoadChartBitmaps(aHbmChart);
            CreateLineBitmaps(aHbmLines);

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

            AddBitmapMenu(
                    hwnd,		// строка меню окна владельца
                    "&Chart",		//текст имени меню в строке меню
                    IDM_PIE,		// ID первого пункта меню
                    aHbmChart,	// массив дескрипторов значков
                    C_CHARTS		// число пунктов меню
                    );
            AddBitmapMenu(hwnd, "&Lines", IDM_SOLID,
                    aHbmLines, C_LINES);
            break;

        case WM_DESTROY:
            for (i = 0; i < C_LINES; i++)
                DeleteObject(aHbmLines[i]);
            for (i = 0; i < C_CHARTS; i++)
                DeleteObject(aHbmChart[i]);
            PostQuitMessage(0);
            break;

        .
        . // здесь обрабатываются дополнительные сообщения.
        .

        default:
            return (DefWindowProc(hwnd, uMsg, wParam, lParam));
    }
    return 0;
}

Определяемая программой функция LoadChartBitmaps загружает ресурсы значков для меню диаграмм путем вызова функция LoadBitmap, как ниже указано.

VOID WINAPI LoadChartBitmaps(HBITMAP *paHbm)
{
    paHbm[0] = LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_PIE));
    paHbm[1] = LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_LINE));
    paHbm[2] = LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_BAR));
}

Определяемая программой функция CreateLineBitmaps создает значки для меню Lines при помощи использования, рисующих функций GDI. Функция создает контекст устройства в памяти (DC) с теми же самыми свойствами, что и DC главного окна программы. Для каждого типа линии, функция создает значок, выбирает его в DC в памяти и рисует в нем.

VOID WINAPI CreateLineBitmaps(HBITMAP *paHbm)
{
    HWND hwndDesktop = GetDesktopWindow();
    HDC hdcDesktop = GetDC(hwndDesktop);
    HDC hdcMem = CreateCompatibleDC(hdcDesktop);
    COLORREF clrMenu = GetSysColor(COLOR_MENU);
    HBRUSH hbrOld;
    HPEN hpenOld;
    HBITMAP hbmOld;
    int fnDrawMode;
    int i;

    // Создайте кисть, чтобы использовать цвет фона
    // меню, и выберите его в DC в памяти.
    hbrOld = SelectObject(hdcMem, CreateSolidBrush(clrMenu));

    // Создайте значки. Выберите каждый из них в DC
    // в памяти, которые были созданы и используйте их.

         for (i = 0; i < C_LINES; i++) {
        // Создадим точечный рисунок (значок) и выберем его в DC.

        paHbm[i] = CreateCompatibleBitmap(hdcDesktop,
                CX_LINEBMP, CY_LINEBMP);
        hbmOld = SelectObject(hdcMem, paHbm[i]);

        // Заполним фон, используя кисть.

        PatBlt(hdcMem, 0, 0, CX_LINEBMP, CY_LINEBMP, PATCOPY);

        // Создадим перо и выберем его в DC.

        hpenOld = SelectObject(hdcMem,
                CreatePen(PS_SOLID + i, 1, RGB(0, 0, 0)));

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

        fnDrawMode = SetROP2(hdcMem, R2_MASKPEN);
        MoveToEx(hdcMem, 0, CY_LINEBMP / 2, NULL);
        LineTo(hdcMem, CX_LINEBMP, CY_LINEBMP / 2);
        SetROP2(hdcMem, fnDrawMode);

        // Уничтожим перо и выберем старое перо и значок.

        DeleteObject(SelectObject(hdcMem, hpenOld));
        SelectObject(hdcMem, hbmOld);
    }
    // Уничтожим кисть и выберем первоначальную кисть.
    DeleteObject(SelectObject(hdcMem, hbrOld));
    // Очистим память, отведенную для DC и освободим DC рабочего стола.
    DeleteDC(hdcMem);
    ReleaseDC(hwndDesktop, hdcDesktop);
}

Определяемая программой функция AddBitmapMenu создает меню и добавляет заданное число значков меню к его пунктам. Затем она добавляет соответствующее название меню к строке меню определяемого окна.

VOID WINAPI AddBitmapMenu(
        HWND hwnd,	// окно, которое владеет строкой меню
        LPSTR lpszText,	// текст имени меню на строке меню
        UINT uID,		// ID первого значка пункта меню
        HBITMAP *paHbm,	// значки для пунктов меню
        int cItems)	// число значков пунктов меню
{
    HMENU hmenuBar = GetMenu(hwnd);
    HMENU hmenuPopup = CreatePopupMenu();
    MENUITEMINFO mii;
    int i;

    // Добавляем значки пунктов меню к меню.

    for (i = 0; i < cItems; i++) {
        mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_DATA;
        mii.fType = MFT_BITMAP;
        mii.wID = uID + i;
        mii.dwTypeData = (LPSTR) (paHbm[i]);
        InsertMenuItem(hmenuPopup, i, TRUE, &mii);
    }

    // Добавляем имя меню в строку меню.

    mii.fMask = MIIM_TYPE | MIIM_DATA | MIIM_SUBMENU;
    mii.fType = MFT_STRING;
    mii.hSubMenu = hmenuPopup;
    mii.dwTypeData = lpszText;
    InsertMenuItem(hmenuBar,
        GetMenuItemCount(hmenuBar), TRUE, &mii);
}


11.18.4 - Создание нарисованных пользователем пунктов меню

Если Вы нуждаетесь в полном контроле над внешним видом пункта меню, Вы можете использовать в вашей прикладной программе нарисованный пользователем пункт меню. Этот раздел описывает шаги, которые приведут к созданию и использованию нарисованного пользователем пункта меню.


11.18.4.1 - Установка флажков при рисовании пользователем пунктов меню

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

Вы можете использовать функцию InsertMenuItem или SetMenuItemInfo, чтобы определить нарисованный пользователем пункт меню. Используйте InsertMenuItem, чтобы вставить новый пункт меню в заданной позиции в строке меню или меню. Используйте SetMenuItemInfo, чтобы изменить состав меню.

При вызове этих двух функций, Вы должны определить адрес структуры MENUITEMINFO, которая описывает свойства нового пункта меню или свойства, которые Вы желаете изменить для существующего пункта меню. Чтобы сделать пункт меню, пунктом нарисованным пользователем, определите значение MIIM_TYPE для члена fMask и значение MFT_OWNERDRAW для члена fType структуры.

Устанавливая соответствующие члены структуры MENUITEMINFO, Вы можете связывать определяемое программой значение, которое называется данными пункта (item data), с каждым пунктом меню. Поступая таким образом, определите значение MIIM_DATA для члена fMask и определяемого программой значения для члена dwItemData структуры.

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

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

Когда Вы вызываете любую из этих трех функций, Вы можете передавать 32-разрядное значение как параметр lpNewItem. Это значение может представлять любую информацию, которая является значимой для вашей прикладной программы, и она будет доступна вашему приложению, когда пункт должен отобразиться. Например, значение могло бы содержать указатель на структуру; структура, в свою очередь, могла бы содержать текстовую строку и дескриптор логического шрифта, который ваша прикладная программа будет использовать, чтобы рисовать строку.


11.18.4.2 - Нарисованные пользователем меню и сообщение WM_MEASUREITEM

Прежде, чем Windows покажет на экране нарисованный пользователем пункт меню впервые, она передает сообщение WM_MEASUREITEM оконной процедуре окна, которое владеет пунктами меню. Это сообщение содержит указатель на структуру MEASUREITEMSTRUCT, которая идентифицирует пункт и содержит данные пункта, которые прикладная программа, возможно, присвоила ему. Оконная процедура должна заполнить члены itemWidth и itemHeight структуры перед возвращением из обработки сообщения. Windows использует информацию в этих элементах при создании ограничительного прямоугольника, в котором прикладная программа рисует пункт меню. К тому же она использует эту информацию, чтобы определить, когда пользователь выбирает пункт.


11.18.4.3 - Нарисованные пользователем меню и сообщение WM_DRAWITEM

Всякий раз, когда пункт должен быть прорисован (например, когда он первоначально отображается или когда пользователь выбирается его), Windows отправляет сообщение WM_DRAWITEM оконной процедуре окна владельца меню. Это сообщение содержит указатель на структуру DRAWITEMSTRUCT содержащую информацию о пункте, включая данные о пункте, которые прикладная программа, возможно, присвоила ему. Кроме того, DRAWITEMSTRUCT содержит флажки, которые обозначают состояние пункта (типа того, является ли он недоступным или выбираемым с отметкой галочкой), а также ограничительный прямоугольник и контекст устройства, которые прикладная программа использует, чтобы рисовать пункт.

Прикладная программа должна делать следующее при обработке сообщения WM_DRAWITEM:

  1. Установить тип рисунка, который является необходимым. Чтобы сделать это, проверьте член itemAction структуры DRAWITEMSTRUCT.
  2. Нарисовать соответствующий пункт меню, используя ограничительный прямоугольник и контекст устройства, полученный из структуры DRAWITEMSTRUCT. Прикладная программа должна рисовать только внутри ограничительного прямоугольника. По причинам производительности, Windows не обрезает части изображения, которые прорисованы снаружи прямоугольника.
  3. Восстановить все объекты GDI, выбранные для пунктов меню в контексте устройства.

Если пользователь выбирает пункт меню, Windows устанавливает член itemAction структуры DRAWITEMSTRUCT в значение ODA_SELECT и устанавливает значение ODS_SELECTED в элементе itemState. Это - команда вызова подпрограммы приложения, которая перерисует пункт меню, чтобы указать, что он выбран.


11.18.4.4 - Настройка шрифтов для текстовых строк пункта меню

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

Здесь меню, заданное в файле определения ресурса. Обратите внимание, что строки для пунктов меню Regular (Обычный), Bold (Полужирный), Italic (Курсив) и Underline (Подчеркнутый) назначены во время выполнения программы, так что их строки пусты в файле определения ресурса.

MainMenu MENU
BEGIN
    POPUP   "&Character"
    BEGIN
        MENUITEM    "",    IDM_REGULAR
        MENUITEM SEPARATOR
        MENUITEM    "",    IDM_BOLD
        MENUITEM    "",    IDM_ITALIC
        MENUITEM    "",    IDM_ULINE
    END
END

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

Установить флажок MF_OWNERDRAW для пунктов меню.

Установить строки текста для пунктов меню.

Получить дескрипторы шрифтов, использованных для прорисовки этих пунктов.

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

Дескрипторы текстовых строк и шрифта сохраняются в массиве определяемых программой структур MYITEM. Определяемая программой функция GetAFont создает шрифт, который соответствует атрибутам данного шрифта и возвращает значение дескриптора шрифта. Дескрипторы разрушаются в ходе обработки сообщения WM_DESTROY.

В ходе обработки сообщения WM_MEASUREITEM, пример получает ширину и высоту строки пункта меню и копирует эти значения в структуру MEASUREITEMSTRUCT. Windows использует значения ширины и высоты, чтобы вычислить размер меню.

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

LRESULT APIENTRY MainWndProc(hwnd, uMsg, wParam, lParam)
HWND hwnd;
UINT uMsg;
WPARAM wParam;
LPARAM lParam;
{

    typedef struct _MYITEM {
        HFONT hfont;
        LPSTR psz;
    } MYITEM;				// структура для шрифта и строки пункта

    MYITEM *pmyitem;			// указатель на шрифт и строку пункта
    static MYITEM myitem[CITEMS];	// массив MYITEMS
    static HMENU hmenu;		// дескриптор главного меню
    static COLORREF crSelText;		// цвет текста выбранного пункта
    static COLORREF crSelBkgnd;		// цвет фона выбранного пункта
    COLORREF crText;			// цвет текста невыбранного пункта
    COLORREF crBkgnd;			// цвет фона невыбранного пункта
    LPMEASUREITEMSTRUCT lpmis;		// указывает на данные пункта
    LPDRAWITEMSTRUCT lpdis;		// указывает на данные для прорисовки пункта
    HDC hdc;				// дескриптор экранного DC
    SIZE size;			// протяженность текста пункта меню
    DWORD dwCheckXY;			// размеры метки «галочка»
    WORD wCheckX;			// ширина метки «галочка»
    int nTextX;			// ширина пункта меню
    int nTextY;			// высота пункта меню
    int i;				// цикл счета
    HFONT hfontOld;			// дескриптор старого шрифта
    BOOL fSelected = FALSE;		// флажок выбора пункта меню

    switch (uMsg) {
        case WM_CREATE:

            // Изменим пункты меню Regular (Обычный), Bold (Полужирный), Italic
            // (Курсив) и Underline (Подчеркнутый), чтобы делать их нарисованными
            // пользователем пунктами. Свяжем структуру MYITEM с каждым пунктом,
            // которые содержат строку и шрифт, чтобы обработать каждый пункт.

            hmenu = GetMenu(hwnd);
            ModifyMenu(hmenu, IDM_REGULAR, MF_BYCOMMAND |
                MF_CHECKED | MF_OWNERDRAW, IDM_REGULAR,
                (LPTSTR) &myitem[REGULAR]);
            ModifyMenu(hmenu, IDM_BOLD, MF_BYCOMMAND |
                MF_OWNERDRAW, IDM_BOLD, (LPTSTR) &myitem[BOLD]);
            ModifyMenu(hmenu, IDM_ITALIC, MF_BYCOMMAND |
                MF_OWNERDRAW, IDM_ITALIC,
                (LPTSTR) &myitem[ITALIC]);
            ModifyMenu(hmenu, IDM_ULINE, MF_BYCOMMAND |
                MF_OWNERDRAW, IDM_ULINE,(LPTSTR)&myitem[ULINE]);

             // Извлечем дескриптор шрифта каждого пункта и скопируем их в
            // элемент hfont структуры MYITEM каждого пункта.
            // А также, скопируем в структуры строку каждого пункта
            myitem[REGULAR].hfont = GetAFont(REGULAR);
            myitem[REGULAR].psz = "Regular";
            myitem[BOLD].hfont = GetAFont(BOLD);
            myitem[BOLD].psz = "Bold";
            myitem[ITALIC].hfont = GetAFont(ITALIC);
            myitem[ITALIC].psz = "Italic";
            myitem[ULINE].hfont = GetAFont(ULINE);
            myitem[ULINE].psz = "Underline";

            // Извлечем текст и цвет фона выбранного текста меню.

            crSelText = GetSysColor(COLOR_HIGHLIGHTTEXT);
            crSelBkgnd = GetSysColor(COLOR_HIGHLIGHT);

            return 0;

        case WM_MEASUREITEM:

            // Извлечем контекст устройства главного окна.

            hdc = GetDC(hwnd);

            // Извлечем указатели на пункты меню в
            // структурах MEASUREITEMSTRUCT и MYITEM.

            lpmis = (LPMEASUREITEMSTRUCT) lParam;
            pmyitem = (MYITEM *) lpmis->itemData;

            // Выберем шрифт, связанный пунктом в
            // контексте устройства главного окна.

            hfontOld = SelectObject(hdc, pmyitem->hfont);

            // Извлечем ширину и высоту строки пункта,
            // а затем скопируем их в элементы itemWidth
            // и itemHeight  структуры MEASUREITEMSTRUCT.

            GetTextExtentPoint32(hdc, pmyitem->psz,
            lstrlen(pmyitem->psz), &size);
            lpmis->itemWidth = size.cx;
            lpmis->itemHeight = size.cy;

            // В контексте устройства обратно выберем старый
            // шрифт, и затем освободим контекст устройства.

            SelectObject(hdc, hfontOld);
            ReleaseDC(hwnd, hdc);

            return TRUE;

            break;

        case WM_DRAWITEM:

            // Получим указатели на пункты меню в структурах
            // DRAWITEMSTRUCT и MYITEM.

            lpdis = (LPDRAWITEMSTRUCT) lParam;
            pmyitem = (MYITEM *) lpdis->itemData;

            // Если пользователь выбрал пункт, используйте выбранный
            // текст и цвет фона для отображения пункта.

            if (lpdis->itemState & ODS_SELECTED) {
                crText = SetTextColor(lpdis->hDC, crSelText);
                crBkgnd = SetBkColor(lpdis->hDC, crSelBkgnd);
                fSelected = TRUE;
            }

            // Не забудьте оставить пространство в пункте
            // меню для значка "галочки ". Извлеките ширину значка
            // и добавьте ее к ширине пункта меню.

            dwCheckXY = GetMenuCheckMarkDimensions();

            wCheckX = LOWORD(dwCheckXY);
            nTextX = wCheckX + lpdis->rcItem.left;
            nTextY = lpdis->rcItem.top;

            // Выберите шрифт, связанный с пунктом в контексте
            // устройства пункта, а затем нарисуйте строку.

            hfontOld = SelectObject(lpdis->hDC, pmyitem->hfont);
            ExtTextOut(lpdis->hDC, nTextX, nTextY, ETO_OPAQUE,
                &lpdis->rcItem, pmyitem->psz,
                lstrlen(pmyitem->psz), NULL);

            // Выберите обратно предыдущий шрифт в контексте устройства.

            SelectObject(lpdis->hDC, hfontOld);

            // Возвратите текст и цвета фона в
            // их нормальное состояние (не выбранное).

            if (fSelected) {
                SetTextColor(lpdis->hDC, crText);
                SetBkColor(lpdis->hDC, crBkgnd);
            }

            return TRUE;

        .
        . // Обработка других сообщений.
        .

        case WM_DESTROY:

            // Уничтожим дескрипторы шрифта пунктов меню.

            for (i = 0; i < CITEMS; i++)
                DeleteObject(myitem[i].hfont);

            PostQuitMessage(0);
            break;

        default:
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return NULL;
}

HFONT GetAFont(fnFont)
int fnFont;			 // флажки атрибутов шрифта
{
    static LOGFONT lf;  // структура для информации о шрифте

    // Получим дескриптор для моноширинного шрифта ANSI, а информацию о шрифте скопируем
    // в структуру LOGFONT.

    GetObject(GetStockObject(ANSI_FIXED_FONT), sizeof(LOGFONT), &lf);

    // Установим соответствующие атрибуты шрифта.

    if (fnFont == BOLD)
        lf.lfWeight = FW_BOLD;
    else
        lf.lfWeight = FW_NORMAL;

    lf.lfItalic = (fnFont == ITALIC);
    lf.lfItalic = (fnFont == ULINE);

    // создадим шрифт, а затем возвратим его дескриптор.

    return CreateFont(lf.lfHeight, lf.lfWidth,
        lf.lfEscapement, lf.lfOrientation, lf.lfWeight,
        lf.lfItalic, lf.lfUnderline, lf.lfStrikeOut,
        lf.lfCharSet, lf.lfOutPrecision, lf.lfClipPrecision,
        lf.lfQuality, lf.lfPitchAndFamily, lf.lfFaceName);
}


11.18.4.5 - Пример "собственных" пунктов меню

Пример в этой теме использует в меню "собственные" пункты. Пункты меню выбирают конкретные атрибуты шрифта, а прикладная программа показывает на экране каждый пункт меню, используя шрифт, который имеет соответствующий атрибут. Например, пункт меню Italic (Курсив) отображается в курсивном шрифте. Название меню Character (Шрифт) в строке меню открывает меню.

Строка меню и раскрывающееся меню определены вначале расширенным ресурсом шаблона меню. Поскольку шаблон меню не может определять "собственные" пункты, меню вначале содержит четыре текстовых пункта меню со следующими строками: "Regular" ("Обычный"), "Bold" ("Полужирный"), "Italic" ("Курсив") и "UnderlineWM_CREATE. Когда процедура получает сообщение WM_CREATE, она вызывает определяемую программой функцию OnCreate, которая выполняет следующие шаги для каждого пункта меню:

  1. Распределяет в памяти определяемую программой структуру MYITEM.
  2. Получает текст пункта меню и сохраняет его в определяемой программой структуре MYITEM.
  3. Создает шрифт, использованный, чтобы показать на экране пункт меню и сохраняет дескриптор в определяемой программой структуре MYITEM.
  4. Изменяет тип пункта меню на MFT_OWNERDRAW и сохраняет указатель на определяемую программой структуру MYITEM, как на данные пункта.

Поскольку указатель на каждую определяемую программой структуру MYITEM сохраняется как данные пункта, он переходит в оконную процедуру вместе с сообщениями WM_MEASUREITEM и WM_DRAWITEM для соответствующего пункта меню. Указатель содержится в члене itemData и структуры MEASUREITEMSTRUCT и структуры DRAWITEMSTRUCT.

Сообщение WM_MEASUREITEM отправляется для каждого "собственного" пункта меню, когда он впервые отображается на экране. Приложение обрабатывает это сообщение, выбирая шрифт для пункта меню в контекст устройства, а затем устанавливает пространство, требуемое, чтобы показать на экране текст пункта меню этим шрифтом. Шрифт и текст пункта меню оба определены структурой пункта меню MYITEM (структура, определенная прикладной программой). Приложение устанавливает размер текста при помощи использования функции GetTextExtentPoint32.

Оконная процедура обрабатывает сообщение WM_DRAWITEM, показывая на экране текст пункта меню в соответствующем шрифте. Шрифт и текст пункта меню оба определены структурой пункта меню MYITEM. Прикладная программа выбирает текст и цвета фона, соответствующие состоянию пункта меню.

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

Ниже следуют необходимые части заголовочного файла прикладной программы.

// Идентификаторы пункта меню для меню Character (Шрифт)

#define IDM_CHARACTER 10
#define IDM_REGULAR   11
#define IDM_BOLD      12
#define IDM_ITALIC    13
#define IDM_UNDERLINE 14

// Структура, связанная с пунктами меню

typedef struct tagMYITEM {
    HFONT hfont;
    int cchItemText;
    char szItemText[1];
} MYITEM;

#define CCH_MAXITEMTEXT 256

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

LRESULT CALLBACK MainWindowProc(
    HWND hwnd,
    UINT uMsg,
    WPARAM wParam,
    LPARAM lParam
    )
{
    switch (uMsg) {
        case WM_CREATE:
            if (!OnCreate(hwnd))
                return -1;
            break;

        case WM_DESTROY:
            OnDestroy(hwnd);
            PostQuitMessage(0);
            break;

        case WM_MEASUREITEM:
            OnMeasureItem(hwnd, (LPMEASUREITEMSTRUCT) lParam);

            return TRUE;

        case WM_DRAWITEM:
            OnDrawItem(hwnd, (LPDRAWITEMSTRUCT) lParam);
            return TRUE;

        .
        . // Дополнительная обработка сообщения идет здесь.
        .

        default:
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return 0;
}

BOOL WINAPI OnCreate(HWND hwnd)
{
    HMENU hmenuBar = GetMenu(hwnd);
    HMENU hmenuPopup;
    MENUITEMINFO mii;
    UINT uID;

    MYITEM *pMyItem;

    // Получим дескриптор выскакивающего меню.

    mii.fMask = MIIM_SUBMENU;	 <>// чтобы получить информацию
    GetMenuItemInfo(hmenuBar, IDM_CHARACTER, FALSE, &mii);
    hmenuPopup = mii.hSubMenu;

    // Модифицируем каждый пункт меню. Предположим, что
    // IDs ( идентификаторы) от IDM_REGULAR до
    // IDM_UNDERLINE - последовательные числа

    for (uID = IDM_REGULAR; uID <= IDM_UNDERLINE; uID++) {

        // Распределим в памяти структуру пункта,
        // оставляя пространство для строки плюс для
        // символов CCH_MAXITEMTEXT.

        pMyItem = (MYITEM *) LocalAlloc(LMEM_FIXED,
                sizeof(MYITEM) + CCH_MAXITEMTEXT);

        // Сохраним текст пункта в структуре пункта

        mii.fMask = MIIM_TYPE;
        mii.dwTypeData = pMyItem->szItemText;
        mii.cch = CCH_MAXITEMTEXT;
        GetMenuItemInfo(hmenuPopup, uID, FALSE, &mii);
        pMyItem->cchItemText = mii.cch;

        // Перераспределим память для структуры для
        // минимально требуемого размера.

        pMyItem = (MYITEM *) LocalReAlloc(pMyItem,
                sizeof(MYITEM) + mii.cch, LMEM_MOVEABLE);

        // Создадим шрифт, который используем для прорисовки пункта.

        pMyItem->hfont = CreateMenuItemFont(uID);

        // Заменим пункт на "собственный" пункт и сохраним
        // адрес структуры пункта как данные пункта.

        mii.fMask = MIIM_TYPE | MIIM_DATA;
        mii.fType = MFT_OWNERDRAW;
        mii.dwItemData = (DWORD) pMyItem;

        SetMenuItemInfo(hmenuPopup, uID, FALSE, &mii);
    }
    return TRUE;
}

HFONT CreateMenuItemFont(UINT uID)
{
    LOGFONT lf;

    ZeroMemory(&lf, sizeof(lf));
    lf.lfHeight = 20;
    lstrcpy(lf.lfFaceName, "Times New Roman");

    switch (uID) {
        case IDM_BOLD:
            lf.lfWeight = FW_HEAVY;
            break;

        case IDM_ITALIC:
            lf.lfItalic = TRUE;
            break;

        case IDM_UNDERLINE:

            lf.lfUnderline = TRUE;
            break;
    }
    return CreateFontIndirect(&lf);
}

VOID WINAPI OnDestroy(HWND hwnd)
{
    HMENU hmenuBar = GetMenu(hwnd);
    HMENU hmenuPopup;
    MENUITEMINFO mii;
    UINT uID;
    MYITEM *pMyItem;

    // Получим дескриптор меню.

    mii.fMask = MIIM_SUBMENU; // чтобы получить информацию
    GetMenuItemInfo(hmenuBar, IDM_CHARACTER, FALSE, &mii);
    hmenuPopup = mii.hSubMenu;

    // Освободим ресурсы, связанные с каждым пунктом меню.

    for (uID = IDM_REGULAR; uID <= IDM_UNDERLINE; uID++) {

        // Получим данные пункта.

        mii.fMask = MIIM_DATA;
        GetMenuItemInfo(hmenuPopup, uID, FALSE, &mii);
        pMyItem = (MYITEM *) mii.dwItemData;

        // Уничтожим шрифт и освободим структуру пункта

        DeleteObject(pMyItem->hfont);
        LocalFree(pMyItem);
    }
}

VOID WINAPI OnMeasureItem(HWND hwnd, LPMEASUREITEMSTRUCT lpmis)
{
    MYITEM *pMyItem = (MYITEM *) lpmis->itemData;
    HDC hdc = GetDC(hwnd);
    HFONT hfntOld = SelectObject(hdc, pMyItem->hfont);
    SIZE size;
    GetTextExtentPoint32(hdc, pMyItem->szItemText, pMyItem->cchItemText, &size);
    lpmis->itemWidth = size.cx;
    lpmis->itemHeight = size.cy;
    SelectObject(hdc, hfntOld);
    ReleaseDC(hwnd, hdc);
}

VOID WINAPI OnDrawItem(HWND hwnd, LPDRAWITEMSTRUCT lpdis)
{
    MYITEM *pMyItem = (MYITEM *) lpdis->itemData;
    COLORREF clrPrevText, clrPrevBkgnd;
    HFONT hfntPrev;
    int x, y;
    // Установим соответствующие цвета шрифта и фона.
    if (lpdis->itemState & ODS_SELECTED) {
        clrPrevText = SetTextColor(lpdis->hDC,
                GetSysColor(COLOR_HIGHLIGHTTEXT));
        clrPrevBkgnd = SetBkColor(lpdis->hDC,
                GetSysColor(COLOR_HIGHLIGHT));
    }
    else {
        clrPrevText = SetTextColor(lpdis->hDC,
                GetSysColor(COLOR_MENUTEXT));
        clrPrevBkgnd = SetBkColor(lpdis->hDC,

                GetSysColor(COLOR_MENU));
    }

    // Решим, где нарисовать и оставить пространство для "галочки".
    x = lpdis->rcItem.left;
    y = lpdis->rcItem.top;
    x += LOWORD(GetMenuCheckMarkDimensions());

    // Выберем шрифт и прорисуем текст.

    hfntPrev = SelectObject(lpdis->hDC, pMyItem->hfont);
    ExtTextOut(lpdis->hDC, x, y, ETO_OPAQUE,
            &lpdis->rcItem, pMyItem->szItemText,
            pMyItem->cchItemText, NULL);

    // Восстанавливаем первоначальный шрифт и цвет.

    SelectObject(lpdis->hDC, hfntPrev);
    SetTextColor(lpdis->hDC, clrPrevText);
    SetBkColor(lpdis->hDC, clrPrevBkgnd);
}


11.18.5 - Использование индивидуальных значков типа "галочки"

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


11.18.5.1 - Создание пользовательских точечных рисунков (значков) типа "галочки"

Пользовательский точечный рисунок (значок) "галочки" должен быть такого же самого размера как и заданный по умолчанию значок "галочки". Вы можете получить заданный по умолчанию размер значка "галочки" путем вызова функции GetMenuCheckMarkDimensions. Младшее слово величины возвращаемого значения этой функции определяет ширину; старшее слово - высоту.

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

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

Чтобы создать значок во время выполнения программы:

  1. Используйте функцию CreateCompatibleDC, чтобы создать контекст устройства, совместимый с тем, который используется основным окном прикладной программы. Параметр функции hdc может установить или значение ПУСТО (NULL) или величину возвращаемого значения из функции GetDC. CreateCompatibleDC возвращает значение дескриптора совместимого контекста устройства.
  2. Используйте функцию CreateCompatibleBitmap, чтобы создать точечный рисунок (значок), совместимый с основным окном приложения. Параметры nWidth и nHeight этой функции устанавливают размеры значка; они должны определить информацию о ширине и высоте, возвращаемую функцией GetMenuCheckMarkDimensions. Вы можете также использовать и функцию CreateBitmap, чтобы создать одноцветный значок.
  3. Используйте функцию SelectObject для выбора значка в совместимом контексте устройства.
  4. Используйте рисующие функции GDI, такие как Ellipse (Эллипс) и LineTo, (Линия), чтобы нарисовать изображение внутри значка, или функции типа BitBlt и StretchBlt, чтобы копировать изображение в точечный рисунок (значок).

За большей информацией обратитесь к статье Bitmaps.


11.18.5.2 - Связывание пункта меню с точечным рисунком (значком)

Вы связываете пару точечных рисунков (значков) "галочки" с пунктом меню, передавая дескрипторы значков функции SetMenuItemBitmaps. Параметр hBitmapUnchecked идентифицирует значок снятия "галочки", а параметр hBitmapChecked идентифицирует установку значка. Если Вы хотите удалить один или оба значка «галочки» из пункта меню, Вы можете установить или параметр hBitmapUnchecked или параметр hBitmapChecked, или оба в значение ПУСТО (NULL).


11.18.5.3 - Настройка атрибута "галочка"

Функция CheckMenuItem устанавливает атрибут "галочки" пункта меню, либо в установленное, либо в снятое состояние. Вы можете определить значение MF_CHECKED, чтобы установить атрибут "галочку " для отметки и значение MF_UNCHECKED, чтобы установить его в снятое состояние.

Вы можете также устанавливать состояние "галочки" пункта меню при помощи использования функция SetMenuItemInfo.

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


11.18.5.4 - Моделирование окошек для флажка "галочкой" в меню

Эта тема содержит пример, который показывает, как моделировать окошки для флажка "галочкой" в меню. Пример содержит меню Character (Символ), пункты которого позволяют пользователю устанавливать атрибуты текущего шрифта, такие как полужирный, курсивный и подчеркнутый. Когда атрибут шрифта действует, галочка отображается в окошке для флажка рядом с соответствующим пунктом меню; иначе, рядом с этим пунктом отображается пустое окошко для флажка.

Пример заменяет заданный по умолчанию точечный рисунок "галочки " на два точечных рисунка (значка): точечный рисунок с установленным в окне маркером и точечным рисунком с пустым окном (без маркера). Точечный рисунок окошка для маркера отображается рядом с пунктом меню Bold (Полужирный), Italic (Курсивный) или Underline (Подчеркнутый), когда атрибут "галочки " пункта установлен в значение MF_CHECKED. Снятый маркер "галочки" или пустой точечный рисунок окошка для маркера отображается тогда, когда атрибут "галочки " установлен в значение MF_UNCHECKED.

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

Чтобы получить дескриптор заданного системой точечного рисунка (значка) окошка для флажка, пример вызывает функцию LoadBitmap, устанавливая значение ПУСТО (NULL) в параметре hInstance и OBM_CHECKBOXES в параметре lpBitmapName. Поскольку все изображения значков одного и того же размера, пример может разделять их, поделив ширину и высоту точечного рисунка на число изображений в строках и столбцах.

Нижеследующая часть файла определения ресурса показывает, как определены пункты меню в меню Character. Обратите внимание!, что сначала атрибуты шрифта не действуют, так как атрибут "галочки " для пункта Обычный (Regular) установлен в отмеченное "галочкой" состояние, а, по умолчанию, атрибут "галочки " оставшихся пунктов установлен в состояние без "галочки".

#include "men3.h"

MainMenu MENU
BEGIN
    POPUP   "&Character"
    BEGIN
        MENUITEM    "&Regular",     IDM_REGULAR, CHECKED
        MENUITEM SEPARATOR
        MENUITEM    "&Bold",        IDM_BOLD
        MENUITEM    "&Italic",      IDM_ITALIC
        MENUITEM    "&Underline",   IDM_ULINE
    END
END

Здесь находится относящееся к делу содержание заголовочного файла прикладной программы.

// Идентификаторы пунктов меню

#define IDM_REGULAR 0x1
#define IDM_BOLD    0x2
#define IDM_ITALIC  0x4
#define IDM_ULINE   0x8

// Флажки - маркеры

#define CHECK   1
#define UNCHECK 2

// Маска атрибута шрифта

#define ATTRIBMASK 0xe

// Прототипы функций

LRESULT APIENTRY MainWndProc(HWND, UINT, WPARAM, LPARAM);
HBITMAP GetMyCheckBitmaps(UINT);
BYTE CheckOrUncheckMenuItem(BYTE, HMENU);

Следующий пример показывает части оконной процедуры, которые создают точечные рисунки (значки) "галочки "; устанавливает атрибут "галочки" пунктов меню Bold (Полужирный), Italic (Курсивный) и Underline(Подчеркнутый); и уничтожает значки "галочки".

LRESULT APIENTRY MainWndProc(hwndMain, uMsg, wParam, lParam)
HWND hwndMain;
UINT uMsg;
WPARAM wParam;
LPARAM lParam;
{
    static HBITMAP hbmpCheck;		// дескриптор значка установленной «галочки»
    static HBITMAP hbmpUncheck;		// дескриптор значка без «галочки»
    static HMENU hmenu;		// дескриптор главного окна
    BYTE fbFontAttrib;			// флажки атрибутов шрифта

    switch (uMsg) {
        case WM_CREATE:

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

            hbmpCheck = GetMyCheckBitmaps(CHECK);
            hbmpUncheck = GetMyCheckBitmaps(UNCHECK);

            // Установим значки для маркера и снятия маркера
            // "галочки" для пунктов меню.

            hmenu = GetMenu(hwndMain);
            SetMenuItemBitmaps(hmenu, IDM_BOLD, MF_BYCOMMAND,
                hbmpUncheck, hbmpCheck);
            SetMenuItemBitmaps(hmenu, IDM_ITALIC, MF_BYCOMMAND,
                hbmpUncheck, hbmpCheck);
            SetMenuItemBitmaps(hmenu, IDM_ULINE, MF_BYCOMMAND,
                hbmpUncheck, hbmpCheck);

            return 0;

        case WM_COMMAND:
            switch (LOWORD(wParam)) {

                // Обработка команд меню.

                case IDM_REGULAR:
                case IDM_BOLD:
                case IDM_ITALIC:
                case IDM_ULINE:

                    // CheckOrUncheckMenuItem – функция, определяемая
                    // прикладной программой, которая устанавливает "галочки"
                    // пунктам меню и возвращает выбранный пользователем
                    // атрибут шрифта.

                    fbFontAttrib = CheckOrUncheckMenuItem(
                        (BYTE) LOWORD(wParam), hmenu);

                    .
                    . // Установим атрибуты шрифта.
                    .

                    return 0;

                .
                . // Обработаем другие командные сообщения.
                .

                default:
                    break;
            }

            break;

        .
        . // Обработаем другие сообщения окна.
        .

        case WM_DESTROY:

            // Разрушим значки установки и снятия маркера "галочки".

            DeleteObject(hbmpCheck);
            DeleteObject(hbmpUncheck);

            PostQuitMessage(0);
            break;

        default:
            return DefWindowProc(hwndMain, uMsg, wParam, lParam);

    }
    return NULL;
}

HBITMAP GetMyCheckBitmaps(fuCheck)
UINT fuCheck;			   	// флажки CHECK или UNCHECK
{
    COLORREF crBackground;		// цвет фона
    HBRUSH hbrBackground;		// кисть фона
    HBRUSH hbrTargetOld;		// первоначальная кисть фона
    HDC hdcSource;			// исходный контекст устройства
    HDC hdcTarget;			// контекст устройства цели

    HBITMAP hbmpCheckboxes;		// дескриптор значка маркера
    BITMAP bmCheckbox;		// структура для данных значка
    HBITMAP hbmpSourceOld;		// дескриптор значка первоисточника
    HBITMAP hbmpTargetOld;		// дескриптор первоначального целевого значка
    HBITMAP hbmpCheck;			// дескриптор значка маркера
    RECT rc;			// прямоугольник для точечного рисунка окна маркера
    DWORD dwCheckXY;			// размеры значка маркера
    WORD wBitmapX;			// ширина значка маркера
    WORD wBitmapY;			// высота значка маркера

    // Получим цвет фона меню и создадим объемную кисть с этим цветом.

    crBackground = GetSysColor(COLOR_MENU);
    hbrBackground = CreateSolidBrush(crBackground);

    // Создадим контекст устройства в памяти для значков источника и цели.

    hdcSource = CreateCompatibleDC((HDC) NULL);
    hdcTarget = CreateCompatibleDC(hdcSource);

    // Получим размер значка "галочки ", который Windows
    // устанавливает по умолчанию и создадим совместимый точечный
    // рисунок (значок) того же самого размера.

    dwCheckXY = GetMenuCheckMarkDimensions();
    wBitmapX = LOWORD(dwCheckXY);
    wBitmapY = LOWORD(dwCheckXY);

    hbmpCheck = CreateCompatibleBitmap(hdcSource, wBitmapX,
        wBitmapY);

    // Выберем кисть фона и значок в целевом значке.

    hbrTargetOld = SelectObject(hdcTarget, hbrBackground);
    hbmpTargetOld = SelectObject(hdcTarget, hbmpCheck);

    // Используем выбранную кисть, чтобы инициализировать цвет фона
    // Точечного рисунка (значка) в целевом контексте устройства.

    PatBlt(hdcTarget, 0, 0, wBitmapX, wBitmapY, PATCOPY);

    // Загрузим предопределенные точечные рисунки окошка
    // для флажка и выберем его в исходном DC.

    hbmpCheckboxes = LoadBitmap((HINSTANCE) NULL,
        (LPTSTR) OBM_CHECKBOXES);

    hbmpSourceOld = SelectObject(hdcSource, hbmpCheckboxes);

    // Заполним структуру BITMAP информацией о точечном рисунке
    // окошка для флажка, а затем найдем левый верхний угол окошка
    для установки или снятия маркера (флажка) "галочки".

    GetObject(hbmpCheckboxes, sizeof(BITMAP), &bmCheckbox);

    if (fuCheck == UNCHECK) {
        rc.left = 0;
        rc.right = (bmCheckbox.bmWidth / 4);
    }
    else {
        rc.left = (bmCheckbox.bmWidth / 4);
        rc.right = (bmCheckbox.bmWidth / 4) * 2;
    }

    rc.top = 0;
    rc.bottom = (bmCheckbox.bmHeight / 3);

    //Копируем соответствующий точечный рисунок (значок) в целевом DC.
    // Если точечный рисунок (значок) переключателя больше, чем заданный
    // по умолчанию значок "галочки", используем StretchBlt,чтобы подогнать
    // его по размерам; теперь копируем его.

    if (((rc.right - rc.left) > (int) wBitmapX) ||
            ((rc.bottom - rc.top) > (int) wBitmapY))
        StretchBlt(hdcTarget, 0, 0, wBitmapX, wBitmapY,
            hdcSource, rc.left, rc.top, rc.right - rc.left,
            rc.bottom - rc.top, SRCCOPY);

    else
        BitBlt(hdcTarget, 0, 0, rc.right - rc.left,

            rc.bottom - rc.top,
            hdcSource, rc.left, rc.top, SRCCOPY);

    // Выберем старый исходный и целевой точечные рисунки
    // в исходном и целевом DC, а затем удалим DC и кисть фона.

    SelectObject(hdcSource, hbmpSourceOld);
    SelectObject(hdcTarget, hbrTargetOld);
    hbmpCheck = SelectObject(hdcTarget, hbmpTargetOld);

    DeleteObject(hbrBackground);
    DeleteObject(hdcSource);
    DeleteObject(hdcTarget);

    // Возвратим дескриптор нового точечного рисунка "галочки ".

    return hbmpCheck;
}

BYTE CheckOrUncheckMenuItem(bMenuItemID, hmenu)
BYTE bMenuItemID;
HMENU hmenu;
{
    DWORD fdwMenu;
    static BYTE fbAttributes;

    switch (bMenuItemID) {
        case IDM_REGULAR:

            // Всякий раз, когда выбран пункт меню Regular,
            // добавим к нему галочку, а затем удалим галочки из
            // любого пункта меню атрибута шрифта.

            CheckMenuItem(hmenu, IDM_REGULAR, MF_BYCOMMAND |
                MF_CHECKED);

            if (fbAttributes & ATTRIBMASK) {
                CheckMenuItem(hmenu, IDM_BOLD, MF_BYCOMMAND |
                    MF_UNCHECKED);
                CheckMenuItem(hmenu, IDM_ITALIC, MF_BYCOMMAND |
                    MF_UNCHECKED);
                CheckMenuItem(hmenu, IDM_ULINE, MF_BYCOMMAND |
                    MF_UNCHECKED);
            }
            fbAttributes = IDM_REGULAR;

            return fbAttributes;

        case IDM_BOLD:
        case IDM_ITALIC:
        case IDM_ULINE:

            // Переключим галочку для выбранного пункта меню и
            // установим флажки атрибута шрифта соответственно.

            fdwMenu = GetMenuState(hmenu, (UINT) bMenuItemID,
                MF_BYCOMMAND);
            if (!(fdwMenu & MF_CHECKED)) {
                CheckMenuItem(hmenu, (UINT) bMenuItemID,
                    MF_BYCOMMAND | MF_CHECKED);

                fbAttributes |= bMenuItemID;

            } else {
                CheckMenuItem(hmenu, (UINT) bMenuItemID,
                    MF_BYCOMMAND | MF_UNCHECKED);
                fbAttributes ^= bMenuItemID;
            }

            // Если какие-либо атрибуты шрифта в настоящее время
            // выбраны, удалим галочку из пункта меню Regular; если
            // никакие атрибуты не выбраны, добавим галочку к пункту
            // меню Regular.

            if (fbAttributes & ATTRIBMASK) {
                CheckMenuItem(hmenu, IDM_REGULAR,
                    MF_BYCOMMAND | MF_UNCHECKED);
                fbAttributes &= (BYTE) ~IDM_REGULAR;

            } else {
                CheckMenuItem(hmenu, IDM_REGULAR,
                    MF_BYCOMMAND | MF_CHECKED);
                fbAttributes = IDM_REGULAR;
            }

            return fbAttributes;
    }
}


11.18.5.5 - Пример использования пользовательских точечных рисунков значков "галочки ".

Пример в этой теме связывает пользовательские точечные рисунки (значки) типа "галочки" с пунктами меню в двух меню. Пункты меню в первом меню определяют атрибуты символа: полужирный, курсивный, и подчеркивание. Каждый пункт меню может быть или отмечен или не отмечен "галочкой". Для этих пунктов меню пример использует значки "галочки ", которые похожи на маркеры установки и сброса состояния проверки органа управления.

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

Оконная процедура обрабатывает сообщение WM_CREATE путем вызова определяемой программой функции OnCreate. OnCreate создает четыре значка "галочки", а затем связывает их со своими соответствующими пунктами меню при помощи использования функции SetMenuItemBitmaps.

Чтобы создать каждый значок, OnCreate вызывает определяемую программой функцию CreateMenuBitmaps, устанавливая указатель на конкретную функцию рисования для значка. Функция CreateMenuBitmaps создает одноцветный значок требуемого размера, выбирает его в памяти контекста устройства и стирает фон. Затем она вызывает заданную функцию рисования, чтобы заполнить передний план картинки.

Имеется четыре определяемые программой функции рисования - DrawCheck, DrawUncheck, DrawRadioCheck и DrawRadioUncheck. Они рисуют прямоугольник с X (крестиком), пустой прямоугольник, эллипс, содержащий меньший затемненный эллипс и, соответственно, пустой эллипс.

Оконная процедура обрабатывает сообщение WM_DESTROY, удаляя значки типа "галочки". Она получает дескриптор каждый картинки при помощи использования функции GetMenuItemInfo, а затем переправляет дескриптор функции DeleteObject.

Когда пользователь выбирает пункт меню, окну владельцу отправляется сообщение WM_COMMAND. Для пунктов меню в меню Character, оконная процедура вызывает определяемую программой функцию CheckCharacterItem. Для пунктов в меню Paragraph, оконная процедура вызывает определяемую программой функцию CheckParagraphItem.

Каждый пункт в меню Character, независимо друг от друга, может быть отмечен или не отмечен значком типа "галочки". Следовательно, CheckCharacterItem просто включает состояние проверки ("галочки") определяемого пункта меню. Сначала функция вызывает функцию GetMenuItemInfo, чтобы получить текущее состояние пункта меню. Затем она включает флажок состояния MFS_CHECKED и устанавливает новое состояние путем вызова функции SetMenuItemInfo.

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

Ниже следуют необходимые части заголовочного файла прикладной программы.

// Идентификаторы пунктов меню для меню Character

#define IDM_CHARACTER 10
#define IDM_BOLD      11
#define IDM_ITALIC    12
#define IDM_UNDERLINE 13

// Идентификаторы пункта меню для меню Paragraph

#define IDM_PARAGRAPH 20
#define IDM_LEFT      21
#define IDM_CENTER    22
#define IDM_RIGHT     23

// Тип указателя функции для функций рисования

typedef VOID (WINAPI * DRAWFUNC)(HDC hdc, SIZE size);

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

LRESULT CALLBACK MainWindowProc(
        HWND hwnd,
        UINT uMsg,
        WPARAM wParam,
        LPARAM lParam
        )
{
    switch (uMsg) {
        case WM_CREATE:
            if (!OnCreate(hwnd))
                return -1;
            break;

        case WM_DESTROY:
            OnDestroy(hwnd);
            PostQuitMessage(0);
            break;

        case WM_COMMAND:
            switch (LOWORD(wParam)) {

                case IDM_BOLD:

                case IDM_ITALIC:

                case IDM_UNDERLINE:
                    CheckCharacterItem(hwnd, LOWORD(wParam));
                    break;

                case IDM_LEFT:
                case IDM_CENTER:
                case IDM_RIGHT:
                    CheckParagraphItem(hwnd, LOWORD(wParam));
                    break;

                .
                . // Обработка других команд здесь.
                .

            }

            break;

        .
        . // Обработка других сообщений здесь.
        .

        default:
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    return 0;
}

VOID WINAPI CheckCharacterItem(HWND hwnd, UINT uID)
{
    HMENU hmenuBar = GetMenu(hwnd);
    HMENU hmenuPopup;
    MENUITEMINFO mii;

    // Получим дескриптор меню Character.

    mii.fMask = MIIM_SUBMENU;  // информация, которую получаем
    GetMenuItemInfo(hmenuBar, IDM_CHARACTER, FALSE, &mii);

    hmenuPopup = mii.hSubMenu;

    // Получим состояние заданного пункта меню.

    mii.fMask = MIIM_STATE;    // информация, которую получаем
    GetMenuItemInfo(hmenuPopup, uID, FALSE, &mii);

    // Переключим состояние отметки типа «галочки».

    mii.fState ^= MFS_CHECKED;
    SetMenuItemInfo(hmenuPopup, uID, FALSE, &mii);
}

VOID WINAPI CheckParagraphItem(HWND hwnd, UINT uID)
{
    HMENU hmenuBar = GetMenu(hwnd);
    HMENU hmenuPopup;
    MENUITEMINFO mii;

    // Получим дескриптор меню Paragraph.

    mii.fMask = MIIM_SUBMENU; // информация, которую получаем
    GetMenuItemInfo(hmenuBar, IDM_PARAGRAPH, FALSE, &mii);
    hmenuPopup = mii.hSubMenu;

    // Отметим "галочкой" определяемый пункт и снимем отметку "галочкой" со всех других.

    CheckMenuRadioItem(
            hmenuPopup,         	// дескриптор меню
            IDM_LEFT,           	// первый пункт в ряду
            IDM_RIGHT,          	// последний пункт в ряду
            uID,                	// пункт для проверки
            MF_BYCOMMAND        	// ID, нет позиции
            );
}

BOOL WINAPI OnCreate(HWND hwnd)
{
    HMENU hmenuBar = GetMenu(hwnd);
    HMENU hmenuPopup;
    MENUITEMINFO mii;
    UINT uID;
    HBITMAP hbmChecked;
    HBITMAP hbmUnchecked;

    // Получим дескриптор меню Character.

    mii.fMask = MIIM_SUBMENU; // информация, которую получаем
    GetMenuItemInfo(hmenuBar, IDM_CHARACTER, FALSE, &mii);
    hmenuPopup = mii.hSubMenu;

    // Создадим значки отметки "галочкой" и снятие отметки.

    hbmChecked = CreateMenuBitmap(DrawCheck);
    hbmUnchecked = CreateMenuBitmap(DrawUncheck);

    // Установим точечные рисунки (значки) пометок для каждого пункта меню.

    for (uID = IDM_BOLD; uID <= IDM_UNDERLINE; uID++) {
        SetMenuItemBitmaps(hmenuPopup, uID, MF_BYCOMMAND,
                hbmUnchecked, hbmChecked);
    }

    // Получим дескриптор выскакивающего меню Paragraph.

    mii.fMask = MIIM_SUBMENU; // информация, которую получаем

    GetMenuItemInfo(hmenuBar, IDM_PARAGRAPH, FALSE, &mii);
    hmenuPopup = mii.hSubMenu;

    // Создадим значки отметки "галочкой" и снятие отметки.

    hbmChecked = CreateMenuBitmap(DrawRadioCheck);
    hbmUnchecked = CreateMenuBitmap(DrawRadioUncheck);

    // Установим точечные рисунки (значки) пометки для каждого пункта меню.

    for (uID = IDM_LEFT; uID <= IDM_RIGHT; uID++) {
        SetMenuItemBitmaps(hmenuPopup, uID, MF_BYCOMMAND,
                hbmUnchecked, hbmChecked);

    }

    // Вначале отметим "галочкой) IDM_LEFT пункт параграфа.

    CheckMenuRadioItem(hmenuPopup, IDM_LEFT, IDM_RIGHT,
            IDM_LEFT, MF_BYCOMMAND);
    return TRUE;
}

HBITMAP WINAPI CreateMenuBitmap(DRAWFUNC lpfnDraw)
{
    // Создадим DC совместимый с DC рабочего стола окна.

    HWND hwndDesktop = GetDesktopWindow();
    HDC hdcDesktop = GetDC(hwndDesktop);
    HDC hdcMem = CreateCompatibleDC(hdcDesktop);

    // Установим требуемый растровый размер.

    DWORD dwExt = GetMenuCheckMarkDimensions();
    SIZE size = { LOWORD(dwExt), HIWORD(dwExt) };

    // Создадим одноцветный значок и выберем его.

    HBITMAP hbm = CreateBitmap(size.cx, size.cy, 1, 1, NULL);
    HBITMAP hbmOld = SelectObject(hdcMem, hbm);

    // Очистим фон и вызовем функцию рисования.

    PatBlt(hdcMem, 0, 0, size.cx, size.cy, WHITENESS);
    (*lpfnDraw)(hdcMem, size);

    // Навести порядок.

    SelectObject(hdcMem, hbmOld);

    DeleteDC(hdcMem);
    ReleaseDC(hwndDesktop, hdcDesktop);
    return hbm;
}

VOID WINAPI DrawCheck(HDC hdc, SIZE size)
{
    HBRUSH hbrOld;
    hbrOld = SelectObject(hdc, GetStockObject(NULL_BRUSH));
    Rectangle(hdc, 0, 0, size.cx, size.cy);
    MoveToEx(hdc, 0, 0, NULL);
    LineTo(hdc, size.cx, size.cy);
    MoveToEx(hdc, 0, size.cy - 1, NULL);
    LineTo(hdc, size.cx - 1, 0);
    SelectObject(hdc, hbrOld);
}

VOID WINAPI DrawUncheck(HDC hdc, SIZE size)

{
    HBRUSH hbrOld;
    hbrOld = SelectObject(hdc, GetStockObject(NULL_BRUSH));
    Rectangle(hdc, 0, 0, size.cx, size.cy);
    SelectObject(hdc, hbrOld);
}

VOID WINAPI DrawRadioCheck(HDC hdc, SIZE size)
{
    HBRUSH hbrOld;
    hbrOld = SelectObject(hdc, GetStockObject(NULL_BRUSH));
    Ellipse(hdc, 0, 0, size.cx, size.cy);
    SelectObject(hdc, GetStockObject(BLACK_BRUSH));
    Ellipse(hdc, 2, 2, size.cx - 2, size.cy - 2);
    SelectObject(hdc, hbrOld);

}

VOID WINAPI DrawRadioUncheck(HDC hdc, SIZE size)
{
    HBRUSH hbrOld;
    hbrOld = SelectObject(hdc, GetStockObject(NULL_BRUSH));
    Ellipse(hdc, 0, 0, size.cx, size.cy);
    SelectObject(hdc, hbrOld);
}

VOID WINAPI OnDestroy(HWND hwnd)
{
    HMENU hmenuBar = GetMenu(hwnd);
    HMENU hmenuPopup;
    MENUITEMINFO mii;

    // Получим дескриптор меню Character.

    mii.fMask = MIIM_SUBMENU; // информация, которую получаем
    GetMenuItemInfo(hmenuBar, IDM_CHARACTER, FALSE, &mii);

    hmenuPopup = mii.hSubMenu;

    // Получим точечные рисунки (значки) "галочки " и удалим их.

    mii.fMask = MIIM_CHECKMARKS;
    GetMenuItemInfo(hmenuPopup, IDM_BOLD, FALSE, &mii);
    DeleteObject(mii.hbmpChecked);
    DeleteObject(mii.hbmpUnchecked);

    // Получим дескриптор меню Paragraph.

    mii.fMask = MIIM_SUBMENU; // информация, которую получаем
    GetMenuItemInfo(hmenuBar, IDM_PARAGRAPH, FALSE, &mii);
    hmenuPopup = mii.hSubMenu;

    // Получим точечные рисунки (значки) "галочки " и удалим их.

    mii.fMask = MIIM_CHECKMARKS;
    GetMenuItemInfo(hmenuPopup, IDM_LEFT, FALSE, &mii);
    DeleteObject(mii.hbmpChecked);
    DeleteObject(mii.hbmpUnchecked);
}


11.19 - Справочник по меню

Функции, структуры и сообщения, используемые в меню, сгруппированы следующим способом.

Дескрипторы меню
GetMenu
GetSubMenu
GetSystemMenu
IsMenu

Информация о пунктах меню
GetMenuItemCount
GetMenuItemID
GetMenuItemInfo
GetMenuState
GetMenuString
SetMenuItemInfo
MENUITEMINFO

Заданные по умолчанию пункты меню
GetMenuDefaultItem
SetMenuDefaultItem

Состояния пунктов меню
CheckMenuItem
CheckMenuRadioItem
EnableMenuItem
GetMenuCheckMarkDimensions
HiliteMenuItem
SetMenuItemBitmaps

Шаблоны меню
LoadMenu
LoadMenuIndirect
MENUITEMTEMPLATE
MENUITEMTEMPLATEHEADER
MENUEX_TEMPLATE_HEADER
MENUEX_TEMPLATE_ITEM

Создание и модификация меню
AppendMenu
CreateMenu
CreatePopupMenu
DeleteMenu
DestroyMenu
DrawMenuBar
InsertMenu
InsertMenuItem
ModifyMenu
RemoveMenu
SetMenuItemInfo

Изображение меню
SetMenu
TrackPopupMenu
TrackPopupMenuEx
WM_CONTEXTMENU

Замененные функции

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

Старая функция	Новая функция

AppendMenu 	InsertMenuItem
ChangeMenu	SetMenuItemInfo
CheckMenuItem	SetMenuItemInfo
GetMenuState	GetMenuItemInfo
InsertMenu	InsertMenuItem
ModifyMenu	SetMenuItemInfo

Устаревшие функции
ChangeMenu

Сообщения меню
WM_COMMAND
WM_CONTEXTMENU
WM_DRAWITEM
WM_ENTERMENULOOP
WM_EXITMENULOOP
WM_INITMENU
WM_INITMENUPOPUP
WM_MEASUREITEM
WM_MENUCHAR
WM_MENUSELECT
WM_SYSCOMMAND

Расширение набора функции меню
CheckMenuRadioItem
GetMenuDefaultItem
EndMenu
GetMenuBarInfo
GetMenuItemInfo
GetMenuItemRect
InsertMenuItem
MenuItemFromPoint
SetMenuDefaultItem
SetMenuItemInfo
TrackPopupMenuEx

Расширение набора сообщений меню
WM_CONTEXTMENU

Расширение набора структур меню
MENUEX_TEMPLATE_HEADER
MENUEX_TEMPLATE_ITEM
MENUITEMINFO
TPMPARAMS

SetMenu
TrackPopupMenu
TrackPopupMenuEx
WM_CONTEXTMENU


11.19.1 - Функции меню

Ниже перечисленные функции используются меню.
CheckMenuItem
CheckMenuRadioItem
CreateMenu
CreatePopupMenu
DeleteMenu
DestroyMenu
DrawMenuBar
EnableMenuItem
EndMenu
GetMenu
GetMenuBarInfo
GetMenuCheckMarkDimensions
GetMenuDefaultItem
GetMenuItemCount
GetMenuItemID
GetMenuItemInfo
GetMenuItemRect
GetMenuState
GetMenuString
GetSubMenu
GetSystemMenu
HiliteMenuItem
InsertMenuItem
IsMenu
LoadMenu
LoadMenuIndirect
MenuItemFromPoint
SetMenu
SetMenuDefaultItem
SetMenuInfo
SetMenuItemBitmaps
SetMenuItemInfo
TrackPopupMenu
TrackPopupMenuEx

Устаревшие функции
AppendMenu
ChangeMenu
InsertMenu
ModifyMenu
RemoveMenu


11.19.1.1 - Функция CheckMenuItem

(УстановитьГалочкуПунктуМеню)

Функция CheckMenuItem устанавливает атрибут "галочки" заданного пункта меню в установленное или снятое состояние.

Функция CheckMenuItem была заменена функцией SetMenuItemInfo. Вы все еще можете использовать CheckMenuItem, однако, если не нуждаетесь в какой-либо из расширенных функций SetMenuItemInfo.

Синтаксис

DWORD CheckMenuItem(
    HMENU hmenu,		// дескриптор меню
    UINT uIDCheckItem,		// пункт меню, напротив которого
                // ставится или снимается отметка
    UINT uCheck		// флажки пункта меню
);

Параметры
hmenu
Идентифицирует представляющее интерес меню.
uIDCheckItem
Определяет пункт меню, атрибут "галочки" которого должен быть установлен, как определено параметром uCheck.
uCheck
Определяет флажки, которые управляют интерпретацией параметра uIDCheckItem и состоянием атрибута "галочки " пункта меню. Этот параметр может быть комбинацией или MF_BYCOMMAND, или MF_BYPOSITION и MF_CHECKED или MF_UNCHECKED:

  • MF_BYCOMMAND - Указывает, что параметр uIDCheckItem дает идентификатор пункта меню. Флажок MF_BYCOMMAND является значением по умолчанию, если не установлены ни флажок MF_BYCOMMAND, ни флажок MF_BYPOSITION.
  • MF_BYPOSITION - Указывает, что параметр uIDCheckItem дает отсчитываемую от нуля относительную позицию пункта меню.
  • MF_CHECKED - Устанавливает атрибут "галочки" в установленное состояние.
  • MF_UNCHECKED - Устанавливает атрибут "галочки" в снятое состояние.

Возвращаемые значения
Возвращаемое значение определяет предшествующее состояние пункта меню (или MF_CHECKED или MF_UNCHECKED). Если пункт меню не существует, возвращаемое значение равно 0xFFFFFFFF.

Замечания
Пункт в горизонтальном (строке) меню не может иметь галочку.
Параметр uIDCheckItem идентифицирует пункт, который открывает подменю или командный пункт. Для пункта, который открывает подменю, параметр uIDCheckItem должен установить позицию пункта. Для командного пункта, параметр uIDCheckItem может установить или позицию пункта или его идентификатор.

Смотри также
EnableMenuItem, GetMenuCheckMarkDimensions, GetMenuItemID, SetMenuItemBitmaps, SetMenuItemInfo

Размещение и совместимость CheckMenuItem

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.2 - Функция CheckMenuRadioItem

(УстановитьПунктуМенюРадиокнопку)

[Теперь поддерживается в Windows NT]

Функция CheckMenuRadioItem отмечает "кружочком" заданный пункт меню и делает его пунктом с «радиокнопкой». Одновременно, функция снимает отметку "кружочком " со всех других пунктов меню в связанной группе и очищает от флажков типа радиоэлементов эти пункты.

Синтаксис

BOOL CheckMenuRadioItem
(
    HMENU hmenu,
    UINT idFirst,
    UINT idLast,
    UINT idCheck,
    UINT uFlags
);

Параметры
hmenu
Дескриптор к меню, которое содержит группу пунктов меню.
idFirst
Идентификатор или позиция первого пункта меню в группе.
idLast
Идентификатор или позиция последнего пункта меню в группе.
idCheck
Идентификатор или позиция пункта меню, который отмечается.
uFlags
Флажок, определяющий значение idFirst, idLast и idCheck. Если этот параметр - MF_BYCOMMAND, другие параметры определяют идентификаторы пункта меню. Если это - MF_BYPOSITION, другие параметры определяют позиции пунктов меню.

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

Замечания
Функция CheckMenuRadioItem устанавливает флажок типа MFT_RADIOCHECK и состояние MFS_CHECKED для пункта, определяемого idCheck и, одновременно, очищает оба флажка во всех других пунктах в группе. Отмеченный пункт отображается на экране, используя точечный рисунок «жирной» точки, вместо значка "галочки ".
Для получения дополнительной информации о типах пунктов меню и флажков состояния, см. структуру MENUITEMINFO.

Смотри также
MENUITEMINFO

Размещение и совместимость CheckMenuRadioItem

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.3 - Функция CreateMenu

(СоздатьМеню)

Функция CreateMenu создает меню. Меню вначале пустое, но оно может быть заполнено пунктами меню при помощи использования функций InsertMenuItem, AppendMenu и InsertMenu.

Синтаксис

HMENU CreateMenu(VOID)

Параметры
У этой функции нет параметров.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - дескриптор недавно созданного меню.
Если функция не выполняет задачу, величина возвращаемого значения - ПУСТО (NULL).

Замечания
Ресурсы, связанные с меню, которое предназначены окну, освобождаются автоматически. Если меню окну не назначено, прикладная программа должна освободить ресурсы системы, связанные с меню перед закрытием. Приложение освобождает ресурсы меню путем вызова функции DestroyMenu.
Windows 95: система может поддерживать максимум 16,364 дескрипторов меню.

Смотри также
AppendMenu, CreatePopupMenu, DestroyMenu, InsertMenu, SetMenu, InsertMenuItem

Размещение и совместимость CreateMenu

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.4 - Функция CreatePopupMenu

(СоздатьВыскакивающееМеню)

Функция CreatePopupMenu создает "выскакивающее" меню, подменю или контекстное меню. Меню вначале пустое. Вы можете вставлять или добавлять в конец пункты меню при помощи использования функции InsertMenuItem. Вы можете также использовать функцию InsertMenu, чтобы вставить пункты меню, а функцию AppendMenu, чтобы добавлять в конец пункты меню.

Синтаксис

HMENU CreatePopupMenu(VOID)

Параметры
У этой функции нет параметров.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - дескриптор недавно созданного меню.
Если функция не выполняет задачу, величина возвращаемого значения - ПУСТО (NULL).

Замечания
Прикладная программа может добавлять новое меню в существующее меню, или она может показывать на экране контекстное меню путем вызова функции TrackPopupMenuEx или TrackPopupMenu.
Ресурсы, связанные с меню, которое предназначены окну, освобождаются автоматически. Если меню окну не назначено, прикладная программа должна освободить ресурсы системы, связанные с меню перед закрытием. Приложение освобождает ресурсы меню путем вызова функция DestroyMenu.
Windows 95: система может поддерживать максимум 16,364 дескрипторов меню.

Смотри также
AppendMenu, CreateMenu, DestroyMenu, InsertMenu, SetMenu, TrackPopupMenu, TrackPopupMenuEx, InsertMenuItem

Размещение и совместимость CreatePopupMenu

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.5 - Функция DeleteMenu

(УдалитьМеню)

Функция DeleteMenu удаляет пункт из заданного меню. Если пункт меню открывает меню или подменю, эта функция уничтожает дескриптор меню или подменю и освобождает память, использованную меню или подменю.

Синтаксис

BOOL DeleteMenu(
    HMENU hMenu,		// дескриптор меню
    UINT uPosition,		//идентификатор пункта или позиции меню
    UINT uFlags		// флажок пункта меню
);

Параметры
hMenu
Идентифицирует меню, которое будет изменено.
uPosition
Определяет пункт меню, который будет удален, как определено параметром uFlags.
uFlags
Определяет, как интерпретируется параметр uPosition. Этот параметр должен быть одним из следующих значений:

  • MF_BYCOMMAND - Указывает, что uPosition дает идентификатор пункта меню. Если не установлен ни флажок MF_BYCOMMAND, ни флажок MF_BYPOSITION,то флажок MF_BYCOMMAND является флажок заданный по умолчанию.
  • MF_BYPOSITION - Указывает, что uPosition дает отсчитываемую от нуля относительную позицию пункта меню.

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

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

Смотри также
DrawMenuBar, RemoveMenu

Размещение и совместимость DeleteMenu

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.6 - Функция DestroyMenu

(РазрушитьМеню)

Функция DestroyMenu уничтожает заданное меню и освобождает любую память, которую меню занимает.

Синтаксис

BOOL DestroyMenu
(
    HMENU hMenu	// дескриптор меню, которое разрушается
);

Параметры
hMenu
Идентифицирует меню, которое будет разрушено.

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

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

Смотри также
CreateMenu, DeleteMenu, RemoveMenu

Размещение и совместимость DestroyMenu

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.7 - Функция DrawMenuBar

(НарисоватьГоризонтальноеМеню)

Функция DrawMenuBar перерисовывает строку меню заданного окна. Если строка меню изменяется после того, как Windows создала окно, эта функция должна быть вызвана, чтобы нарисовать измененную строку меню.

Синтаксис

BOOL DrawMenuBar
(
    HWND hWnd		// дескриптор окна со строкой меню, которая перерисовывается
);

Параметры
hWnd
Идентифицирует окно, строка меню которого нуждается в изменении.

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

Смотри также
DeleteMenu, InsertMenuItem, RemoveMenu, SetMenuItemInfo

Размещение и совместимость DrawMenuBar

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.8 - Функция EnableMenuItem

(ВключитьПунктМеню)

Функция EnableMenuItem включает, отключает или окрашивает в серый цвет (делает недоступным) определяемый пункт меню.

Синтаксис

BOOL EnableMenuItem(
    HMENU hMenu,		// дескриптор меню
    UINT uIDEnableItem, 	// пункт меню, который включается,
                // отключается или делается недоступным
    UINT uEnable		// флажки пункта меню
);

Параметры
hMenu
Идентифицирует меню.
uIDEnableItem
Определяет пункт меню, который будет включен, выключен или сделан недоступным, как обусловлено параметром uEnable. Этот параметр устанавливает пункт в строке меню, меню, или подменю.
uEnable
Определяет флажки, которые управляют интерпретацией параметра uIDEnableItem и указывает на состояние пункта меню, т. е. включен, заблокирован или недоступен он. Этот параметр должен быть комбинацией или флажков MF_BYCOMMAND или MF_BYPOSITION и MF_ENABLED, MF_DISABLED, или MF_GRAYED:

  • MF_BYCOMMAND - Указывает, что uIDEnableItem дает идентификатор пункта меню. Если ни флажок MF_BYCOMMAND, ни флажок MF_BYPOSITION не установлен, флажок MF_BYCOMMAND является флажком, заданным по умолчанию.
  • MF_BYPOSITION - Указывает, что uIDEnableItem дает отсчитываемую от нуля относительную позицию пункта меню.
  • MF_DISABLED - Указывает, что пункт меню заблокирован, а не недоступный, так что он не может быть выбран.
  • MF_ENABLED - Указывает, что пункт меню включен и восстановлен из недоступного состояния так, чтобы он мог быть выбран.
  • MF_GRAYED - Указывает, что пункт меню заблокирован и недоступен так, чтобы он не мог быть выбран.

Возвращаемые значения
Величина возвращаемого значения определяется предыдущим состоянием пункта меню (оно является, или MF_DISABLED, MF_ENABLED, или MF_GRAYED). Если пункт меню не существует, величина возвращаемого значения - 0xFFFFFFFF.

Замечания
Прикладная программа должна использовать флажок MF_BYPOSITION, чтобы определить правильный дескриптор меню. Если дескриптор меню определен для строки меню, то затрагивается пункт меню верхнего уровня (пункт в горизонтальном меню). Чтобы установить состояние пункта в "выскакивающем" меню или позицию подменю, программа должна определить дескриптор "выскакивающего " меню или подменю.
Когда приложение определяет флажок MF_BYCOMMAND, Windows отмечает значком типа "галочки" все пункты, которые открывают подменю в меню, идентифицированные при помощи определения дескриптора меню. Следовательно, если двойные пункты меню не присутствуют, достаточно определения дескриптора меню в строке меню.
Функции CreateMenu, InsertMenu, InsertMenuItem, LoadMenuIndirect, ModifyMenu и SetMenuItemInfo также могут устанавливать состояние (включения, блокировки или недоступности) меню

Смотри также
CreateMenu, GetMenuItemID, InsertMenu, InsertMenuItem, LoadMenuIndirect, ModifyMenu, SetMenuItemInfo, WM_SYSCOMMAND

Размещение и совместимость EnableMenuItem

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.9 - Функция EndMenu

(КонецМеню)

Функция EndMenu завершает активное меню вызывающего потока.

Синтаксис

BOOL EndMenu(VOID);

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

Замечания
Если платформа не поддерживает EndMenu, отправьте владельцу активного меню сообщение WM_CANCELMODE.

Смотри также
WM_CANCELMODE

Размещение и совместимость EnableMenuItem

Windows NT			Нет
Win95				Нет
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Включена в Windows 98, Windows 2000


11.19.1.10 - Функция GetMenu

(ПолучитьМеню)

Функция GetMenu извлекает дескриптор меню, связанного с данным окном.

Синтаксис

HMENU GetMenu
(
    HWND hWnd	// дескриптор окна
);

Параметры
hWnd
Идентифицирует окно, дескриптор меню которого извлекается.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - дескриптор меню. Если у данного окна нет меню, величина возвращаемого значения ПУСТО (NULL). Если окно - дочернее окно, величина возвращаемого значения неопределенная.

Смотри также
GetSubMenu, SetMenu

Размещение и совместимость GetMenu

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


11.19.1.11 - Функция GetMenuBarInfo

(ПолучитьДанныеОСтрокеМеню)

Функция GetMenuBarInfo получает информацию об определяемом горизонтальном меню.

Синтаксис

BOOL GetMenuBarInfo
(
    HWND hwnd,
    LONG idObject,
    LONG idItem,
    PMENUBARINFO pmbi
);

Параметры
hwnd
Дескриптор окна (горизонтального меню), информация о котором должна быть извлечена.
idObject
Определяет объект меню. Этот параметр может быть одним из следующих значений:

  • OBJID_CLIENT - Всплывающее меню, связанное с окном.
  • OBJID_MENU - Горизонтальное меню, связанное с окном (см. функцию GetMenu).
  • OBJID_SYSMENU - Системное меню, связанное с окном (см. функцию GetSystemMenu).

idItem
Задает пункт, о котором извлекается информация. Если этот параметр нулевой, функция извлекает информацию об меню непосредственно. Если этот параметр равен 1, функция извлекает информацию о первом пункте меню и так далее.

pmbi
Указатель на структуру MENUBARINFO, которая получает информацию. Обратите внимание! то, что перед вызовом этой функции Вы должны установить член MENUBARINFO.cbSize в sizeof (MENUBARINFO).

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

Смотри также
GetMenu, GetSystemMenu, MENUBARINFO

Размещение и совместимость GetMenuBarInfo

Windows NT			Да
Win95				Нет
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Влючена Windows 98, Windows NT 4.0 Service Pack 6


11.19.1.12 - Функция GetMenuCheckMarkDimensions

(ПолучитьРазмерыГалочкиМеню)

Эта функция устаревшая. Чтобы получить размеры растрового рисунка, используйте GetSystemMetrics со значениями CXMENUCHECK и CYMENUCHECK.

Функция GetMenuCheckMarkDimensions возвращает значение размеров заданного по умолчанию точечного рисунка (значка) типа «галочки». Windows показывает на экране этот значок рядом с пунктами меню, против которых установлены "галочки". Перед вызовом функции SetMenuItemBitmaps, чтобы заменить заданный по умолчанию значок типа «галочки» для пункта меню, прикладная программа должна установить правильный размер значка путем вызова GetMenuCheckMarkDimensions.

Синтаксис

LONG GetMenuCheckMarkDimensions(VOID)

Параметры
У этой функции нет параметров.

Возвращаемые значения
Величина возвращаемого значения определяет высоту и ширину, в пикселях, заданного по умолчанию значка типа «галочки». Старшее слово содержит высоту; младшее слово содержит ширину.

Смотри также
SetMenuItemBitmaps

Размещение и совместимость GetMenuCheckMarkDimensions

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.13 - Функция GetMenuDefaultItem

(Получить ПунктМенюПоУмолчанию)

[Теперь поддерживается в Windows NT]

Функция GetMenuDefaultItem устанавливает заданный по умолчанию пункт меню в определяемом меню.

Синтаксис

UINT WINAPI GetMenuDefaultItem
(
    HMENU hMenu,
    UINT fByPos,
    UINT gmdiFlags
);

Параметры
hMenu
Дескриптор меню, для которого извлекается заданный по умолчанию пункт меню.
fByPos
Значение, определяющее, извлекать ли данные о идентификаторе или позиции пункта меню. Если этот параметр - ЛОЖЬ (FALSE), возвращается идентификатор. Иначе, возвращается позиция меню.
gmdiFlags
Значение, определяющее, как функции искать пункты меню. Этот параметр может быть нулевой или одним из следующих значений:

  • GMDI_GOINTOPOPUPS - Определяет то, что если заданный по умолчанию пункт тот, который открывает подменю, функция должна искать рекурсивно в соответствующем подменю. Если подменю не имеет никакого заданного по умолчанию пункта, величина возвращаемого значения идентифицирует пункт, который открывает подменю. По умолчанию, функция возвращает значение первого заданного по умолчанию пункта в определяемом меню, независимо от того, является ли он пунктом, который открывает подменю.
  • GMDI_USEDISABLED - Определяет, что функция должна возвратить заданный по умолчанию пункт, даже если он заблокирован. По умолчанию, функция пропускает заблокированные или недоступные пункты.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - идентификатор или позиция пункта меню.
Если функция не выполняет задачу, величина возвращаемого значения - - (минус)1.

Смотри также
SetMenuDefaultItem

Размещение и совместимость GetMenuDefaultItem

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.14 - Функция GetMenuItemCount

(ПолучитьЧислоПунктовМеню)

Функция GetMenuItemCount вычисляет число пунктов в определяемом меню.

Синтаксис

int GetMenuItemCount
(
    HMENU hMenu	// дескриптор меню
);

Параметры
hMenu
Идентифицирует дескриптор меню, которое будет проверено.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения определяет число пунктов в меню.
Если функция не выполняет задачу, величина возвращаемого значения равна - (минус) 1. Чтобы получать расширенные данные об ошибках, вызовите GetLastError.

Смотри также
GetMenuItemID

Размещение и совместимость GetMenuItemCount

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.15 - Функция GetMenuItemID

(ПолучитьИдентификаторПунктаМеню)

Функция GetMenuItemID извлекает идентификатор пункта меню, размещенного в определенной позиции в меню.

Синтаксис

UINT GetMenuItemID(
    HMENU hMenu,	// дескриптор меню
    int nPos		// позиция пункта меню
);

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

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения определяет идентификатор данного пункта меню. Если идентификатор пункта меню имеет значение ПУСТО (NULL) или, если определяемый пункт открывает подменю, величина возвращаемого значения - 0xFFFFFFFF.

Смотри также
GetMenuItemCount, GetMenuString

Размещение и совместимость GetMenuItemID

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.16 - Функция GetMenuItemInfo

(ПолучитьДаннныеОПунктеМеню)

[Теперь поддердивается в Windows NT]

Функция GetMenuItemInfo извлекает информацию о пункте меню.

Синтаксис

BOOL WINAPI GetMenuItemInfo(
    HMENU hMenu,
    UINT uItem,
    BOOL fByPosition,
    LPMENUITEMINFO lpmii
);

Параметры
hMenu
Дескриптор меню, которое содержит пункт меню.
uItem
Идентификатор или позиция пункта меню, о котором надо получить информацию. Предназначение этого параметра зависит от значения fByPosition.
fByPosition
Значение, определяющее предназначение uItem. Если этот параметр - ЛОЖЬ (FALSE), uItem - идентификатор пункта меню. Иначе, это - позиция пункта меню.
lpmii
Указатель на структуру MENUITEMINFO, которая определяет информацию, чтобы извлечь и получить информацию о пункте меню.

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

Смотри также
SetMenuItemInfo, MENUITEMINFO

Размещение и совместимость GetMenuItemInfo

Windows NT				Да
Win95					Да
Win32s					Нет
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


11.19.1.17 - Функция GetMenuItemRect

(ПолучитьПрямоугольникПунктаМеню)

[Теперь поддерживается в Windows NT]

Функция GetMenuItemRect извлекает данные об ограничительном прямоугольнике для определяемого пункта меню.

Синтаксис

BOOL WINAPI GetMenuItemRect
(
    HWND hWnd,
    HMENU hMenu,
    UINT uItem,
    LPRECT lprcItem
);

Параметры
hWnd
Дескриптор окна, содержащего меню.
hMenu
Дескриптор меню
uItem
Отсчитываемая от нуля позиция пункта меню.
lprcItem
Указатель на структуру RECT, которая принимает ограничительный прямоугольник определяемого пункта меню, выраженного в экранной системе координат.

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

Смотри также
RECT

Размещение и совместимость GetMenuItemRect

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.18 - Функция GetMenuState

(ПолучитьСостояниеМеню)

Функция GetMenuState извлекает данные о флажках меню, связанные с определяемым пунктом меню. Если пункт меню открывает подменю, эта функция, к тому же, возвращает число пунктов в подменю.

Функция GetMenuState была заменена функцией GetMenuItemInfo. Вы можете все еще использовать GetMenuState, в том случае, если вам не нужно какая-либо из расширенных функций GetMenuItemInfo.

Синтаксис

UINT GetMenuState(
    HMENU hMenu,	// дескриптор меню
    UINT uId,		// запрошенный пункт меню
    UINT uFlags	// флажки меню
);

Параметры hMenu
Идентифицирует меню, которое содержит пункт, чьи флажки должны быть получены.
uId
Определяет пункт меню, флажки которого должны быть получены, как определяется параметром uFlags.
uFlags
Определяет, как интерпретировать параметр универсального идентификатора. Этот параметр может быть одним из следующих значений:

  • MF_BYCOMMAND - Обозначает, что параметр uId дает идентификатор пункта меню. Флажок MF_BYCOMMAND – это значение по умолчанию, если ни флажок MF_BYCOMMAND, ни флажок MF_BYPOSITION не установлены.
  • MF_BYPOSITION - Обозначает, что параметр uId дает отсчитываемую от нуля относительную позицию пункта меню.

Возвращаемые значения
Если определяемый пункт не существует, величина возвращаемого значения - 0xFFFFFFFF.
Если пункт меню открывает подменю, младший байт величины возвращаемого значения содержит флажки меню, связанные с пунктом, а старший байт содержит число пунктов в подменю, открываемых при помощи этого пункта.
Иначе, величина возвращаемого значения - маска (Булево OR (ИЛИ)) флажков меню. Ниже перечислены флажки меню, связанные с пунктом меню:

  • MF_CHECKED - Помещает «галочку» рядом с пунктом (только для "выскакивающих" меню, подменю и контекстных меню).
  • MF_DISABLED - Отключает пункт.
  • MF_GRAYED - Отключает и делает недоступным пункт.
  • MF_HILITE - Выделяет пункт.
  • MF_MENUBARBREAK - Исполняет функцию такую же как и флажок MF_MENUBREAK, за исключением "выскакивающих" меню, подменю и контекстных меню, где новый столбец отделяется от старого столбца вертикальной строкой.
  • MF_MENUBREAK - Размещает пункт на новой строке (для горизонтального меню) или в новом столбце (для "выскакивающих" меню, подменю и контекстных меню), без разделения столбцов.
  • MF_SEPARATOR - Создает горизонтальную разделительную линию (только для "выскакивающих" меню, подменю и контекстных меню).

Смотри также
GetMenu, GetMenuItemCount, GetMenuItemID, GetMenuItemInfo, GetMenuString

Размещение и совместимость GetMenuState

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.19 - Функция GetMenuString

(ПолучитьСтрокуМеню)

Функция GetMenuString копирует текстовую строку определяемого пункта меню в заданный буфер.

GetMenuString работает, но уже устарела. Вместо нее используйте GetMenuItemInfo.

Синтаксис

int GetMenuString(
    HMENU hMenu,		// дескриптор меню
    UINT uIDItem,		// идентификатор пункта меню
    LPTSTR lpString,		// указатель на буфер для строки
    int nMaxCount,		// максимальная длина строки
    UINT uFlag		// флажки меню
);

Параметры
hMenu
Идентифицирует меню.
uIDItem
Определяет пункт меню, который будет изменен, как обусловлено параметром uFlag.
lpString
Указатель на буфер, который принимает строку с символом нуля в конце. Если строка такой же длины или длиннее чем lpString, строка обрезается и добавляется признак конца ПУСТО (NULL). Если lpString - значение ПУСТО (NULL), функция возвращает длину строки меню.
nMaxCount
Определяет максимальную длину, в символах, строки, которая будет скопирована. Если строка длиннее, чем максимум, определяемый в параметре nMaxCount, лишние символы обрезаются.
Если nMaxCount имеет значение 0, функция возвращает значение длины строки меню.
uFlag
Определяет, как интерпретируется параметр uIDItem. Этот параметр должен быть одним из следующих значений:

  • MF_BYCOMMAND - Указывает, что uIDItem дает идентификатор пункта меню. Если ни флажок MF_BYCOMMAND, ни флажок MF_BYPOSITION не установлен, флажок MF_BYCOMMAND является флажком, заданным по умолчанию.
  • MF_BYPOSITION - Указывает, что uIDItem дает отсчитываемую от нуля относительную позицию пункта меню.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения определяет число символов, скопированное в буфер, не, включая в себя символ завершения строки (ноль-терминатор).
Если функция не выполняет задачу, величина возвращаемого значения нулевая.

Замечания
Обратите внимание! функция GetMenuString была заменена. Используйте функцию GetMenuItemInfo, чтобы получить текст пункта меню.
Параметр nMaxCount должен быть большим, чем число символов в текстовой строке, чтобы разместить символ завершения строки (ноль-терминатор).
Если nMaxCount - 0, функция возвращает значение длины строки меню.
Обратите внимание!
Параметр lpString - буфер TCHAR, а nMaxCount - длина строки меню в TCHARs. Неправильное изменение размеров этих параметров может стать причиной усечения строки, ведя к возможной потере данных.

Смотри также
GetMenuItemID

Размещение и совместимость GetMenuString

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


11.19.1.20 - Функция GetSubMenu

(ПолучитьПодменю)

Функция GetSubMenu извлекает дескриптор "выскакивающего" меню или подменю, активизированного заданным пунктом меню.

Синтаксис

HMENU GetSubMenu(
    HMENU hMenu,	// дескриптор меню
    int nPos		// позиция пункта меню
);

Параметры
hMenu
Идентифицирует меню.
nPos
Определяет отсчитываемую от нуля относительную позицию пункта в данном меню, который активизирует "выскакивающее" меню или подменю.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - дескриптор "выскакивающего" меню или подменю, активизированного пунктом меню. Если пункт меню не активизирует "выскакивающее" меню или подменю, величина возвращаемого значения - ПУСТО (NULL).

Смотри также
CreatePopupMenu, GetMenu

Размещение и совместимость GetSubMenu

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.21 - Функция GetSystemMenu

(ПолучитьСистемноеМеню)

Функция GetSystemMenu позволяет прикладной программе обратиться к меню окна, (известное также как Системное меню (System menu) или Управляющее меню (Control menu)) для копирования и изменения.

Синтаксис

HMENU GetSystemMenu
(
    HWND hWnd,		// дескриптор окна, которое владеет меню окна
    BOOL bRevert		// флажок сброса
);

Параметры
hWnd
Идентифицирует окно, которое будет владеть копией меню окна.
bRevert
Определяет действие, которое нужно предпринять. Если этот параметр - ЛОЖЬ (FALSE), GetSystemMenu возвращает дескриптор копии используемого в настоящее время меню окна. Копия вначале идентична меню окна, но она может быть изменена.
Если этот параметр - ИСТИНА (TRUE), GetSystemMenu возвращает меню окна обратно в состояние определяемое в Windows по умолчанию. Предыдущее меню окна, если оно есть, разрушается.

Возвращаемые значения
Если параметр bRevert - ЛОЖЬ (FALSE), величина возвращаемого значения - дескриптор копии меню окна. Если bRevert параметр - ИСТИНА (TRUE), величина возвращаемого значения - ПУСТО (NULL).

Замечания
Любое окно, которое не использует функцию GetSystemMenu, чтобы сделать свою собственную копию меню окна, получает стандартное меню окна.
Меню окна вначале содержит пункты с различными значениями идентификатора, такие как SC_CLOSE, SC_MOVE и SC_SIZE.
Пункты меню в меню окна посылают сообщения WM_SYSCOMMAND.
Все предопределенные пункты меню окна имеют числа идентификатора большие, чем 0xF000. Если прикладная программа добавляет команды в меню окна, она должна использовать числа идентификаторов меньшие, чем 0xF000.
Windows автоматически окрашивает в серый цвет (делает недоступными) пункты стандартного меню окна, в зависимости от ситуации. Прикладная программа может выполнить свою собственную проверку или установку запрета выбора, отвечая на сообщение WM_INITMENU, которое отправляся, до того, как покажется на экране какое-либо меню.

Смотри также
GetMenu, WM_INITMENU, WM_SYSCOMMAND

Размещение и совместимость GetSystemMenu

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.22 - Функция HiliteMenuItem

(ВыделитьПунктМеню)

Функция HiliteMenuItem выделяет или удаляет выделение пункта в строке меню.

Синтаксис

BOOL HiliteMenuItem
(
    HWND hwnd,		// дескриптор окна с меню
    HMENU hmenu,		// дескриптор меню
    UINT uItemHilite,		// выделенный или со снятым выделением пункт меню
    UINT uHilite		// флажки выделения
);

Параметры
hwnd
Идентифицирует окно, которое содержит меню.
hmenu
Идентифицирует строку меню, которая содержит пункт, который будет выделен.
uItemHilite
Определяет пункт меню, который будет выделен. Этот параметр является или идентификатором пункта меню или смещения пункта меню в строке меню, завися от значения параметра uHilite.
uHilite
Определяет флажки, которые управляют интерпретацией параметра uItemHilite, и обозначает, выделен ли пункт меню. Этот параметр должен быть комбинацией флажков или MF_BYCOMMAND, или MF_BYPOSITION и MF_HILITE, или MF_UNHILITE:

  • MF_BYCOMMAND - Обозначает, что uItemHilite дает идентификатор пункта меню.
  • MF_BYPOSITION - Обозначает, что uItemHilite дает отсчитываемую от нуля относительную позицию пункта меню.
  • MF_HILITE - Выделяет пункт меню. Если этот флажок не установлен, выделение удаляется из пункта.
  • MF_UNHILITE - Удаляет выделение из пункта меню.

Возвращаемые значения
Если пункт меню установлен в заданное состояние выделения, величина возвращаемого значения отличная от нуля.
Если пункт меню не установлен в заданное состояние выделения, величина возвращаемого значения нулевая.

Замечания
Флажки MF_HILITE и MF_UNHILITE могут быть использованы только с функцией HiliteMenuItem; они не могут быть использованы с функцией ModifyMenu.

Смотри также
ModifyMenu

Размещение и совместимость HiliteMenuItem

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.23 - Функция InsertMenuItem

(ВставитьПунктМеню)

[Теперь поддерживается в Windows NT]

Функция InsertMenuItem вставляет новый пункт меню в заданной позиции в меню.

BOOL WINAPI InsertMenuItem
(
    HMENU hMenu,
    UINT uItem,
    BOOL fByPosition,
    LPMENUITEMINFO lpmii
);

Параметры
hMenu
Дескриптор меню, в которое вставляется новый пункт меню.
uItem
Идентификатор или позиция пункта меню перед тем, как будет вставлен новый пункт. Предназначение этого параметра зависит от значения fByPosition.
fByPosition
Значение, определяющее предназначение uItem. Если этот параметр - ЛОЖЬ (FALSE), uItem - идентификатор пункта меню. Иначе, это - позиция пункта меню.
lpmii
Указатель на структуру MENUITEMINFO, которая содержит информацию о новом пункте меню.

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

Смотри также
MENUITEMINFO

Размещение и совместимость InsertMenuItem

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


11.19.1.24 - Функция IsMenu

(ЭтоМеню)

Функция IsMenu устанавливает, является ли дескриптор дескриптором меню.

Синтаксис

BOOL IsMenu
(
    HMENU hMenu	// дескриптор для проверки
);

Параметры
hMenu
Дескриптор, который будет проверен.

Возвращаемые значения
Если hMenu - дескриптор меню, величина возвращаемого значения отличная от нуля.
Если hMenu - дескриптор не меню, величина возвращаемого значения нулевая.

Размещение и совместимость IsMenu

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.25 - Функция LoadMenu

(ЗагрузитьМеню)

Функция LoadMenu загружает определяемый ресурс меню из исполняемого (.EXE) файла, связанного с экземпляром прикладной программы.

Синтаксис

HMENU LoadMenu(
    HINSTANCE hInstance,	// дескриптор экземпляра программы
    LPCTSTR lpMenuName		// строка с названием меню или идентификатор ресурса меню
);

Параметры
hInstance
Идентифицирует экземпляр модуля, содержащего ресурс меню, который будет загружен.
lpMenuName
Указывает на строку с символом нуля в конце, которая содержит имя ресурса меню. Или же, этот параметр может состоять из идентификатора ресурса в младшем слове и нуля в старшем слове. Чтобы создать это значение, используйте макрокоманду MAKEINTRESOURCE.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - дескриптор ресурса меню.
Если функция не выполняет задачу, величина возвращаемого значения - ПУСТО (NULL). Чтобы получать расширенные данные об ошибках, вызовите GetLastError.

Замечания
Функция DestroyMenu используется до того, как прикладная программа закроется, чтобы уничтожить меню и освободить память, которую заняло загруженное меню.

Смотри также
LoadMenuIndirect, MAKEINTRESOURCE

Размещение и совместимость LoadMenu

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


11.19.1.26 - Функция LoadMenuIndirect

(КосвеннаяЗагрузкаМеню)

Функция LoadMenuIndirect загружает определяемый шаблон меню в память.

Синтаксис

HMENU LoadMenuIndirect
{
    CONST MENUTEMPLATE *lpMenuTemplate	// адрес шаблона меню
);

Параметры
lpMenuTemplate
Указывает на шаблон или расширенный шаблон меню.
Шаблон меню состоит из структуры MENUITEMTEMPLATEHEADER, сопровождаемой одной или несколькими смежными структурами MENUITEMTEMPLATE. Расширенный шаблон меню состоит из структуры MENUEX_TEMPLATE_HEADER, сопровождаемой одной или несколькими смежными структурами MENUEX_TEMPLATE_ITEM.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - дескриптор меню.
Если функция не выполняет задачу, величина возвращаемого значения - ПУСТО (NULL). Чтобы получать расширенные данные об ошибках, вызовите GetLastError.

Замечания
И для версии ANSI и для версии Unicode этой функции, строки в структуре MENUITEMTEMPLATE должны быть строки Unicode.

Смотри также
LoadMenu, MENUEX_TEMPLATE_HEADER, MENUEX_TEMPLATE_ITEM, MENUITEMTEMPLATE, MENUITEMTEMPLATEHEADER

Размещение и совместимость LoadMenuIndirect

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


11.19.1.27 - Функция MenuItemFromPoint

(ПунктМенюИзТочки)

[Теперь поддерживается в Windows NT]

Функция MenuItemFromPoint обуславливает, какой пункт меню, если он есть, появляется в заданном месте.

Синтаксис

UINT WINAPI MenuItemFromPoint
(
    HWND hWnd,
    HMENU hMenu,
    POINT ptScreen
);

Параметры
hWnd
Дескриптор окна, содержащего меню.
hMenu
Дескриптор меню, содержащего пункты, которые подлежат проверке.
ptScreen
Структура POINT, определяющая расположение, которое проверяется. Если hMenu определяет строку меню, этот параметр находится в координатах окна. Иначе, он находится в рабочих координатах.

Возвращаемые значения
Возвращает отсчитываемую от нуля позицию пункта меню в заданном расположении или – (минус) 1, если в заданном расположении никакого пункта меню нет.

Смотри также
POINT

Размещение и совместимость MenuItemFromPoint

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.28 - Функция SetMenu

(УстановитьМеню)

Функция SetMenu связывает новое меню с заданным окном.

Синтаксис

BOOL SetMenu
(
    HWND hWnd,	// дескриптор окна
    HMENU hMenu	// дескриптор меню
);

Параметры
hWnd
Идентифицирует окно, с которым должно быть связано меню.
hMenu
Идентифицирует новое меню. Если этот параметр имеет значение ПУСТО (NULL), текущее меню окна удаляется.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - не ноль.
Если функция не выполняет задачу, величина возвращаемого значения - ноль. Чтобы получать расширенные данные об ошибках, вызовите GetLastError.

Замечания
Окно повторно рисуется, чтобы отобразить измененное меню.
Функция SetMenu заменяет предыдущее меню, если таковое имеется, но она не уничтожает его. Прикладная программа должна вызвать функцию DestroyMenu, чтобы выполнить эту задачу.

Смотри также
DestroyMenu, GetMenu

Размещение и совместимость SetMenu

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.29 - Функция SetMenuDefaultItem

(УстановитьПунктМенюПоУмолчанию)

[Теперь поддерживается в Windows NT]

Функция SetMenuDefaultItem устанавливает заданный по умолчанию пункт меню для заданного меню.

Синтаксис

BOOL SetMenuDefaultItem
(
    HMENU hMenu,
    UINT uItem,
    UINT fByPos
);

Параметры
hMenu
Дескриптор меню, в котором устанавливается заданный по умолчанию пункт.
uItem
Идентификатор или позиция нового заданного по умолчанию пункта меню или – (минус) 1, если заданный по умолчанию пункт отсутствует. Предназначение этого параметра зависит от значения fByPos.
fByPos
Значение, определяющее предназначение uItem. Если этот параметр - ЛОЖЬ (FALSE), uItem - идентификатор пункта меню. Иначе, он - позиция пункта меню.

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

Смотри также
GetMenuDefaultItem

Размещение и совместимость SetMenuDefaultItem

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.30 - Функция SetMenuInfo

(УстановитьДанныеОМеню)

Функция SetMenuInfo устанавливает информацию для заданного меню.

Синтаксис

BOOL SetMenuInfo(
    HMENU hmenu,
    LPCMENUINFO lpcmi
);

Параметры
hmenu
Дескриптор меню.
lpcmi
Указатель на структуру MENUINFO для меню.

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

Смотри также
MENUINFO

Размещение и совместимость SetMenuDefaultItem

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется Windows 98, Windows NT 2000


11.19.1.31 - Функция SetMenuItemBitmaps

(УстановитьЗначокПунктаМеню)

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

Синтаксис

BOOL SetMenuItemBitmaps
(
    HMENU hMenu,			// дескриптор меню
    UINT uPosition,			// пункт меню, который принимает значки
    UINT uFlags,			// флажки пункта меню
    HBITMAP hBitmapUnchecked,		// дескриптор значка снятия метки
    HBITMAP hBitmapChecked		// дескриптор значка установки метки
);

Параметры
hMenu
Идентифицирует меню, содержащее пункт, который принимает новые значки меток.
uPosition
Определяет пункт меню, который будет изменен, как обусловлено параметром uFlags.
uFlags
Определяет, как интерпретируется параметр uPosition. Параметр uFlags должен быть одним из следующих значений:

  • MF_BYCOMMAND - Указывает, что uPosition дает идентификатор пункта меню. Если ни флажок MF_BYCOMMAND ни флажок MF_BYPOSITION не установлен, MF_BYCOMMAND - флажок заданный по умолчанию.
  • MF_BYPOSITION - Указывает, что uPosition дает отсчитываемую от нуля относительную позицию пункта меню.

hBitmapUnchecked
Идентифицирует отображаемый точечный рисунок (значок), когда пункт меню не отмечен "галочкой".
hBitmapChecked
Идентифицирует отображаемый точечный рисунок (значок), когда пункт меню отмечен "галочкой".

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - не ноль.
Если функция не выполняет задачу, величина возвращаемого значения - ноль. Чтобы получать расширенные данные об ошибках, вызовите GetLastError.

Замечания
Если или параметр hBitmapUnchecked, или параметр hBitmapChecked имеют значение ПУСТО (NULL), Windows на экране ничего не показывает рядом с пунктом меню для обозначения соответствующего состояния метки. Если оба параметра имеют значение ПУСТО (NULL), Windows по умолчанию показывает на экране заданный значок галочки, когда пункт отмечен "галочкой" и удаляет метку, когда пункт не отмечен "галочкой".
Когда меню разрушается, эти значки не разрушаются; это является заботой приложения, чтобы уничтожить их.
Windows NT: функция GetMenuCheckMarkDimensions извлекает размеры заданной по умолчанию галочки, использованной для пунктов меню. Эти значения используются, чтобы установить соответствующий размер для точечных рисунков, предоставленных этой функцией.
Windows 95: Функция GetMenuCheckMarkDimensions устаревшая. Используйте GetSystemMetrics со значениями CXMENUCHECK и CYMENUCHECK, чтобы извлечь размеры значка.

Смотри также
GetMenu, GetMenuCheckMarkDimensions

Размещение и совместимость SetMenuItemBitmaps

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.32 - Функция SetMenuItemInfo

(УстановитьДанныеОПунктеМеню)

[Теперь поддерживается в Windows NT]

Функция SetMenuItemInfo изменяет информацию о пункте меню.

Синтаксис

BOOL WINAPI SetMenuItemInfo
(
    HMENU hMenu,
    UINT uItem,
    BOOL fByPosition,
    LPMENUITEMINFO lpmii
);

Параметры
hMenu
Дескриптор меню, которое содержит пункт меню.
uItem
Идентификатор или позиция пункта меню, который измениться. Предназначение этого параметра зависит от значения fByPosition.
fByPosition
Значение, определяющее предназначение uItem. Если этот параметр - ЛОЖЬ (FALSE), то uItem - идентификатор пункта меню. Иначе, он - позиция пункта меню.
lpmii
Указатель на структуру MENUITEMINFO, которая содержит информацию о пункте меню и определяет, какие атрибуты пункта меню изменятся.

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

Смотри также
GetMenuItemInfo, MENUITEMINFO

Размещение и совместимость SetMenuItemInfo

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.33 - Функция TrackPopupMenu

(ОтследитьВыскакивающееМеню)

Функция TrackPopupMenu показывает на экране контекстное меню в заданном расположении и устанавливает выбор пунктов в меню. Контекстное меню может появляться в любом месте на экране.

Синтаксис

BOOL TrackPopupMenu(
    HMENU hMenu,		// дескриптор контекстного меню
    UINT uFlags,		// флажки расположения на экране и кнопки мыши
    int x,			// горизонтальная позиция в экранных координатах
    int y,			// вертикальная позиция в экранных координатах
    int nReserved,		// зарезервирован, должен быть ноль
    HWND hWnd,			// дескриптор окна владельца
    CONST RECT *prcRect 	// указывает на RECT, которая определяет не освобожденную область
);

Параметры
hMenu
Идентифицирует контекстное меню, которое нужно отобразить. Дескриптор может быть получен путем вызова CreatePopupMenu, чтобы создать новое контекстное меню, или путем вызова GetSubMenu, чтобы извлечь дескриптор подменю, связанного с существующим пунктом меню.
uFlags
Набор битовых флажков, которые определяют параметры функции.
Используйте одну из следующих констант битовых флажков, чтобы определить, как функция установит контекстное меню по горизонтали:

  • TPM_CENTERALIGN - Если этот флажок установлен, функция выравнивает по центру горизонтали контекстное меню, относительно координаты, определяемой параметром x.
  • TPM_LEFTALIGN - Если этот флажок установлен, функция устанавливает контекстное меню так, чтобы его левая сторона была выровнена по координате, определяемой параметром x.
  • TPM_RIGHTALIGN - Устанавливает контекстное меню так, чтобы правая сторона была выровнена по координате, определяемой параметром x.

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

  • TPM_LEFTBUTTON - Если этот флажок установлен, контекстное меню устанавливается левой кнопкой мыши.
  • TPM_RIGHTBUTTON - Если этот флажок установлен, контекстное меню устанавливается правой кнопкой мыши.

x
Определяет горизонтальное расположение контекстного меню, в экранной системе координат.
y
Определяет вертикальное расположение контекстного меню, в экранной системе координат.
nReserved
Зарезервировано; должнобыть ноль.
hWnd
Идентифицирует окно, которое владеет контекстным меню. Это окно принимает все сообщения от меню. Окно не получает сообщение WM_COMMAND от меню до тех пор, пока функция не возвратит значение.
prcRect
Указывает на структуру RECT, которая определяет часть экрана, в которой пользователь может выбирать контекстное меню без ее освобождения. Если этот параметр имеет значение ПУСТО (NULL), контекстное меню освобождается, если пользователь щелкает кнопкой мыши вне контекстного меню.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - не ноль.
Если функция не выполняет задачу, величина возвращаемого значения - ноль. Чтобы получать расширенные данные об ошибках, вызовите GetLastError.

Смотри также
CreatePopupMenu, GetSubMenu, RECT, WM_COMMAND

Размещение и совместимость TrackPopupMenu

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.34 - Функция TrackPopupMenuEx

(ОтследитьВыскакивающееМенюРасширенная)

[Теперь поддерживается в Windows NT]

Функция TrackPopupMenuEx показывает на экране контекстное меню в заданном расположении и отслеживает выбор пунктов на контекстном меню. Контекстное меню может появляться в любом месте на экране.

Синтаксис

BOOL TrackPopupMenuEx(
    HMENU hmenu,
    UINT fuFlags,
    int x,
    int y,
    HWND hwnd,
    LPTPMPARAMS lptpm
);

Параметры
hmenu
Дескриптор контекстного меню, которое нужно отобразить. Этот дескриптор может быть получен путем вызова функции CreatePopupMenu, чтобы создать новое контекстное меню или путем вызова функции GetSubMenu, чтобы извлечь дескриптор подменю, связанное с существующим пунктом меню.
fuFlags
Позиционирование и другие параметры. Этот параметр, который может быть нулевой или большим количеством значений, перечисленных с функцией TrackPopupMenu, который может также включать в себя одно из следующих значений:

  • TPM_HORIZONTAL - Если меню нельзя показать в заданном месте без наложения на исключенный прямоугольник, система пытается приспособить затребованное горизонтальное выравнивание до того, как запрошено выравнивание по вертикали.
  • TPM_VERTICAL - Если меню нельзя показать в заданном месте без наложения на исключенный прямоугольник, система пытается приспособить затребованное выравнивание по вертикали до того, как запрошено горизонтальное выравнивание.

Исключенный прямоугольник является частью экрана, которую меню не должно перекрывать; он определяется lptpm.
x
Горизонтальное расположение контекстного меню, в экранной системе координат.
y
Вертикальное расположение контекстного меню, в экранной системе координат.
hwnd
Дескриптор окна, которое владеет контекстным меню. Это окно принимает все сообщения от меню. Окно не получает сообщение WM_COMMAND от меню до тех пор, пока функция не возвратит значение.
lptpm
Указатель на структуру TPMPARAMS, которая определяет область экрана, которую меню не должно перекрывать. Этот параметр может иметь значение ПУСТО (NULL).

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

Смотри также
CreatePopupMenu, GetSubMenu, TPMPARAMS, TrackPopupMenu, WM_COMMAND

Размещение и совместимость TrackPopupMenuEx

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.1.35 - Функция AppendMenu

(ДобавитьМеню)

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

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

Синтаксис

BOOL AppendMenu(
    HMENU hMenu,		// дескриптор меню, который будет изменен
    UINT uFlags,		// флажки пункта меню
    UINT uIDNewItem,		// идентификатор пункта меню или дескриптор "выскакивающего" меню
                // или подменю
    LPCTSTR lpNewItem		// пункт контекстного меню
);

Параметры
hMenu
Идентифицирует строку меню, "выскакивающее" меню, подменю или контекстное меню, которое будет изменено.
uFlags
Определяет флажки, которые управляют внешним видом и характеристиками нового пункта меню. Этот параметр может быть комбинация значений, перечисленных в разделе Замечаний ниже.
uIDNewItem
Определяет или идентификатор нового пункта меню или, если параметр uFlags установлен в MF_POPUP, дескриптор "выскакивающего" меню или подменю.
lpNewItem
Определяет содержание нового пункта меню. Интерпретация lpNewItem зависит от того, включает ли параметр uFlags в себя флажок MF_BITMAP, MF_OWNERDRAW или MF_STRING, как указано ниже:

  • MF_BITMAP - Содержит дескриптор растрового рисунка.
  • MF_OWNERDRAW - Содержит 32-разрядное значение, предоставленное прикладной программой, которое может быть использовано, чтобы утвердить, что дополнительные данные касаются пункта меню. Значение является членом itemData структуры, указываемой параметром lParam при помощи передачи сообщения WM_MEASURE или WM_DRAWITEM, когда создается меню, или его внешний вид модифицируется.
  • MF_STRING - Содержит указатель на строку с символом нуля в конце.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - не ноль.
Если функция не выполняет задачу, величина возвращаемого значения - ноль. Чтобы получать расширенные данные об ошибках, вызовите GetLastError.

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

  • MF_BITMAP - Использует точечный рисунок как пункт меню. Параметр lpNewItem содержит дескриптор точечного рисунка.
  • MF_CHECKED - Помещает галочку рядом с пунктом меню. Если прикладная программа предоставляет значки "галочки" (см. SetMenuItemBitmaps), этот флажок показывает на экране точечный рисунок галочки рядом с пунктом меню.
  • MF_DISABLED - Отключает пункт меню, так что он не может быть выбран, но флажок не окрашивает его в серый цвет.
  • MF_ENABLED - Включает пункт меню, так что он может быть выбран и восстанавливает его из недоступного состояния.
  • MF_GRAYED - Отключает пункт меню и окрашивает его в серый цвет (делает недоступным), так что он не может быть выбран.
  • MF_MENUBARBREAK - Исполняет такую же функцию, как и флажок MF_MENUBREAK для строки меню. Для "выскакивающего" меню, подменю или контекстного меню, новый столбец отделяется от старого столбца вертикальной линией.
  • MF_MENUBREAK - Помещает пункт в новую строку (для строки меню) или в новом столбце (для "выскакивающего" меню, подменю, или контекстного меню) без разделения столбцов.
  • MF_OWNERDRAW - Определяет, что пункт является "собственным" пунктом (нарисованным пользователем). Перед тем как меню отображается впервые, окно, которое владеет им, получает сообщение WM_MEASUREITEM, чтобы извлечь данные о ширине и высоте пункта меню. Сообщение WM_DRAWITEM затем отправляется в оконную процедуру окна владельца всякий раз, когда внешний вид пункта меню должен модифицироваться.
  • MF_POPUP - Определяет, что пункт меню открывает "выскакивающее" меню или подменю. Параметр uIDNewItem определяет дескриптор "выскакивающего" меню или подменю. Этот флажок используется, чтобы добавить имя меню в строке меню, или пункт меню, который открывает подменю "выскакивающего" меню, подменю или контекстное меню.
  • MF_SEPARATOR - Рисует горизонтальную разделительную линию. Этот флажок используется только в "выскакивающем" меню, подменю или контекстном меню. Строка не может быть недоступна, заблокирована, или выделена. Параметры lpNewItem и uIDNewItem игнорируются.
  • MF_STRING - Определяет, что пункт меню - текстовая строка; параметр lpNewItem указывает на строке.
  • MF_UNCHECKED - Удаляет галочку рядом с пунктом (значение по умолчанию). Если прикладная программа предоставляет точечные рисунки (значки) "галочки" (см. SetMenuItemBitmaps), этот флажок показывает на экране снятую метку "галочки" рядом с пунктом меню.

Следующие группы флажков не могут быть использованы вместе:

MF_DISABLED, MF_ENABLED и MF_GRAYED
MF_BITMAP, MF_STRING и MF_OWNERDRAW
MF_MENUBARBREAK и MF_MENUBREAK
MF_CHECKED и MF_UNCHECKED

Смотри также
CreateMenu, DeleteMenu, DestroyMenu, DrawMenuBar, InsertMenu, InsertMenuItem, ModifyMenu, RemoveMenu, SetMenuItemBitmaps

Размещение и совместимость AppendMenu

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


11.19.1.36 - Функция ChangeMenu

Функция ChangeMenu была заменена следующими специализированными функциями, которые являются доступными и в Windows NT и Windows 95:

  • AppendMenu - Добавляет в конец меню пункт.
  • InsertMenu - Вставляет пункт в меню.
  • ModifyMenu - Модифицирует пункт в меню
  • RemoveMenu - Удаляет пункт из меню, если он является выскакивающим пунктом, соответствующее выскакивающее меню не разрушается.

Windows 95:
Вместо того, чтобы использовать AppendMenu, InsertMenu и ModifyMenu, прикладные программы, написанные исключительно в Windows 95 должны использовать следующие новые функции, которые являются доступными только в Windows 95.

  • GetMenuItemInfo - Получает информацию о пункте меню.
  • InsertMenuItem - Вставляет новый пункт меню в определяемой позиции в строке меню или выскакивающем меню.
  • SetMenuItemInfo - Изменяет информацию о пункте меню.

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

Размещение и совместимость ChangeMenu

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


11.19.1.37 - Функция InsertMenu

(ВставитьМеню)

Функция InsertMenu вставляет новый пункт меню в меню, перемещая другие элементы вниз меню.

Функция InsertMenu была заменена функцией InsertMenuItem. Вы все еще можете использовать InsertMenu, однако, если Вы не нуждаетесь в какой-либо из расширенных функций InsertMenuItem.

Синтаксис

BOOL InsertMenu(
    HMENU hMenu,			// дескриптор меню
    UINT uPosition,		// пункт меню,который предшествует новому пункту меню
    UINT uFlags,		// флажки пункта меню
    UINT uIDNewItem,		// идентификатор меню пункта или выскакивающего меню или подменю
    LPCTSTR lpNewItem		// содержание пункта меню
);

Параметры
hMenu
Идентифицирует меню, которое будет изменено.
uPosition
Определяет пункт меню, перед которым должен быть вставлен новый пункт меню, как обусловлено параметром uFlags.
uFlags
Устанавливает флажки, которые управляют интерпретацией параметра uPosition и содержанием, внешним видом и поведением нового пункта меню. Этот параметр должен быть комбинацией одного из ниже перечисленных значений и, по крайней мере, одного из значений, перечисленных в следующем разделе Замечаний:

  • MF_BYCOMMAND - Указывает, что параметр uPosition дает идентификатор пункта меню. Флажок MF_BYCOMMAND является значением по умолчанию, если ни флажок MF_BYCOMMAND, ни флажок MF_BYPOSITION не установлен.
  • MF_BYPOSITION - Указывает, что параметр uPosition дает отсчитываемое от нуля взаимное положение нового пункта меню. Если uPosition - 0xFFFFFFFF, новый пункт меню добавлен в конец меню.

uIDNewItem
Определяет или идентификатор нового пункта меню или, если параметр uFlags имеет установленный флажок MF_POPUP, дескриптор "выскакивающего" меню или подменю.
lpNewItem
Определяет содержание нового пункта меню. Интерпретация lpNewItem зависит от того, включает ли параметр uFlags в себя флажок MF_BITMAP, MF_OWNERDRAW или MF_STRING, как ниже указано:

  • MF_BITMAP - Содержит дескриптор точечного рисунка.
  • MF_OWNERDRAW - Содержит 32-разрядное значение, поставляемое прикладной программой, которое может быть использовано для поддержки дополнительных данных родственного пункта меню. Значение находится в члене itemData структуры, указанной параметром lParam сообщения WM_MEASUREITEM или WM_DRAWITEM отправленного тогда, когда создавался пункт меню или модифицировался его внешний вид.
  • MF_STRING - Содержит указатель на строку с символом нуля в конце (значение по умолчанию).

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

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

  • MF_BITMAP - Использует точечный рисунок как пункт меню. Параметр lpNewItem содержит дескриптор точечного рисунка.
  • MF_CHECKED - Помещает галочку рядом с пунктом меню. Если прикладная программа предоставляет значки "галочки" (см. SetMenuItemBitmaps), этот флажок показывает на экране точечный рисунок галочки рядом с пунктом меню.
  • MF_DISABLED - Отключает пункт меню, так что он не может быть выбран, но флажок не окрашивает его в серый цвет.
  • MF_ENABLED - Включает пункт меню, так что он может быть выбран и восстанавливает его из недоступного состояния.
  • MF_GRAYED - Отключает пункт меню и окрашивает его в серый цвет (делает недоступным), так что он не может быть выбран.
  • MF_MENUBARBREAK - Исполняет такую же функцию, как и флажок MF_MENUBREAK для строки меню. Для "выскакивающего" меню, подменю или контекстного меню, новый столбец отделяется от старого столбца вертикальной линией.
  • MF_MENUBREAK - Помещает пункт в новую строку (для строки меню) или в новом столбце (для "выскакивающего" меню, подменю, или контекстного меню) без разделения столбцов.
  • MF_OWNERDRAW - Определяет, что пункт является «собственным» пунктом (нарисованным пользователем). Перед тем как меню отображается впервые, окно, которое владеет им, получает сообщение WM_MEASUREITEM, чтобы извлечь данные о ширине и высоте пункта меню. Сообщение WM_DRAWITEM затем отправляется в оконную процедуру окна владельца всякий раз, когда внешний вид пункта меню должен модифицироваться.
  • MF_POPUP - Определяет, что пункт меню открывает "выскакивающее" меню или подменю. Параметр uIDNewItem определяет дескриптор "выскакивающего" меню или подменю. Этот флажок используется, чтобы добавить имя меню в строке меню, или пункт меню, который открывает подменю "выскакивающего" меню, подменю или контекстное меню.
  • MF_SEPARATOR - Рисует горизонтальную разделительную линию. Этот флажок используется только в "выскакивающем" меню, подменю или контекстном меню. Строка не может быть недоступна, заблокирована, или выделена. Параметры lpNewItem и uIDNewItem игнорируются.
  • MF_STRING - Определяет, что пункт меню - текстовая строка; параметр lpNewItem указывает на строке.
  • MF_UNCHECKED - Удаляет галочку рядом с пунктом (значение по умолчанию). Если прикладная программа предоставляет точечные рисунки (значки) "галочки" (см. SetMenuItemBitmaps), этот флажок показывает на экране снятую метку "галочки" рядом с пунктом меню.

Следующие группы флажков не могут быть использованы вместе:

MF_BYCOMMAND и MF_BYPOSITION
MF_DISABLED, MF_ENABLED и MF_GRAYED
MF_BITMAP, MF_STRING, MF_OWNERDRAW и MF_SEPARATOR
MF_MENUBARBREAK и MF_MENUBREAK
MF_CHECKED и MF_UNCHECKED

Смотри также
AppendMenu, DeleteMenu, DrawMenuBar, InsertMenuItem, ModifyMenu, RemoveMenu, SetMenuItemBitmaps, WM_DRAWITEM, WM_MEASUREITEM

Размещение и совместимость InsertMenu

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


11.19.1.38 - Функция ModifyMenu

(МодифицироватьМеню)

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

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

Синтаксис

BOOL ModifyMenu(
    HMENU hMnu,		// дескриптор меню
    UINT uPosition,		// пункт меню, который модифицируется
    UINT uFlags,		// флажки пункта меню
    PTR uIDNewItem,		// идентификатор пункта меню или дескриптор «выскакивающего меню»
                // или подменю
    LPCTSTR lpNewItem		// содержание пункта меню
);

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

  • MF_BYCOMMAND - Указывает, что параметр uPosition дает идентификатор пункта меню. Флажок MF_BYCOMMAND является значением по умолчанию, если ни флажок MF_BYCOMMAND ни флажок MF_BYPOSITION не установлен.
  • MF_BYPOSITION - Указывает, что параметр uPosition дает отсчитываемую от нуля относительную позицию пункта меню.

uIDNewItem
Определяет или идентификатор измененного пункта меню или, если параметр uFlags имеет установленный флажок MF_POPUP, дескриптор "выскакивающего" меню или подменю.
lpNewItem
Указывает на содержание измененного пункта меню. Интерпретация этого параметра зависит от того, включает ли параметр uFlags в себя флажок MF_BITMAP, MF_OWNERDRAW или MF_STRING.

  • MF_BITMAP - Содержит дескриптор точечного рисунка.
  • MF_OWNERDRAW - Содержит 32-разрядное значение, поставляемое прикладной программой, которое может быть использовано для поддержки дополнительных данных родственного пункта меню. Значение находится в члене itemData структуры, указанной параметром lParam сообщения WM_MEASUREITEM или WM_DRAWITEM отправленного тогда, когда создавался пункт меню или модифицировался его внешний вид.
  • MF_STRING - Содержит указатель на строку с символом нуля в конце (значение по умолчанию).

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

Замечания
Если ModifyMenu заменяет пункт меню, который открывает "выскакивающее" меню или подменю, функция уничтожает старое "выскакивающее" меню или подменю и освобождает память, используемую им.
Для ускорителей клавиатуры, чтобы работать с растровыми или "собственными" (нарисованными пользователем) пунктами меню, владелец меню должен обработать WM_MENUCHAR сообщение. Для получения дополнительной информации см. Нарисованные пользователем ("собственные") меню и Сообщение WM_MENUCHAR.
Прикладная программа должна вызывать функцию DrawMenuBar всякий раз, когда меню изменяется, независимо от того, находится оно или нет в отображаемом окне. Чтобы изменить атрибуты существующих пунктов меню, значительно лучше использовать функции CheckMenuItem и EnableMenuItem.
Нижеследующий список описывает флажки, которые могут быть установлены в параметре uFlags:

  • MF_BITMAP - Использует точечный рисунок как пункт меню. Параметр lpNewItem содержит дескриптор точечного рисунка.
  • MF_BYCOMMAND - Указывает, что параметр uPosition определяет идентификатор пункта меню (по умолчанию).
  • MF_BYPOSITION - Указывает, что параметр uPosition определяет отсчитываемое от нуля взаимное положение нового пункта меню.
  • MF_CHECKED - Помещает галочку рядом с пунктом меню. Если прикладная программа предоставляет значки "галочки" (см. SetMenuItemBitmaps), этот флажок показывает на экране точечный рисунок галочки рядом с пунктом меню.
  • MF_DISABLED - Отключает пункт меню, так что он не может быть выбран, но флажок не окрашивает его в серый цвет.
  • MF_ENABLED - Включает пункт меню, так что он может быть выбран и восстанавливает его из недоступного состояния.
  • MF_GRAYED - Отключает пункт меню и окрашивает его в серый цвет (делает недоступным), так что он не может быть выбран.
  • MF_MENUBARBREAK - Исполняет такую же функцию, как и флажок MF_MENUBREAK для строки меню. Для "выскакивающего" меню, подменю или контекстного меню, новый столбец отделяется от старого столбца вертикальной линией.
  • MF_MENUBREAK - Помещает пункт в новую строку (для строки меню) или в новом столбце (для "выскакивающего" меню, подменю, или контекстного меню) без разделения столбцов.
  • MF_OWNERDRAW - Определяет, что пункт является «собственным» пунктом (нарисованным пользователем). Перед тем как меню отображается впервые, окно, которое владеет им, получает сообщение WM_MEASUREITEM, чтобы извлечь данные о ширине и высоте пункта меню. Сообщение WM_DRAWITEM затем отправляется в оконную процедуру окна владельца всякий раз, когда внешний вид пункта меню должен.
  • MF_POPUP - Определяет, что пункт меню открывает "выскакивающее" меню или подменю. Параметр uIDNewItem определяет дескриптор "выскакивающего" меню или подменю. Этот флажок используется, чтобы добавить имя меню в строке меню, или пункт меню, который открывает подменю "выскакивающего" меню, подменю или контекстное меню.
  • MF_SEPARATOR - Рисует горизонтальную разделительную линию. Этот флажок используется только в "выскакивающем" меню, подменю или контекстном меню. Строка не может быть недоступна, заблокирована, или выделена. Параметры lpNewItem и uIDNewItem игнорируются.
  • MF_STRING - Определяет, что пункт меню - текстовая строка; параметр lpNewItem указывает на строке.
  • MF_UNCHECKED - Удаляет галочку рядом с пунктом (значение по умолчанию). Если прикладная программа предоставляет точечные рисунки (значки) "галочки" (см. SetMenuItemBitmaps), этот флажок показывает на экране снятую метку "галочки" рядом с пунктом меню.

Следующие группы флажков не могут быть использованы вместе:

MF_BYCOMMAND и MF_BYPOSITION
MF_DISABLED, MF_ENABLED и MF_GRAYED
MF_BITMAP, MF_STRING, MF_OWNERDRAW и MF_SEPARATOR
MF_MENUBARBREAK и MF_MENUBREAK
MF_CHECKED и MF_UNCHECKED

Windows 95/98/Me: ModifyMenuW поддерживается Microsoft Layer для Уникода. Чтобы использовать его, Вы должны добавить некоторые файлы в вашу прикладную программу, как намечено в общих чертах в Microsoft Layer для Уникода для оперативных систем Windows 95/98/Me.

За примером обратитесь к статье Настройки шрифта текстовых строк пункта меню.

Смотри также
AppendMenu, CheckMenuItem, DrawMenuBar, EnableMenuItem, SetMenuItemBitmaps, SetMenuItemInfo, WM_DRAWITEM, WM_MEASUREITEM

Размещение и совместимость ModifyMenu

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


11.19.1.39 - Функция RemoveMenu

(УдалитьМеню)

Функция RemoveMenu удаляет пункт меню или отключает подменю от заданного меню. Если пункт меню открывает "выскакивающее" меню или подменю, RemoveMenu не уничтожает меню или его дескриптор, позволяя меню многократно использовать. Прежде, чем эта функцию вызвать, функция GetSubMenu должна извлечь дескриптор "выскакивающего" меню или подменю.

Синтаксис

BOOL RemoveMenu(
    HMENU hMenu,
    UINT uPosition,
    UINT uFlags
);

Параметры
hMenu
Дескриптор к меню, которое будет изменено.
uPosition
Задает пункт меню, который будет удален, как обусловлено параметром uFlags.
uFlags
Устанавливает, как параметр uPosition интерпретируется. Этот параметр должен быть одно из следующих значений.

  • MF_BYCOMMAND - Указывает, что uPosition дает идентификатор пункта меню. Если ни флажок MF_BYCOMMAND, ни флажок MF_BYPOSITION не установлен, флажок MF_BYCOMMAND является заданный по умолчанию флажок.
  • MF_BYPOSITION - Указывает, что uPosition дает отсчитываемое от нуля относительное положение пункта меню.

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

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

Смотри также
CreatePopupMenu, DeleteMenu, DrawMenuBar, GetSubMenu

Размещение и совместимость RemoveMenu

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.2 - Сообщения меню

Ниже перечисленные сообщения используются меню.
WM_COMMAND
WM_CONTEXTMENU
WM_DRAWITEM
WM_ENTERMENULOOP
WM_EXITMENULOOP
WM_INITMENU
WM_INITMENUPOPUP
WM_MEASUREITEM
WM_MENUCHAR
WM_MENUCOMMAND
WM_MENUDRAG
WM_MENUGETOBJECT
WM_MENURBUTTONUP
WM_MENUSELECT
WM_NEXTMENU
WM_SYSCOMMAND
WM_UNINITMENUPOPUP


11.19.2.1 - Сообщение WM_COMMAND

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

Синтаксис

WM_COMMAND
wNotifyCode = HIWORD(wParam); // код предупреждения
wID = LOWORD(wParam);         // идентификатор пункта, органа управления или клавиши-ускорителя
hwndCtl = (HWND) lParam;      // дескриптор органа управления

Параметры
wNotifyCode
Значение старшего слова wParam. Устанавливает код предупреждения, если сообщение от органа управления. Если сообщение от клавиши - ускорителя, этот параметр равен 1. Если сообщение от меню, этот параметр 0.
wID
Значение младшего слова wParam. Устанавливает идентификатор пункта меню, органа управления или клавиши - ускорителя.
hwndCtl
Значение lParam. Идентифицирует орган управления, отправляющий сообщение, если сообщение от органа управления. Иначе, этот параметр имеет значение ПУСТО (NULL).

Возвращаемые значения
Если приложение обрабатывает это сообщение, оно должно возвратить нуль.

Замечания
Нажатия клавиш - ускорителей, которые выбирают пункты меню окна, транслируются в сообщения WM_SYSCOMMAND.
Если происходит нажатие клавиши - ускорителя, которое соответствует пункту меню, когда окно, которое владеет меню, свернуто, сообщение WM_COMMAND не отправляется. Однако, если происходит нажатие клавиши - ускорителя, которое не соответствует какому-либо из пунктов меню в окне или в меню окна (системном), сообщение WM_COMMAND отправляется, даже если окно свернуто.
Если прикладная программа включает разделитель меню, то когда пользователь выбирает разделитель, система отправляет сообщение WM_COMMAND с младшим словом параметра wParam установленным в нуль.

Смотри также
WM_SYSCOMMAND

Размещение и совместимость WM_COMMAND

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.2.2 - Сообщение WM_CONTEXTMENU

Сообщение WM_CONTEXTMENU уведомляет окно, что пользователь щелкнул правой кнопкой мыши (правый щелчок) в окне.

Синтаксис

hwnd = (HWND) wParam;
xPos = LOWORD(lParam);
yPos = HIWORD(lParam);

Параметры
hwnd
Дескриптор окна, в котором пользователь щелкает правой кнопкой мыши. Это может быть дочернее окно окна, принимающего сообщение. Для получения дополнительной информации об обработке этого сообщения, см. раздел Замечаний.
xPos
Горизонтальная позиция курсора, в экранной системе координат, во время щелчка клавишей мыши.
yPos
Вертикальная позиция курсора, в экранной системе координат, во время щелчка клавишей мыши.

Возвращаемые значения
Возвращаемых значений нет.

Замечания
Окно может обрабатывать это сообщение, чтобы показать на экране контекстное меню, используя функцию TrackPopupMenu или TrackPopupMenuEx.
Если окно не показывает на экране контекстное меню, оно должно передать это сообщение в функцию DefWindowProc. Если окно является дочерним окном, DefWindowProc отправляет сообщение родителю. Иначе, DefWindowProc показывает на экране заданное по умолчанию контекстное меню, если определяемая позиция находится в заголовке окна.
Функция DefWindowProc создает сообщение WM_CONTEXTMENU, когда она обрабатывает сообщение WM_RBUTTONUP или WM_NCRBUTTONUP.

Смотри также
DefWindowProc, TrackPopupMenu, TrackPopupMenuEx, WM_NCRBUTTONUP, WM_RBUTTONUP

Размещение и совместимость WM_CONTEXTMENU

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.2.3 - Сообщение WM_DRAWITEM

Сообщение WM_DRAWITEM отправляется окну владельцу нарисованной пользователем ("собственной") кнопки, комбинированного блока, окна со списком, или меню, когда внешний вид кнопки, комбинированного блока, окно со списком или меню изменился.

Синтаксис

WM_DRAWITEM
idCtl = (UINT) wParam;             		// идентификатор органа управления
lpdis = (LPDRAWITEMSTRUCT) lParam; 		// информация о "собственном" элементе

Параметры
idCtl
Значение wParam. Устанавливает идентификатор органа управления, который отправил сообщение WM_DRAWITEM. Если сообщение было отправлено меню, этот параметр нулевой.
lpdis
Значение lParam. Указывает на структуру DRAWITEMSTRUCT, содержащую информацию об элементе, который нужно рисовать и типе требуемого рисунка.

Возвращаемые значения
Если приложение обрабатывает это сообщение, оно должно возвратить значение ИСТИНА (TRUE).

Действие по умолчанию
Функция DefWindowProc рисует прямоугольник фокуса в нарисованном пользователем ("собственный") элементе окна со списком.

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

Смотри также
DefWindowProc, DRAWITEMSTRUCT

Размещение и совместимость WM_DRAWITEM

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.2.4 - Сообщение WM_ENTERMENULOOP

Сообщение WM_ENTERMENULOOP информирует главную оконную процедуру прикладной программы, что был введен модальный цикл меню.

Синтаксис

WM_ENTERMENULOOP
wParam = (BOOL) fIsTrackPopupMenu	// флажки контекстного меню
lParam = 0 ;			// не используется, должен быть нуль

Параметры
fIsTrackPopupMenu
Определяет, является ли связанное меню контекстным меню. Этот параметр имеет значение ИСТИНА (TRUE), если это - контекстное меню, если нет - ЛОЖЬ (FALSE).

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

Замечания
Функция DefWindowProc возвращает нуль.

Смотри также
DefWindowProc, WM_EXITMENULOOP

Размещение и совместимость WM_ENTERMENULOOP

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.2.5 - Сообщение WM_EXITMENULOOP

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

Синтаксис

WM_EXITLOOP
wParam = (BOOL) fIsTrackPopupMenu	// флажки контекстного меню
lParam = 0;			// не используется, должен быть нуль

Параметры
fIsTrackPopupMenu
Устанавливает, является ли включенное меню контекстным меню. Этот параметр имеет значение ИСТИНА (TRUE), если это контекстное меню, и ЛОЖЬ (FALSE), если это не так.

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

Замечания
Функция DefWindowProc возвращает значение нуль.

Смотри также
DefWindowProc, WM_ENTERMENULOOP

Размещение и совместимость WM_EXITMENULOOP

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.2.6 - Сообщение WM_INITMENU

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

Синтаксис

WM_INITMENU
hmenuInit = (HMENU) wParam; // дескриптор меню, которое инициализируется

Параметры
hmenuInit
Значение wParam. Идентифицирует меню, которое будет инициализировано.

Возвращаемые значения
Если приложение обрабатывает это сообщение, оно должно возвратить нуль.

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

Смотри также
WM_INITMENUPOPUP

Размещение и совместимость WM_EXITMENULOOP

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.2.7 - Сообщение WM_INITMENUPOPUP

Сообщение WM_INITMENUPOPUP отправляется тогда, когда "выскакивающее" меню или подменю собирается стать активным. Это позволяет прикладной программе изменить меню до того, как оно покажется на экране, без изменения взятого в целом меню.

Синтаксис

WM_INITMENUPOPUP
hmenuPopup = (HMENU) wParam;		// дескриптор подменю
uPos = (UINT) LOWORD(lParam);		// позиция пункта подменю
fSystemMenu = (BOOL) HIWORD(lParam);		// флажок меню окна (системного)

Параметры
hmenuPopup
Значение wParam. Идентифицирует "выскакивающее" меню или подменю.
uPos
Значение младшего слова lParam. Устанавливает отсчитываемую от нуля относительную позицию пункта меню, который открывает "выскакивающее" меню или подменю.
fSystemMenu
Значение старшего слова lParam. Устанавливает, является ли "выскакивающее" меню меню окна (известное также как Системное меню или Меню управления). Если меню - меню окна, этот параметр - ИСТИНА (TRUE); иначе, это - ЛОЖЬ (FALSE).

Возвращаемые значения
Если приложение обрабатывает это сообщение, оно должно возвратить нуль.

Смотри также
WM_INITMENU

Размещение и совместимость WM_INITMENUPOPUP

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.2.8 - Сообщение WM_MEASUREITEM

Сообщение WM_MEASUREITEM отправляется окну владельцу нарисованной пользователем ("собственной ") кнопки, комбинированного блока, окна со списком, органа управления в виде списка или пункта меню, когда орган управления или меню создается.

Синтаксис

WM_MEASUREITEM
idCtl = (UINT) wParam;			// идентификатор органа управления
lpmis = (LPMEASUREITEMSTRUCT) lParam;	// информация о размере пункта

Параметры
idCtl
Значение wParam. Содержит значение члена CtlID структуры MEASUREITEMSTRUCT, указанной параметром lpmis. Это значение идентифицирует орган управления, который отправил сообщение WM_MEASUREITEM.
Если это значение нулевое, сообщение было отправлено меню. Если это значение не нуль, сообщение было отправлено комбинированным блоком или окном со списком. Если значение не нуль, а значение члена itemID структурв MEASUREITEMSTRUCT, указанной lpmis равно (UINT) - (минус) 1, сообщение было отправлено комбинированным полем редактирования.
lpmis
Значение lParam. Указывает на структуру MEASUREITEMSTRUCT, которая содержит размеры нарисованного пользователем ("собственного ") органа управления или пункта меню.

Возвращаемые значения
Если приложение обрабатывает это сообщение, оно должно возвратить значение ИСТИНА (TRUE).

Замечания
Когда окно владелец получает сообщение WM_MEASUREITEM, оно заполняет структуру MEASUREITEMSTRUCT, указанную параметром lParam сообщения и возвращает значение; структура сообщает Windows о размерах органа управления. Если окно со списком или комбинированный блок созданы со стилем LBS_OWNERDRAWVARIABLE или CBS_OWNERDRAWVARIABLE, это сообщение отправляется владельцу для каждого элемента в органе управления; иначе, это сообщение посылается только один раз.
Windows отправляет сообщение WM_MEASUREITEM окну владельцу комбинированных блоков и окон со списком, созданных со стилем OWNERDRAWFIXED перед посылкой сообщения WM_INITDIALOG. В результате, когда владелец получает это сообщение, Windows еще не установил высоту и ширину шрифта, используемого в органе управления; функция вызывает и вычисляет, требующиеся эти значения, которые должны встретиться в главной функции прикладной программы или библиотеки.

Смотри также
MEASUREITEMSTRUCT, WM_INITDIALOG

Размещение и совместимость WM_MEASUREITEM

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.2.9 - Сообщение WM_MENUCHAR

Сообщение WM_MENUCHAR отправляется тогда, когда меню активизируется, а пользователь, нажимает клавишу, которая не соответствует какому-либо символу или клавише ускорения. Это сообщение отправляется окну, которое владеет меню.

Синтаксис

WM_MENUCHAR
chUser = (char) LOWORD(wParam); 	// символ ASCII
fuFlag = (UINT) HIWORD(wParam); 	// флажок меню
hmenu = (HMENU) lParam;         	// дескриптор меню

Параметры
chUser
Значение младшего слова wParam. Устанавливает символ ASCII, который соответствует клавише нажатой пользователем.
fuFlag
Значение старшего слова wParam. Устанавливает тип активного меню. Этот параметр может быть одним из следующих значений:

  • MF_POPUP - Выпадающее меню, подменю или контекстное меню.
  • MF_SYSMENU - Меню окна (Системное меню или Управляющее меню).

hmenu
Значение lParam. Идентифицирует активное меню.

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

  • 0 - Сообщает Windows, что она должна отвергнуть символ, нажатый пользователем, и создать короткий гудок на системном динамике компьютера.
  • 1 - Сообщает Windows, что она должно закрыть активное меню.
  • 2 - Сообщает Windows, что младшее слово величины возвращаемого значения устанавливает отсчитываемую от нуля относительную позицию пункта меню. Этот пункт выбирается при помощи Windows.

Замечания
Младшее слово игнорируется, если старшее слово содержит 0 или 1. Прикладная программа должна обработать это сообщение тогда, когда клавиша - ускоритель используется для выбора пункта меню, который отображен на экране значком.

Размещение и совместимость WM_MENUCHAR

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.2.10 - Уведомляющее сообщение WM_MENUCOMMAND

Сообщение WM_MENUCOMMAND отправляется тогда, когда пользователь делает выбор из меню.

Синтаксис

WM_MENUCOMMAND

    WPARAM wParam
    LPARAM lParam;

Параметры
wParam
Определяет отсчитываемый от нуля индекс выбранного пункта.
Windows 98/Me: Старшее слово является отсчитываемый от нуля индекс выбранного пункта. Младшее слово - ID (ИДЕНТИФИКАТОР) пункта.
lParam
Дескриптор выбранного пункта меню.

Возвращаемые значения
Возвращаемых значений нет

Замечания
Сообщение WM_MENUCOMMAND дает Вам дескриптор меню —, так что Вы можете обращаться к данным меню в структуре MENUINFO, и также даете Вам индекс выбранного пункта, в котором обычно нуждаются прикладные программы. Напротив, сообщение WM_COMMAND дает Вам идентификатор пункта меню.
Сообщение WM_MENUCOMMAND посылается только для меню, которые определены установленным флажком MNS_NOTIFYBYPOS в члене dwStyle структуры MENUINFO.

Размещение и совместимость WM_MENUCOMMAND

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Включена в Windows 98/ NT/2000


11.19.2.11 - Уведомляющее сообщение WM_MENUDRAG

Уведомляющее сообщение WM_MENUDRAG отправляется владельцу перетаскиваемого меню, когда пользователь перетаскивает пункт меню.

Синтаксис

WM_MENUDRAG

    WPARAM wParam
    LPARAM lParam;

Параметры
wParam
Устанавливает позицию пункта, где началась операция перетаскивания.
lParam
Дескриптор меню, содержащего этот пункт.

Возвращаемые значения
Прикладная программа должна возвратить, одно из ниже перечисленных значений.

  • MND_CONTINUE - Меню должно остаться активным. Если мышь отпускается, это событие должно быть проигнорировано.
  • MND_ENDMENU - Меню должно быть закончено.

Замечания
Прикладная программа в ответ на это сообщение может вызвать функцию DoDragDrop.
Чтобы создать перетаскиваемое меню, вызовите функцию SetMenuInfo с флажком MNS_DRAGDROP.

Смотри также
DoDragDrop, SetMenuInfo

Размещение и совместимость WM_MENUDRAG

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Включена в Windows 98/ NT/2000


11.19.2.12 - Уведомляющее сообщение WM_MENUGETOBJECT

Уведомляющее сообщение WM_MENUGETOBJECT отправляется владельцу перетаскиваемого меню, когда курсор мыши входит в пункт меню или перемещается от центра пункта к вершине или основанию пункта.

Синтаксис

WM_MENUGETOBJECT
    WPARAM wParam
    LPARAM lParam;

Параметры
wParam
Этот параметр не используется.
lParam
Указатель на структуру MENUGETOBJECTINFO.

Возвращаемые значения
Приложение должно возвратить одно из нижеследующих значений:

  • MNGO_NOERROR - Указатель интерфейса был возвращен в члене pvObj структуры MENUGETOBJECTINFO.
  • MNGO_NOINTERFACE - Этот интерфейс не поддерживается.

Смотри также
MENUGETOBJECTINFO

Размещение и совместимость WM_MENUGETOBJECT

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Включена в Windows 98/ NT/2000


11.19.2.13 - Уведомляющее сообщение WM_MENURBUTTONUP

Уведомляющее сообщение WM_MENURBUTTONUP отправляется тогда, когда пользователь отпускает правую кнопку мыши, в то время как курсор находится на пункте меню.

Синтаксис

WM_MENURBUTTONUP

    WPARAM wParam
    LPARAM lParam;

Параметры
wParam
Устанавливает позицию пункта, когда мышь была отпущена.
lParam
Дескриптор меню, содержащего пункт.

Возвращаемые значения
Возвращаемых значений нет.

Замечания
Сообщение WM_MENURBUTTONUP позволяет прикладным программам, чтобы предоставить контекстно-зависимое меню - известное также как контекстное меню — для пункта меню, определяемого в этом сообщении. Чтобы показать на экране контекстно-зависимое меню для пункта меню, вызовите функцию TrackPopupMenuEx с флажком TPM_RECURSE.

Смотри также
TrackPopupMenuEx

Размещение и совместимость WM_MENURBUTTONUP

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Включена в Windows 98/ NT/2000


11.19.2.14 - Сообщение WM_MENUSELECT

Сообщение WM_MENUSELECT отправляется окну владельца меню тогда, когда пользователь выбирает пункт меню.

Синтаксис

WM_MENUSELECT
uItem = (UINT) LOWORD(wParam);   	// пункт меню или индекс подменю
fuFlags = (UINT) HIWORD(wParam); 	// флажки меню
hmenu = (HMENU) lParam;          	// дескриптор меню, по которому щелкнули мышью

Параметры
uItem
Значение младшего слова wParam. Если выбранный элемент - командный элемент, этот параметр содержит идентификатор пункта меню. Если выбранный элемент открывает выскакивающее меню или подменю, этот параметр содержит индекс выскакивающего меню или подменю, в основном меню, а параметр hMenu тогда содержит дескриптор главного (по которому щелкнули) меню; используйте функцию GetSubMenu, чтобы получить дескриптор меню выскакивающего меню или подменю.
fuFlags
Значение старшего слова wParam. Определяет один или несколько флажков меню. Этот параметр может быть комбинацией следующих значений:

  • MF_BITMAP - Элемент отображает точечный рисунок.
  • MF_CHECKED - Элемент проверен.
  • MF_DISABLED - Элемент блокирован.
  • MF_GRAYED - Элемент недоступен.
  • MF_HILITE - Элемент выделен.
  • MF_MOUSESELECT - Элемент выбран при помощи мыши.
  • MF_OWNERDRAW - Элемент является элемент "собственным" (нарисованным пользователем).
  • MF_POPUP - Элемент открывает раскрывающееся меню или подменю.
  • MF_SYSMENU - Элемент содержится в меню окна (известное также как Системное или Управляющее меню). Параметр hmenu идентифицирует меню окна, связанное с сообщением.

hmenu
Значение lParam. Идентифицирует меню, по которому щелкнули мышью.

Возвращаемые значения
Если приложение обрабатывает это сообщение, оно должно возвратить нуль.

Замечания
Если параметр fuFlags содержит 0xFFFF, а параметр hmenu содержит ПУСТО (NULL), значит Windows закрыла меню.
Не используйте для fuFlags значение - (минус) 1. Это делается потому, что fuFlags определен как (UINT) HIWORD (wParam). Если бы HIWORD (wParam) были 0xFFFF, fuFlags (из-за приведения UINT) был бы 0x0000FFFF, а не - (минус)1.

Смотри также
GetSubMenu

Размещение и совместимость WM_MENUSELECT

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.2.15 - Уведомляющее сообщение WM_NEXTMENU

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

Синтаксис

WM_NEXTMENU
    WPARAM wParam
    lpMdiNextMenu = (LPMDINEXTMENU) lParam;

Параметры
wParam
Определяет код виртуальной клавиши для клавиши.
lpMdiNextMenu
Указатель на структуру MDINEXTMENU, которая содержит информацию о меню, которое будет активизировано.

Возвращаемые значения
Возвращаемых значений нет.

Замечания
В ответ на это сообщение, приложение может задать меню, которое будет переключаться в члене hmenuNext структуры MDINEXTMENU и окно, которое будет получить уведомительные сообщения меню в члене hwndNext этой же структуры. Вы должны установить оба члена для переключения, чтобы получить желаемый результат (они вначале имеют значение ПУСТО (NULL)).

Смотри также
MDINEXTMENU

Размещение и совместимость WM_NEXTMENU

Windows NT			Да (вер. 4.0)
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.2.16 - Сообщение WM_SYSCOMMAND

Окно получает это сообщение тогда, когда пользователь выбирает команду из меню окна (известное также как Системное меню или Меню управления) или когда пользователь выбирает кнопку Развернуть (Maximize) или кнопку Свернуть (Minimize).

Синтаксис

WM_SYSCOMMAND
uCmdType = wParam;		// затребованный тип системной команды
xPos = LOWORD(lParam);	// горизонтальная позиция, в экранных координатах
yPos = HIWORD(lParam);	// вертикальная позиция, в экранных координатах

Параметры
uCmdType
Определяет тип запрошенной системной команды. Он может быть одним из этих значений:

  • SC_CLOSE - Закрывает окно.
  • SC_CONTEXTHELP - Изменяет курсор на указатель с вопросительным знаком. Если пользователь затем щелкает кнопкой мыши по органу управления в диалоговом окне, элемент управления получает сообщение WM_HELP.
  • SC_DEFAULT - Выбирает заданный по умолчанию пункт; пользователь дважды щелкнул мышью по меню окна.
  • SC_HOTKEY - Активизирует окно, связанное с определяемой прикладной программой последовательностью клавиш-ускорителей "hot key". Младшее слово lParam идентифицирует окно, которое активизируется.
  • SC_HSCROLL - Прокрутка содержимого окна по горизонтали.
  • SC_KEYMENU - Извлекает данные о меню окна в результате нажатия клавиши.
  • SC_MAXIMIZE (или SC_ZOOM) - Развертывает окно.
  • SC_MINIMIZE (или SC_ICON) - Свертывает окно.
  • SC_MONITORPOWER - Только для Windows 95: Устанавливает состояние дисплея. Эта команда поддерживает устройства, которые имеют энергосберегающие функции, типа персонального компьютера с батарейным питанием.
  • SC_MOUSEMENU - Извлекает данные о меню окна в результате щелчка клавиши мыши.
  • SC_MOVE - Перемещает окно.
  • SC_NEXTWINDOW - Перемещает в следующее окно.
  • SC_PREVWINDOW - Перемещает в предыдущее окно.
  • SC_RESTORE - Восстанавливает окно в обычной позиции и размере.
  • SC_SCREENSAVE - Запускает программу-заставку приложения, определяемую в разделе [boot] (начальной загрузки) файла SYSTEM.INI.
  • SC_SIZE - Изменяет размеры окна.
  • SC_TASKLIST - Запускает или активизирует Windows Task Manager (Диспетчер задач).
  • SC_VSCROLL - Прокрутка содержимого окна по вертикали.

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

yPos
Определяет вертикальную позицию курсора, в экранной системе координат, если команда меню окна выбрана при помощи мыши. Этот параметр является – (минус) 1, если команда выбрана, с использованием клавиши - ускорителя системы, или нуль, если использовалась мнемоника.

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

Замечания
Функция DefWindowProc завершает запрос меню окна о предопределенных действиях, перечисленных в предыдущей таблице.
В сообщениях WM_SYSCOMMAND, четыре младших бита параметра uCmdType используются для внутренних потребностей Windows. Чтобы получить правильный результат при проверке значения uCmdType, прикладная программа должна объединить значение 0xFFF0 со значением uCmdType при помощи использования побитового оператора AND.
Пункты в меню окна могут быть изменены при помощи использования функций GetSystemMenu, AppendMenu, InsertMenu, ModifyMenu, InsertMenuItem и SetMenuItem. Прикладные программы, которые изменяют меню окна, должны обрабатывать сообщения WM_SYSCOMMAND.
Прикладная программа может выполнить любую команду системы в любое время, передавая сообщение WM_SYSCOMMAND в DefWindowProc. Любые сообщения WM_SYSCOMMAND, не обработанные программой должны быть переданы в DefWindowProc. Любые значения команд, добавленные приложением, должны быть обработаны прикладной программой и не могут быть переданы в DefWindowProc.
Клавиши-ускорители, которые определены для выбора пунктов из меню окна, транслируются в сообщения WM_SYSCOMMAND; все другие нажатия клавиш - ускорителей транслируются в сообщения WM_COMMAND.

Смотри также
AppendMenu, DefWindowProc, GetSystemMenu, InsertMenu, ModifyMenu, WM_COMMAND

Размещение и совместимость WM_SYSCOMMAND

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.2.17 - Уведомляющее сообщение WM_UNINITMENUPOPUP

Уведомляющее сообщение WM_UNINITMENUPOPUP отправлется тогда, когда "выскакивающее" меню или подменю было разрушено.

Синтаксис

WM_UNINITMENUPOPUP
    WPARAM wParam
    LPARAM lParam;

Параметры
wParam
Дескриптор меню.
lParam
Старшее слово идентифицирует меню, которое было разрушено. В настоящее время, это может быть только MF_SYSMENU (меню окна).

Возвращаемые значения
Возвращаемых значений нет.

Замечания
Если прикладная программа получает сообщение WM_INITMENUPOPUP, она получит и сообщение WM_UNINITMENUPOPUP.

Смотри также
HIWORD

Размещение и совместимость WM_UNINITMENUPOPUP

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Включена в Windows 98/ NT/2000


11.19.3 - Структуры меню

Нижеследующие структуры используются меню.
MDINEXTMENU
MENUBARINFO
MENUEX_TEMPLATE_HEADER
MENUEX_TEMPLATE_ITEM
MENUGETOBJECTINFO
MENUINFO
MENUITEMINFO
MENUITEMTEMPLATE
MENUITEMTEMPLATEHEADER
TPMPARAMS


11.19.3.1 - Структура MDINEXTMENU

Структура MDINEXTMENU содержит информацию о меню, которое будет активизировано.

Синтаксис

typedef struct tagMDINEXTMENU {
    HMENU hmenuIn;
    HMENU hmenuNext;
    HWND hwndNext;
} MDINEXTMENU, *PMDINEXTMENU;

Члены сруктуры
hmenuIn
Принимает дескриптор текущего меню.
hmenuNext
Определяет дескриптор меню, которое будет активизировано.
hwndNext
Определяет дескриптор окна, которое приметуведомительные сообщения меню.

Смотри также
WM_NEXTMENU

Размещение и совместимость MDINEXTMENU

Windows NT			Да (вер. 4.0)
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.3.2 - Структура MENUBARINFO

Структура MENUBARINFO содержит информацию о горизонтальном меню.

Синтаксис

typedef struct tagMENUBARINFO {
    DWORD cbSize;
    RECT rcBar;
    HMENU hMenu;
    HWND hwndMenu;
    BOOL fBarFocused:1;
    BOOL fFocused:1;
} MENUBARINFO, *PMENUBARINFO;

Члены сруктуры
cbSize
Определяет размер структуры, в байтах. Вызывающая программа должна установить этот член в sizeof (MENUBARINFO).
rcBar
Указатель на структуру RECT, которая устанавливает координаты горизонтального меню, выскакивающего меню или пункта меню.
hMenu
Дескриптор горизонтального или выскакивающего меню.
hwndMenu
Дескриптор подменю.
fBarFocused
Если горизонтальное или выскакивающее меню имеет фокус, этот параметр - ИСТИНА (TRUE). Иначе, этот параметр - ЛОЖЬ (FALSE).
fFocused
Если пункт меню имеет фокус, этот параметр - ИСТИНА (TRUE). Иначе, этот параметр - ЛОЖЬ (FALSE).

Смотри также
GetMenuBarInfo, RECT

Размещение и совместимость MENUBARINFO

Windows NT			Да (вер. 4.0)
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Включен в Windows 98/ NT 4.0 Service Pack 6


11.19.3.3 - Структура MENUEX_TEMPLATE_HEADER

Структура MENUEX_TEMPLATE_HEADER определяет заголовок расширенного шаблона меню. Определение структуры, данное здесь - только для объяснения; оно не представлено в каком-либо стандартном заголовочном файле.

Синтаксис

// typedef struct  {
//     WORD  wVersion;
//     WORD  wOffset;
//     DWORD dwHelpId;
// } MENUEX_TEMPLATE_HEADER;

Члены структуры
wVersion
Номер версии шаблона. Этот член должен быть равен 1 для расширенных шаблонов меню.
wOffset
Смещение первой структуры MENUEX_TEMPLATE_ITEM, относительно конца этого члена структуры. Если первый пункт определяется непосредственно следом за членом dwHelpId, этот член должен быть равен 4.
dwHelpId
Идентификатор пункта Справка (Help) горизонтального меню

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

Смотри также
LoadMenuIndirect, MENUEX_TEMPLATE_ITEM

Размещение и совместимость MENUEX_TEMPLATE_HEADER

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			-
Unicode				-
Замечания по платформе		Не имеется


11.19.3.4 - Структура MENUEX_TEMPLATE_ITEM

Структура MENUEX_TEMPLATE_ITEM определяет пункт меню в расширенном шаблоне. Определение структуры, данное здесь - только для объяснения; она не представлена в каком-либо стандартном заголовочном файле.

Синтаксис

// typedef struct {
//	DWORD dwType;
//	DWORD dwState;
//	UINT uId;
//	WORD bResInfo;
//	WCHAR szText[1];
//	DWORD dwHelpId;
// } MENUEX_TEMPLATE_ITEM;

Члены структуры
dwType
Тип пункта меню. Этот член может быть комбинацией типов (начинающихся с MFT) значений, перечисляемых структурой MENUITEMINFO.
dwState
Состояние пункта меню. Этот член может быть комбинацией значений состояний (начинающихся с MFS), перечисляемых структурой MENUITEMINFO.
uId
Идентификатор пункта меню. Это - определяемое программой 16-разрядное значение, которое идентифицирует пункт меню. В расширенном ресурсе меню, пункты, которые открывают "выскакивающие" меню или подменю также как командные пункты могут иметь идентификаторы.
bResInfo
Значение, устанавливающее, является ли пункт меню последним пунктом в горизонтальном, "выскакивающем " меню, подменю или контекстном меню и является ли он пунктом, который, открывает "выскакивающее " меню или подменю. Этот член может быть нулевым или иметь такие значения:

  • 0x80 - Структура определяет последний пункт меню в горизонтальном, "выскакивающем" меню, подменю или контекстном меню.
  • 0x01 - Структура определяет пункт, который открывает "выскакивающее" меню или подменю. Последующие структуры определяют пункты меню в соответствующем "выскакивающем" меню или подменю.

Для 32-разрядных прикладных программ, этот член - СЛОВО (WORD); для 16-разрядных прикладных программ, это - БАЙТ (BYTE).

szText
Текст пункта меню. Этот член, который является строкой Уникода с нулевым символом в конце, выравнивается по границе слова. Размер пункта меню определяется вариантами, зависящими от длины этой строки.
dwHelpId
Идентификатор Справки (Help) для "выскакивающего" меню или подменю. Этот член, который включается только для пунктов, которые открывают "выскакивающие" меню или подменю, помещается в начале границы двойного слова, следом за членом szText переменной длины.

Замечания
Расширенный шаблон меню состоит из структуры MENUEX_TEMPLATE_HEADER, сопровождаемой одной или несколькими следующими друг за другом структурами MENUEX_TEMPLATE_ITEM. Структуры MENUEX_TEMPLATE_ITEM, которые являются переменными по длине, выравниваются на границах двойного слова. Чтобы создать меню из расширенного шаблона меню в памяти, используйте функцию LoadMenuIndirect.

Смотри также
LoadMenuIndirect, MENUEX_TEMPLATE_HEADER, MENUITEMINFO

Размещение и совместимость MENUEX_TEMPLATE_ITEM

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			-
Unicode				-
Замечания по платформе		Не имеется


11.19.3.5 - Структура MENUGETOBJECTINFO

Структура MENUGETOBJECTINFO содержит информацию о меню, который включился курсором мыши.

Синтаксис

typedef struct tagMENUGETOBJECTINFO {
    DWORD  dwFlags;
    UINT  uPos;
    HMENU  hmenu;
    PVOID  riid;
    PVOID  pvObj;
} MENUGETOBJECTINFO, *PMENUGETOBJECTINFO;

Члены сруктуры
dwFlags
Позиция курсора мыши относительно пункта, указанного параметром uPos. Это может быть одним из следующих значений:

  • MNGOF_BOTTOMGAP - Мышь находится внизу элемента, указанного параметром uPos.
  • MNGOF_TOPGAP - Мышь находится наверху элемента, указанного uPos.

uPos
Позиция пункта включенного курсором мыши.
hmenu
Дескриптор меню, которое включил курсор мыши.
riid
Идентификатор требуемого интерфейса. В настоящее время это может только быть IDropTarget.
pvObj
Указатель на интерфейс, соответствующий члену riid структуры. Этот указатель должен быть возвращен приложением при обработке сообщения.

Замечания
Структура MENUGETOBJECTINFO используется только в перетаскиваемых меню. Когда отправляется сообщение WM_MENUGETOBJECT, параметр lParam - указатель на эту структуру.
Чтобы создать перетаскиваемое меню, вызовите функцию SetMenuInfo с установленным флажком MNS_DRAGDROP.

Смотри также
SetMenuInfo, IDropTarget, WM_MENUGETOBJECT

Размещение и совместимость MENUBARINFO

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Включен в Windows 98/NT/2000


11.19.3.6 - Структура MENUINFO

Структура MENUINFO содержит информацию о меню.

Синтаксис

typedef struct tagMENUINFO {
    DWORD cbSize;
    DWORD fMask;
    DWORD dwStyle;
    UINT cyMax;
    HBRUSH hbrBack;
    DWORD dwContextHelpID;
    ULONG_PTR dwMenuData;
} MENUINFO, FAR *LPMENUINFO;
typedef MENUINFO CONST FAR *LPCMENUINFO;

Члены сруктуры
cbSize
Размер структуры, в байтах. Вызывающая программа должна установить этот параметр в sizeof (MENUINFO).
fMask
Члены структуры, которые извлекаются или устанавливаются (исключение для MIM_APPLYTOSUBMENUS). Этот член может быть один или несколько из ниже перечисленных значений:

  • MIM_APPLYTOSUBMENUS - Параметры настройки применяются к меню и всем его подменю. Функция SetMenuInfo использует этот флажок, а GetMenuInfo игнорирует этот флажок.
  • MIM_BACKGROUND - Извлекает или устанавливает член hbrBack структуры.
  • MIM_HELPID - Извлекает или устанавливает член dwContextHelpID структуры.
  • MIM_MAXHEIGHT - Извлекает или устанавливает член cyMax структуры.
  • MIM_MENUDATA - Извлекает или устанавливает член dwMenuData структуры.
  • MIM_STYLE - Извлекает или устанавливает член dwStyle структуры.

dwStyle
Стиль меню. Этот член может быть одно или несколько из ниже перечисленных значений:

  • MNS_AUTODISMISS - Меню автоматически закрвается, когда мышь находится вне меню приблизительно через 10 секунд.
  • MNS_CHECKORBMP - Одно и то же пространство резервируется для галочки и точечного рисунка. Если галочка рисуется, точечный рисунок - нет. Все галочки и рисунки выравниваются. Используется для меню, где некоторые пункты используют галочки, а некоторые используют точечные рисунки.
  • MNS_DRAGDROP - Пункты меню являются OLE целевыми пунктами перемещения данных или источниками перемещаемых данных. Владелец меню получает сообщения WM_MENUDRAG и WM_MENUGETOBJECT.
  • MNS_MODELESS - Меню является немодальным; то есть, нет никакого меню с модальным циклом обработки сообщений, в то время как меню активно.
  • MNS_NOCHECK - Пространство слева от пункта для галочки не резервируется. Пункт может все еще выбираться, но галочка не будет появляться рядом с пунктом.
  • MNS_NOTIFYBYPOS - Владелец меню, когда пользователь делает выбор, получает сообщение WM_MENUCOMMAND вместо сообщения WM_COMMAND.

cyMax
Максимальная высота меню в пикселях. Когда пункты меню превышают доступное пространство, автоматически используются линейки прокрутки. Значение по умолчанию (0) является экранной высотой.
hbrBack
Кисть, которая используется для фона меню.
dwContextHelpID
Идентификатор контекстной справки. Это - то же самое значение, используемое в функциях GetMenuContextHelpId и SetMenuContextHelpId.
dwMenuData
Значение определяемое прграммой.

Смотри также
GetMenuInfo, GetMenuContextHelpId, SetMenuInfo, SetMenuContextHelpId, WM_COMMAND, WM_MENUCOMMAND, WM_MENUDRAG, WM_MENUGETOBJECT

Размещение и совместимость MENUINFO

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Включен в Windows 98/NT/2000


11.19.3.7 - Структура MENUITEMINFO

Структура MENUITEMINFO содержит информацию о пункте меню.

Синтаксис

typedef struct tagMENUITEMINFO {
    UINT cbSize;
    UINT fMask;
    UINT fType;
    UINT fState;
    UINT wID;
    HMENU hSubMenu;
    HBITMAP hbmpChecked;
    HBITMAP hbmpUnchecked;
    DWORD dwItemData;
    LPTSTR  dwTypeData;
    UINT cch;
} MENUITEMINFO, FAR *LPMENUITEMINFO;

Члены сруктуры
cbsize
Размер структуры, в байтах.
fMask
Члены структуры, которые извлекаются или устанавливаются. Этот член структуры может иметь одно или несколько этих значений:

  • MIIM_CHECKMARKS - Получает или устанавливает члены структуры hbmpChecked и hbmpUnchecked.
  • MIIM_DATA - Получает или устанавливает член структуры dwItemData.
  • MIIM_ID - Получает или устанавливает член структуры wID.
  • MIIM_STATE - Получает или устанавливает член структуры fState.
  • MIIM_SUBMENU - Получает или устанавливает член структуры hSubMenu.
  • MIIM_TYPE - Получает или устанавливает члены структуры fType и dwTypeData.

fType
Тип пункта меню. Этот член стуктуры может иметь одно или несколько этих значений:

  • MFT_BITMAP - Показывает на экране пункт меню, используя точечный рисунок. Младшее слово члена структуры dwTypeData - дескриптор точечного рисунка, а член cch игнорируется.
  • MFT_MENUBARBREAK - Помещает пункт меню в новую строку (для горизонтального меню) или в новый столбец (для "выскакивающего" меню, подменю, или контекстного меню). Для "выскакивающего" меню, подменю, или контекстного меню, вертикальная черта отделяет новый столбец от старого.
  • MFT_MENUBREAK - Помещает пункт меню в новую строку (для горизонтального меню) или в новом столбце (для "выскакивающего" меню, подменю, или контекстного меню). Для "выскакивающего" меню, подменю, или контекстного меню, столбцы не отделяются вертикальной чертой.
  • MFT_OWNERDRAW - Присваивает ответственность за прорисовку пункта меню к окну, которое владет меню. Окно получает сообщение WM_MEASUREITEM прежде, чем меню покажется на экране впервые, а сообщение WM_DRAWITEM всякий раз, когда внешний вид пункта меню должен быть модифицирован. Если это значение определено, член структуры dwTypeData содержит определяемое программой 32-разрядное значение.
  • MFT_RADIOCHECK - Показывает на экране отмеченные маркером пункты меню, используя вместо "галочки" переключатель радиокнопок в том случае, если член структуры hbmpChecked имеет значение ПУСТО (NULL).
  • MFT_RIGHTJUSTIFY - Выравненный справа пункт меню и любые последующие пункты. Это значение допустимо, только в том случае, если пункт меню находится в горизонтальном меню.
  • MFT_SEPARATOR - Устанавливает, что пункт меню - разделитель. Разделитель пункта меню появляется как горизонтальная разделительная линия. Члены структуры dwTypeData и cch игнорируются. Это значение допустимо только в "выскакивающем" меню, подменю или контекстном меню.
  • MFT_STRING - Показывает на экране пункт меню, используя текстовую строку. Член стуктуры dwTypeData - указатель на строку с символом нуля в конце, а член cch равен длине строки.

Значения MFT_BITMAP, MFT_SEPARATOR и MFT_STRING не могут быть объединены друг с другом.
fState
Состояние пункта меню. Этот член стуктуры может иметь одно или несколько этих значений:

  • MFS_CHECKED - Отмечает "галочкой" пункт меню. Для получения дополнительной информации об установке отметок "галочкой" пунктов меню, см. член структуры hbmpChecked.
  • MFS_DEFAULT - Устанавливает, что пункт меню задан по умолчанию. Меню может содержать только один заданный по умолчанию пункт меню, который отображается полужирным шрифтом.
  • MFS_DISABLED - Отключает пункт меню так, чтобы он не мог быть выбран, но не окрашивает его в серый цвет (не делает недоступным).
  • MFS_ENABLED - Включает пункт меню так, чтобы он мог быть выбран. Это - заданное по умолчанию состояние.
  • MFS_GRAYED - Отключает пункт меню и окрашивает его в серый цвет (делает недоступным) так, чтобы он не мог быть выбран.
  • MFS_HILITE - Выделяет цветом пункт меню.
  • MFS_UNCHECKED - Снимает "галочку" в пункте меню. Для получения дополнительной информации о снятии "галочки" у пунктов меню, см. член hbmpUnchecked.
  • MFS_UNHILITE - Удаляет подсветку (выделение) пункта меню. Это - заданное по умолчанию состояние.

wID
Определяемое программой 16-разрядное значение, которое идентифицирует пункт меню.
hSubMenu
Дескриптор "выскакивающего" меню или подменю, связанного с пунктом меню. Если пункт меню - не пункт, который открывает "выскакивающее" меню или подменю, этот член имеет значение ПУСТО (NULL).
hbmpChecked
Дескриптор точечного рисунка, который показывается на экране рядом с пунктом, если он отмечен "галочкой". Если этот член структуры имеет значение ПУСТО (NULL), используется заданный по умолчанию точечный рисунок. Если определено значение типа MFT_RADIOCHECK, заданный по умолчанию точечный рисунок – жирная точка. Иначе, это - галочка.
hbmpUnchecked
Дескриптор точечного рисунка, который показывается на экране рядом с пунктом, если он не отмечен "галочкой". Если этот член имеет значение ПУСТО (NULL), никакой рисунок не используется.
dwItemData
Определяемое программой значение, связанное с пунктом меню.
dwTypeData
Содержание пункта меню. Значение этого члена структуры зависит от типа пункта меню: MFT_BITMAP, MFT_SEPARATOR или MFT_STRING.
cch
Длина текста пункта меню, когда информация принимается о пункте меню типа MFT_STRING. Это значение нулевое для других типов пункта меню. Этот член структуры игнорируется, когда содержание пункта меню установлено.

Замечания
Структура MENUITEMINFO используется функциями GetMenuItemInfo, InsertMenuItem и SetMenuItemInfo.

Смотри также
GetMenuItemInfo, InsertMenuItem, SetMenuItemInfo, WM_DRAWITEM, WM_MEASUREITEM.


11.19.3.8 - Структура MENUITEMTEMPLATE

Структура MENUITEMTEMPLATE определяет пункт меню в шаблоне меню.

Синтаксис

typedef struct {			// mit
    WORD mtOption;		// флажки пункта меню
    WORD mtID;		// идентификатор пункта меню (опускается для пунктов
                // открывающих выскакивающее меню)
    WCHAR mtString[1];		// строка с нулем в конце для пункта меню
} MENUITEMTEMPLATE;

Члены структуры
mtOption
Устанавливает один или несколько нижеследующих предопределенных параметров меню, которые управляют внешним видом пункта меню:

  • MF_CHECKED - Указывает, что пункт меню рядом с собой имеет галочку.
  • MF_GRAYED - Указывает, что пункт меню с самого начала неактивный и нарисован с серым эффектом (недоступен).
  • MF_HELP - Указывает, что пункт меню имеет вертикальный разделитель со своей левой стороны.
  • MF_MENUBARBREAK - Указывает, что пункт меню помещен в новом столбце. Старые и новые столбцы отделены полосой.
  • MF_MENUBREAK - Указывает, что пункт меню помещен в новом столбце.
  • MF_OWNERDRAW - Указывает, что окно владелец меню ответственно за прорисовку всех визуальных элементов пункта меню, включая выделение, установку "галочки" и неактивного состояния. Этот параметр не допустим для пункта в горизонтальном меню.
  • MF_POPUP - Указывает, что это пункт один из тех, который, открывает "выскакивающее" меню или подменю.

mtID
Устанавливает идентификатор командный пункта меню; командный пункт отправляет сообщение о команде своему окну владельцу. Структура MENUITEMTEMPLATE для пункта, который открывает "выскакивающее" меню или подменю, не содержит члена структуры.
mtString
Устанавливает строку с символом нуля в конце для пункта меню.

Смотри также
LoadMenuIndirect, MENUITEMTEMPLATEHEADER

Размещение и совместимость MENUITEMTEMPLATE

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.3.9 - Структура MENUITEMTEMPLATEHEADER

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

Синтаксис

typedef struct {			// mith
    WORD versionNumber;	// номер версии, должен быть нуль
    WORD offset;		// смещение первой структуры MENUITEMTEMPLATE
} MENUITEMTEMPLATEHEADER;

Члены структуры
versionNumber
Устанавливает номер версии. Этот член должен быть нулевой.
offset
Устанавливает смещение, в байтах, от конца заголовка. Перечисление пунктов меню начинается с этого смещения. Обычно, этот член структуры нулевой, а список пунктов меню следует непосредственно после заголовка.

Замечания
Одна или несколько структур MENUITEMTEMPLATE объединяются, чтобы сформировать список пунктов меню.

Смотри также
LoadMenuIndirect, MENUITEMTEMPLATE

Размещение и совместимость MENUITEMTEMPLATEHEADER

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


11.19.3.10 - Структура TPMPARAMS

Структура TPMPARAMS содержит расширенные параметры для функции TrackPopupMenuEx.

Синтаксис:

typedef struct tagTPMPARAMS {
    UINT cbSize;
    RECT rcExclude;
} TPMPARAMS, FAR *LPTPMPARAMS;

Члены структуры
cbsize
Размер структуры, в байтах.
rcExclude
Исключающий прямоугольник при позиционировании окна, в экранной системе координат.

Смотри также
TrackPopupMenuEx, Rectangle

Размещение и совместимость TPMPARAMS

Windows NT				Да
Win95					Да
Win32s					Нет
Импортируемая библиотека			-
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется
Предыдущий Шаг


В качестве Введения

Источником этого материала послужил в основном справочный файл Win32.hlp из пакета Borland C++ версии 5.02.

Сначала была потребность разобраться с основами API Win32 непосредственно из первоисточника, созданного авторами Windows. Поискал в Интернете, прочитал то, что там нашел. Показалось мало. Решил, что буду сам переводить этот материал и, в ходе перевода, заодно, буду разбираться со всеми этими понятиями, функциями, структурами и т. д. По ходу дела зашел уже довольно далеко - перевел 13 разделов, а сейчас работаю над разделом Menu.

Не планировал пропагандировать свою работу, так как я не профессиональный переводчик и предназначал ее только для себя.

Но коль так получается, что кому-то это интересно, то предоставляю возможность всем желающим прочитать этот раздел API и высказать свое суждение по его содержанию, и нужен ли такой тяжелый материал русскоязычной аудитории Интернета.

Единственно не приму замечаний, касающихся примеров программ они скпированы один к одному из руководства. Так что все претензии в этом вопросе к Microsoft.

Владивосток. Владимир Соковиков

Я очень благодарен Владимиру за предоставленный материал, работа проделана просто безумная. В конце шагов я буду добавлять ссылки на материалы которые есть на сайте по этой же теме. Артем.

Следующий Шаг


1 - Окно.

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


1.1 Об окнах

Окна являются основным средством графической прикладной программы, базирующейся на Win32, которые взаимодействуют с пользователем и выполняют задачи, поэтому одной из первых задач графического приложения, базирующегося на Win32, является создание окна. Этот обзор описывает элементы прикладного программного интерфейса (API) Microsoft ® Win32 ®, который прикладные программы используют, чтобы создавать и использовать окна; управлять связями между ними; а также размером, перемещением и отображением окна на экране дисплея.


1.2 Окно Рабочего стола

Когда запускается Windows, он автоматически создает окно рабочего стола (desktop window). Окно рабочего стола - определяемое системой окно, которое окрашивает фон экрана и служит ядром для всех окон, отображаемых всеми прикладными программами.

Окно Рабочего стола использует точечный рисунок, чтобы прорисовывать фон экрана. Узор, создаваемый точечным рисунком называется обоями рабочего стола (desktop wallpaper). По умолчанию, окно рабочего стола использует точечный рисунок из файла .BMP, который определен в системном реестре, как обои рабочего стола.

Функция GetDesktopWindow возвращает дескриптор окна рабочего стола.

Прикладная программа конфигурации системы, типа аплета Панель Управления (Control Panel), изменяет настольные обои рабочего стола, используя функцию SystemParametersInfo с параметром wAction, установленным в SPI_SETDESKWALLPAPER и параметром lpvParam, определяющим имя файла растровой картинки. Тогда SystemParametersInfo загружает точечный рисунок из заданного файла, используя его, чтобы окрасить фон экрана, и вводит новое имя файла в системный реестр.

Дополнительная информация на сайте.

"Шаг 133 - Рабочий стол Windows маленький обзор"
"Шаг 20 - Значки элементов рабочего стола"
"Шаг 33 - Где в реестре хранятся настойки рабочего стола"
"Шаг 1 - Окна Windows и функции доступа к ним"
"Шаг 5 - GetWindowDC и рабочий стол"
"Шаг 149 - SystemParametersInfo и смена рисунка рабочего стола"


1.3 Окна прикладной программы

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

Когда Вы запускаете прикладную программу, система к тому же связывает кнопку панели задач с прикладной программой. Кнопка панели задач (taskbar button) содержит пиктограмму и заголовок программы. Когда прикладная программа активная, ее кнопка на панели задач отображается в нажатом состоянии.


1.4 Компоненты окна прикладной программы

Окно прикладной программы включает в себя такие элементы как, строка заголовка, стро-ка меню, меню окна (прежде известное как системное меню), кнопка свертывания окна, кнопка развертывания окна, кнопка восстановления, кнопка закрытия окна, рамка установки размеров, рабочая область, линейка горизонтальной прокрутки и линейка вертикальной прокрутки. Главное окно прикладной программы обычно включает в себя все эти компоненты. Иллюстрация ниже показывает эти компоненты в типичном главном окне.

6_1.gif (18312 b)

1 - системное меню				2 - строка заголовка
3 - строка меню				4 - кнопка свертывания
5 - кнопка развертывания			6 - рабочая область
7 - линейка горизонтальной прокрутки		8 - линейка вертикальной прокрутки

Строка заголовка (title bar) отображает на экране заданную прикладной программой пиктограмму и строку текста; обычно текст определяет имя прикладной программы или указывает предназначение окна. Прикладная программа определяет пиктограмму и текст, когда создается окно. К тому же, строка заголовка делает возможным для пользователя перемещение окна, используя мышь или другое устройство управления позицией.

Большинство прикладных программ включает в себя строку меню (menu bar), которая перечисляет команды, поддерживаемые прикладной программой. Пункты в строке меню представляют основные категории команд. Выбор пункта в строке меню обычно открывает выскакивающее меню, чьи пункты соответствуют задачам внутри данной категории. Выбирая команду, пользователь направляет прикладную программу на выполнение задачи.

Меню окна (window menu) создается и управляется при помощи Windows. Оно содержит стандартный набор пунктов меню, которые, когда выбираются пользователем, устанавливают размер или позицию окна, закрывают прикладную программу или выполняют задачи. Для получения дополнительной информации о меню и меню окна, см. статью Меню.

Когда Вы щелкаете мышью по кнопке развертывания или свертывания окна, она воздействует на размер и позицию окна. Когда пользователь щелкает мышью по кнопке развертывания (maximize button) окна, Windows увеличивает окно до размеров экрана и располагает окно так, что оно закрывает весь рабочий стол, минус панель задач. В то же самое время, Windows заменяет кнопку развертывания окна на кнопку восстановления прежнего размера. Кнопка восстановления (restore button)- точечный рисунок, по которому когда щелкнешь мышью, восстанавливает окно в его предыдущем размере и позиции.

Когда пользователь щелкает мышью по кнопке свертывания (minimize button) окна, Windows уменьшает окно до размера кнопки его панели задач, помещает окно над кнопкой панели задач и отображает на экране кнопку панели задач в ее нормальном состоянии. Чтобы восстановить прикладную программу в её предыдущем размере и позиции, щелкните мышью по её кнопке на панели задач.

Рамка установки размеров (sizing border) - зона по периметру окна, которая дает возможность пользователю изменять по величине окно, используя мышь или другое устройство управления позицией.

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

Линейка горизонтальной (horizontal scroll bar) и вертикальной (vertical scroll bar) прокрутки преобразуют ввод данных от мыши или клавиатуры в значения, которые прикладная программа использует, чтобы передвигать содержимое рабочей области по горизонтали или вертикали. Например, прикладная программа обработки текстов, которая отображает длинный документ, обычно предоставляет линейку вертикальной прокрутки, чтобы дать возможность пользователю перемещаться вверх и вниз по документу.

Строка заголовка, строка меню, меню окна, кнопки свертывания и развертывания окна, установка размера рамки и линейки прокрутки, рассматриваются в собирательном значении как не рабочая область (nonclient area) окна. Windows управляет большинством аспектов не рабочей области; прикладная программа управляет всем остальным, что касается окна. В частности, прикладная программа управляет видом и поведением рабочей области.


1.5 Элементы управления, диалоговые окна и окна сообщений

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

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

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

Окно сообщений (message box) - окно, которое показывает на экране примечание, предостережение, или предупреждение пользователю. Например, окно сообщений может сообщать пользователю о проблеме, с которой прикладная программа столкнулась при выполнении задачи.

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


1.6 Z-последовательность (Z Order)

Z-последовательность (Z order) окна обозначает позицию окна в стеке перекрывающихся окон. Этот оконный стек ориентируется по воображаемой оси, z-оси (оси аппликат), уходящей за пределы экрана. Окно наверху Z-последовательности перекрывает все другие окна. Окно внизу Z-последовательности перекрыто всеми другими окнами.

Windows Z-последовательность сохраняет в обычном списке. Добавляя окна в Z-последовательность, она основывается на том, что в любом случае они самые верхние окна, окна верхнего уровня или дочерние окна. Самое верхнее окно (topmost window) накладывается на все другие не самые верхние окна, независимо от того, является ли они активными или приоритетными окнами. Самое верхнее окно имеет стиль WS_EX_TOPMOST. Все самые верхние окна появляются в Z-последовательности перед любыми не самыми верхними окнами. Дочернее окно сгруппировано со своим родителем в Z-последовательности.

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

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

Дополнительные материалы на сайте.


1.7 Создание окна

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

Win32 API предусматривает дополнительные функции - включая DialogBox, CreateDialog, и MessageBox - для создания окон специального назначения, таких как диалоговые окна и окна сообщений. Для получения дополнительной информации об этих функциях, см. Диалоговые окна.

Дополнительные материалы на сайте.


1.8 Атрибуты окна

Прикладная программа, когда создается окно, должна предоставить следующую информацию:

Класс окна (Window class)
Имя окна (Window name)
Стиль окна (Window style)
Родительское окно или окно владелец
Размеры
Размещение
Позицию на экране
Идентификатор дочернего окна или дескриптор меню
Дескриптор экземпляра
Данные для создания

В разделах ниже описываются эти атрибуты.

Класс окна

Каждое окно принадлежит определенному классу окна. Прикладная программа должна зарегистрировать класс окна перед созданием любого окна этого класса. Класс окна (window class) определяет большинство аспектов внешнего вида и поведения. Главный компонент класса окна - это оконная процедура (window procedure), функция которой получать и обрабатывать все вводимые данные и запросы, посланные окну. Окна предоставляют входные данные и запросы в форме сообщений (messages). Для большей информации о классах окна, оконных процедурах или сообщениях смотрите Классы окна, Оконные процедуры или Сообщения и Очереди сообщений.

Имя окна

Окно может иметь имя. Имя окна (window name) (называемое также оконный текст (window text)) - это текстовая строка, которая идентифицирует окно для пользователя. Главное окно, диалоговое окно или окно сообщения, если представлено, обычно показывает свое имя окна в своей строке заголовка. Для элемента управления внешний вид имени окна зависит от класса элементов управления. Кнопка, поле редактирования или статический элемент управления отображают свое оконное имя внутри прямоугольника, который занимает элемент управлением. Окно со списком, комбинированное окно или статический элемент управления не показывают имя своего окна.

Программа использует функцию SetWindowText, чтобы изменить имя окна после того, как окно создано. Она использует функции GetWindowTextLength и GetWindowText, чтобы сделать выборку текущего текста имени окна.

Стиль окна

Каждое окно имеет один или несколько стилей окна. Стиль окна (window style) - это име-нованная константа, которая определяет аспекты внешнего вида и поведения окна, которые не определяет класс окна. Например, класс SCROLLBAR создает линейку прокрутки, а стили SBS_HORZ и SBS_VERT определяют создание или горизонтальной или вертикальной линейки прокрутки. Несколько стилей окна применяют все окна, но большинство их применяют окна конкретного класса окна. Окна и, до некоторой степени, оконная процедура класса, интерпретируют стили.

Родительское или самостоятельное окно

Окно может иметь родительское окно. Окно, которое имеет родительское окно, называется дочерним окном (child window). Родительское окно (parent window) предоставляет систему координат, которая используется для позиционирования дочернего окна. Наличие родительского окна воздействует на аспекты внешнего вида окна; например, дочернее окно обрезается так, что-бы ни одна часть дочернего окна не могла появиться вне рамок своего родительского окна. Окно, у которого нет родительского окна или родитель которого самое главное окно, называется окном верхнего уровня (top-level window). Прикладная программа использует функцию EnumWindows, чтобы получить дескриптор каждого из своих окон верхнего уровня. Функция EnumWindows, в свою очередь, передает дескриптор каждого окна верхнего уровня в определенную программой функцию повторного вызова EnumWindowsProc.

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

Расположение, размер и позиция в Z-последовательности

Каждое окно имеет расположение, размер и позицию в Z-последовательности. Расположение - это координаты верхнего левого угла окна, относительно верхнего левого угла экрана или, в случае дочернего окна, верхнего левого угла рабочей области родителя. Размер окна - это его ширина и высота, измеряемая в пикселях. Позиция окна в Z-последовательности (Z order) - это позиция окна в стеке перекрывающихся окон. Для получения дополнительной информации, см "1.6 Z-последовательность (Z Order)".

Идентификатор Дочернего окна или дескриптор Меню

Дочернее окно может иметь идентификатор дочернего окна (child-window identifier), уникальное значение определенное программой, связанное с дочерним окном. Идентификаторы дочернего окна особенно полезны в прикладных программах, которые создают многочисленные дочерние окна. При создании дочернего окна, прикладная программа определяет идентификатор дочернего окна. После создания окна, прикладная программа может изменять идентификатор окна, используя функцию SetWindowLong, или может отыскать идентификатор, используя функцию GetWindowLong.

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

Дескриптор экземпляра

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

Данные создания

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

Дополнительные материалы на сайте.

"Подробности - О классах окон"
"Шаг 1 - Окна Windows и функции доступа к ним"
"Шаг 251 - Инициализация данных и события в DialogBar"
"Шаг 354 - Создание разных окон MDI"
"Шаг 49 - Меняем размер и икону диалогового окна"
"Шаг 2 - Три способа обновления информации на панелях CStatusBar"
"Шаг 134 - Смена курсора"


1.9 Дескрипторы окна

После создания окна, создающая функция возвращает дескриптор окна (window handle), который уникально идентифицирует окно. Прикладная программа использует этот дескриптор в других функциях, чтобы направить их действия на это окно. Дескриптор окна имеет тип данных HWND; прикладная программа должна использовать этот тип при объявлении переменной, которая содержит в себе дескриптор окна.

Win32 API включает в себя несколько специальных констант, которые могут заменять дескриптор окна в некоторых функциях. Например, прикладная программа может использовать HWND_TOPMOST в функции SendMessageTimeout, HWND_BROADCAST в функции SendMessage, или HWND_DESKTOP в функции MapWindowPoints.

Хотя константа ПУСТО (NULL) - не дескриптор окна, Вы можете использовать её в некоторых функциях, чтобы определить, нет ли воздействия на какое-либо окно. Например, установив значение ПУСТО (NULL) в параметре hwndParent функции CreateWindowEx, создается окно, у которого нет какого либо родителя или владельца. Некоторые функции могут возвращать значение ПУСТО (NULL) вместо дескриптора, указывая, что данное действие не применяется ни к какому окну.

Прикладная программа может использовать функцию FindWindow, чтобы обнаружить, существует ли в системе окно с определенным именем класса или именем окна. Если такое окно существует, FindWindow возвращает дескриптор окна. Чтобы ограничивать поиск в дочерних окнах отдельной прикладной программы, используйте функцию FindWindowEx. Функция IsWindow определяет, правильно ли идентифицирует дескриптор окна существующее окно.

Дополнительные материалы на сайте.

"Шаг 116 - Посылка сообщений между программи"
"Сообщение от элементов на диалоговом окне"
"Шаг 17 - Посылаем сообщение закрытия приложения"
"Шаг 6 - Рисуем в консольном окне"
"Шаг 3 - GetMenu"
"Шаг 6 - Связь окна с сокетом для получения сообщений"


1.10 Создание Главного окна

Каждая базирующаяся на Win32 прикладная программа должна иметь функцию WinMain как свою точку входа. Функция WinMain выполняет ряд задач, включая регистрацию класса окна для главного окна и создание этого главного окна. Функция WinMain регистрирует класс главного окна, путем вызова функции RegisterClass, и создает главное окно, вызывая функцию CreateWindowEx.

Проблема Мобильности Точка входа в программу не должна называться WinMain.

Ваша функция WinMain может также ограничить вашу прикладную программу единственным экземпляром. Создайте именованный mutex-объект (объект-статист), используя функцию CreateMutex. Если функция GetLastError возвращает ERROR_ALREADY_EXISTS, другой образец вашей прикладной программы существует (он создан mutex-объектом), и Вы должны выйти из вашей WinMain.

Windows автоматически не отображает на экране главное окно после его создания; чтобы отобразить его прикладная программа должна использовать функцию ShowWindow. После создания главного окна, функция прикладной программы WinMain вызывает ShowWindow, чтобы передать ей два параметра: дескриптор главного окна и флажок, определяющий, должно ли основное окно быть свернуто или развернуто, когда оно отображается в первый раз. Обычно, флажок может быть установлен для любой из констант, начинающихся SW_ префиксом. Однако, когда вызывается функция ShowWindow, чтобы показать главное окно прикладной программы, флажок должен быть установлен в SW_SHOWDEFAULT. Этот флажок сообщает, чтобы Windows отобразил окно как определено программой, которая запустила прикладную программу.

Если окно создано как окно Уникода (Unicode), оно принимает только сообщения в Уникоде (Unicode). Чтобы определить, является ли окно - окном Уникода (Unicode), вызывается функция IsWindowUnicode.

Дополнительные материалы на сайте:

  • "Шаг 4 - Окно Windows на С"
  • "Шаг 39 - RegisterClass()"
  • "Шаг 43 - CreateWindow()"
  • "Как делали MFC - Регистрируем окно"
  • "Шаг 118 - Функции CreateMutex() и ReleaseMutex()"
  • "Шаг 42 - Функция WinMain()"
  • "Шаг 9 - Синхронизация файловых операций Mutex"
  • "Шаг 335 - Mutex в MFC"
  • "Шаг 82 - Что такое взаимоисключение (Mutex)"
  • "Шаг 57 - Функции ShowWindow() и UpdateWindow()"
  • "Шаг 188 - Наборы символов"


1.11 Сообщения, создающие окно

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

При создании дочернего окна, Windows, после отправки сообщений WM_NCCREATE и WM_CREATE, посылает родительскому окну сообщение WM_PARENTNOTIFY. Он также посылает и другие сообщения при создании окна. Число и порядок этих сообщений зависят от класса окна и стиля и функций, используемых для создания окна. Эти сообщения описаны в других разделах этого справочного файла.

Дополнительные материалы на сайте:

  • "Шаг 43 - CreateWindow()"


1.12 Многопотоковые прикладные программы

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

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

Функция GetWindowThreadProcessId возвращает идентификатор потока, который создал отдельное окно.

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


1.13 Общие стили окна

Win32 API обеспечивает общие стили окна и определенные классом стили окна. Общие стили окон представляются константами, которые начинаются с префикса WS_; они могут быть объединены оператором OR (ИЛИ), чтобы формировать различные типы окон, включая главные окна, диалоговые окна и дочерние окна. Определенные классом стили окна определяют вид и поведение окон, принадлежащих к предопределенным классам элемента управления, таких как окна редактирования и окна списков. Этот обзор описывает общие стили окна.

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

Дополнительные материалы на сайте:

  • "Подробности - О классах окон"


1.14 Перекрывающее окно

Перекрывающее окно (overlapped window) - окно верхнего уровня, которое имеет строку заголовка, рамку и рабочую область; оно, как предполагается, служит как главное окно прикладной программы. Оно также может иметь меню окна, кнопки свертывания и развертывания окна и линейки прокрутки. Перекрывающее окно, используемое как главное окно, обычно включает все эти компоненты.

Определяя стиль WS_OVERLAPPED или WS_OVERLAPPEDWINDOW в функции CreateWindowEx, прикладная программа создает перекрывающее окно. Если Вы используете стиль WS_OVERLAPPED, окно имеет строку заголовка и рамку. Если Вы используете WS_OVERLAPPEDWINDOW стиль, окно имеет строку заголовка, устанавливающую размеры окна рамку, меню окна и кнопки свертывания и развертывания окна.


1.15 Выскакивающее Окно

Выскакивающее окно (pop-up window) - специальный тип перекрывающего окна, используемого для диалоговых окон, окон сообщений, и других временных окон, которые появляются снаружи главного окна прикладной программы. Строки заголовка для выскакивающих окон необязательны; иначе, выскакивающие окна - такие же, как и перекрывающие окна стиля WS_OVERLAPPED.

Вы создаете выскакивающее окно, определяя стиль WS_POPUP в функции CreateWindowEx. Чтобы включать строку заголовка, определите стиль WS_CAPTION. Используйте стиль WS_POPUPWINDOW, чтобы создать выскакивающее окно, которое имеет рамку и меню окна. Стиль WS_CAPTION должен быть объединен со стилем WS_POPUPWINDOW, чтобы сделать меню окна видимым.


1.16 Дочернее окно

Дочернее окно (child window) имеет стиль WS_CHILD и ограничено рабочей областью его родительского окна. Прикладная программа обычно использует дочерние окна, чтобы поделить рабочую область родительского окна на функциональные области. Вы создаете дочернее окно, определяя стиль WS_CHILD в функции CreateWindowEx.

Дочернее окно должно иметь родительское окно. Родительское окно может быть перекрывающим окном, выскакивающим окном или даже другим дочерним окном. Вы определяете родительское окно, когда Вы вызываете CreateWindowEx. Если Вы определяете стиль WS_CHILD в CreateWindowEx, но не определяете родительское окно, Windows не создает окно.

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

Позиционирование

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

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

Закрепление

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

Дочернее окно может накладываться на другие дочерние окна в той же самой рабочей области. Дочернее окно, которое разделяет то же самое родительское окно с одним или большим количеством других дочерних окон, называется сестринским окном (sibling window). Сестринские окна могут рисовать в рабочей области друг друга, если одно из дочерних окон не имеет стиля WS_CLIPSIBLINGS. Если дочернее окно имеет этот стиль, любая часть его сестринского окна, которое находится внутри дочернего окна, закрепляется.

Если окно имеет стиль WS_CLIPCHILDREN или WS_CLIPSIBLINGS, происходит небольшая потеря в эффективности. Каждое окно занимает системные ресурсы, так что прикладная программа не должна использовать дочерние окна беспорядочно. Для самой лучшей эффективности, прикладная программа, которой нужно логически поделить свое главное окно, должна сделать это в оконной процедуре главного окна скорее, чем используемые дочерние окна.

Взаимоотношение с родительским окном

Прикладная программа может изменять родительское окно существующего дочернего окна, вызывая функцию SetParent. В этом случае, Windows удаляет дочернее окно из рабочей области старого родительского окна и перемещает его в рабочую область нового родительского окна. Если SetParent определяет значение дескриптора ПУСТО (NULL), окно рабочего стола становится новым родительским окном. В этом случае, дочернее окно рисуется в самом главном окне, вне рамок любого другого окна. Функция GetParent восстанавливает дескриптор родительского окна для дочернего окна.

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

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

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

Сообщения

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

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


1.17 Рамка окна

Win32 API предоставляет нижеследующие стили рамки окна.

  • WS_BORDER - Создает окно с рамкой из тонких линий.
  • WS_DLGFRAME - Создает окно с двойной рамкой, стиль обычно используемый диалоговыми окнами. Окно с этим стилем не может иметь строку заголовка.
  • WS_EX_DLGMODALFRAME - Создает окно с двойной рамкой. В отличие от WS_DLGFRAME стиля, прикладная программа может также определить WS_CAPTION стиль, чтобы создать строку заголовка для окна.
  • WS_EX_STATICEDGE - Создает окно с трехмерным стилем рамки, предназначаемым для использования элементов, в которые нет доступа для вводимой информации пользователем.
  • WS_THICKFRAME - Создает окно с изменяемыми размерами рамки.

Окно со стилем WS_OVERLAPPED или WS_POPUPWINDOW имеет по умолчанию стиль WS_BORDER. Один из оставшихся стилей рамки должен быть объединен со стилем WS_OVERLAPPED или WS_POPUPWINDOW, чтобы дать перекрывающему окну различные стили рамки.

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


1.18 Компоненты нерабочей области

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

  • WS_CAPTION - Создает окно, которое имеет строку заголовка (включает в себя стиль WS_BORDER).
  • WS_HSCROLL - Создает окно, которое имеет горизонтальную линейку прокрутки.
  • WS_MAXIMIZEBOX - Создает окно, которое имеет кнопку развертывания окна. Стиль не может быть объединен со стилем WS_EX_CONTEXTHELP.
  • WS_MINIMIZEBOX - Создает окно, которое имеет кнопку свертывания окна. Стиль не может быть объединен со стилем WS_EX_CONTEXTHELP.
  • WS_SYSMENU - Создает окно, которое имеет меню окна в своей строке заголовка. Должен быть также определен стиль WS_CAPTION.
  • WS_VSCROLL - Создает окно, которое имеет вертикальную линейку прокрутки.


1.19 Исходное состояние окна

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

  • WS_DISABLED - Создает окно, которое первоначально заблокировано. Заблокированное окно не может принимать вводимую информацию от пользователя.
  • WS_MAXIMIZE - Создает окно, которое первоначально развернуто.
  • WS_MINIMIZE - Создает окно, которое первоначально свернуто.
  • WS_VISIBLE - Создает окно, которое первоначально видимое.


1.20 Стили родительского и дочернего окон

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

  • WS_CLIPCHILDREN - Исключает область, занятую дочерними окнами при прорисовке внутри родительского окна. Используйте этот стиль при создании родительского окна.
  • WS_CLIPSIBLINGS - Закрепляет дочерние окна относительно друг друга, то есть когда отдельное дочернее окно принимает сообщение WM_PAINT, стиль WS_CLIPSIBLINGS закрепляет все другие перекрывающие дочерние окна вне области дочернего окна, которое нужно модифицировать. Если WS_CLIPSIBLINGS не определен, и дочерние окна перекрываются, то возможно, что при прорисовке внутри рабочей области в одном из дочерних окон, произойдет прорисовка внутри рабочей области другого соседнего дочернего окна.


1.21 Расширенные стили

Следующие стили могут быть определены в параметре dwExStyle функции CreateWindowEx:

  • WS_EX_ACCEPTFILES - Определяет, что окно, созданное с этим стилем принимает файлы информационной технологии "перетащи и вставь" (drag-and-drop).
  • WS_EX_CONTEXTHELP - Включает вопросительный знак в строку заголовка окна. Когда пользователь щелкает мышью по вопросительному знаку, курсор изменяется на указатель с вопросительным знаком. Если пользователь затем щелкает мышью по дочернему окну, оно принимает сообщение WM_HELP. Дочернее окно должно передать сообщение в родительскую оконную процедуру, которая должна вызвать функцию WinHelp, использующую команду HELP_WM_HELP. Прикладная программа Справка (Help) отображает на экране выскакивающее окно, которое обычно содержит справку для дочернего окна. WS_EX_CONTEXTHELP не может использоваться со стилями WS_MAXIMIZEBOX или WS_MINIMIZEBOX.
  • WS_EX_CONTROLPARENT - Позволяет пользователю перемещаться по дочерним окнам родительского окна, используя клавишу табуляции TAB.
  • WS_EX_DLGMODALFRAME - Создает окно с двойной рамкой. В отличие от стиля WS_DLGFRAME, прикладная программа может также определять стиль WS_CAPTION, чтобы создать область заголовка для окна.
  • WS_EX_NOPARENTNOTIFY - Определяет, что дочернее окно, созданное с этим стилем не будет посылать сообщение WM_PARENTNOTIFY своему родительскому окну, когда создается или разрушается.
  • WS_EX_TOPMOST - Определяет, что окно, созданное с этим стилем, должно быть помещено выше всех не самых верхних окон и пребывать выше их даже тогда, когда окно дезактивировано.
  • WS_EX_TOOLWINDOW - Создает инструментальные средства окна; то есть окно предполагается использовать как плавающую инструментальную панель. Окно инструментальных средств имеет строку заголовка короче, чем нормальная строка заголовка, а заголовок окна выводится, используя более мелкий шрифт. Окно инструментальных средств не появляется в панели задач или в окне, которые появляются, когда пользователь нажимает ALT+TAB.

Дополнительные материалы на сайте:

  • "Шаг 97 - Структура окна на шаг впереди MFC"


1.22 Взаимоотношение Окон

Окно может быть находящимся во владении окном, заблокированным окном, приоритет-ным или фоновым окном. Имеется несколько различных способов, которые могут окно связывать с пользователем или другим окном.


1.22.1 Окна находящиеся во владении

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

  • Находящееся в собственности окно всегда выше его владельца в Z-последовательности.
  • Windows автоматически разрушает находящееся в собственности окно, когда его владелец разрушен.
  • Находящееся в собственности окно скрыто, когда его владелец свернут.

Только перекрывающее или выскакивающее окно может быть владельцем окна; дочернее окно не может быть им. Прикладная программа создает находящееся в собственности окно, определяя дескриптор владельца окна через параметр hwndParent функции CreateWindowEx, когда она создает окно в стиле WS_OVERLAPPED или WS_POPUP. Параметр hwndParent должен идентифицировать перекрывающее или выскакивающее окно. Если hwndParent идентифицирует дочернее окно, Windows назначает монопольное использование дочернего окна родительским окном верхнего уровня. После создания находящегося в собственности окна, прикладная программа не может передать монопольное использование окна к другому окну.

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

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


1.22.2 Блокирование окон

Окно может быть заблокировано. Заблокированное окно (disabled window) не принимает вводную информацию через клавиатуру или мышь от пользователя, но оно может принимать сообщения от других окон, из других прикладных программ и из Windows. Прикладная программа обычно отключает окно, чтобы предотвратить использование окна пользователем. Например, прикладная программа может отключить кнопку команды в диалоговом окне, чтобы предотвратить выбор ее пользователем. Прикладная программа может открыть доступ к заблокированному окну в любое время; давая возможность окну восстановить нормальный ввод информации.

По умолчанию, окно, когда создается, включено в работу. Однако, прикладная программа может определить стиль WS_DISABLED, чтобы отключить новое окно. Прикладная программа включает или отключает существующее окно, используя функцию EnableWindow. Windows посылает сообщение WM_ENABLE окну, когда собирается изменить его включенное состояние. Прикладная программа может определить, включено ли окно, используя функцию IsWindowEnabled.

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

Только одно окно одновременно может принимать ввод данных от клавиатуры; в этом окне, как говорят, находится фокус клавиатуры. Если прикладная программа использует функцию EnableWindow, чтобы отключить окно с фокусом клавиатуры, окно, в дополнение к отключению, теряет фокус клавиатуры. Затем EnableWindow устанавливает фокус клавиатуры в значение ПУСТО (NULL), не обозначая, какое окно имеет фокус. Если дочернее окно, или другое порожденное окно, имеет фокус клавиатуры, порожденное окно теряет фокус тогда, когда родительское окно заблокировано. Для получения дополнительной информации о фокусе клавиатуры, см. Ввод данных с клавиатуры.


1.22.3 Приоритетные и фоновые окна

Каждый процесс может иметь многопоточное выполнение, и каждый поток может создавать окна. Поток, который создал окно, с которым пользователь в настоящее время работает, называется приоритетным потоком, а окно называется приоритетным окном (foreground window). Все другие потоки являются фоновыми, а созданные ими окна называются фоновыми окнами (background windows).

Каждый поток имеет приоритетный уровень, который определяет количество ПРОЦЕССОРНОГО ВРЕМЕНИ, которое поток занимает. Хотя прикладная программа может устанавливать приоритетный уровень своих потоков, обычно приоритетный поток имеет немного более высокий приоритетный уровень, чем фоновые потоки. Приоритетный поток, поскольку он имеет более высокий приоритет, занимает большее количество ПРОЦЕССОРНОГО ВРЕМЕНИ, чем фоновые потоки. Приоритетный поток имеет обычный базовый приоритет - 9; фоновый поток имеет обычный базовый приоритет - 7.

Пользователь устанавливает приоритетное окно, щелкая мышью по окну или, используя комбинацию клавиш ALT+TAB или ALT+ESC. Прикладная программа устанавливает приоритетное окно, используя функцию SetForegroundWindow. Если новое приоритетное окно - окно верхнего уровня, Windows активизирует его; иначе он активизирует связанное окно верхнего уровня. Прикладная программа отыскивает данные о дескрипторе приоритетного окна, используя функцию GetForegroundWindow. Чтобы проверить, является ли ваше окно прикладной программы активным, сравните дескриптор, возвращенный GetForegroundWindow с дескриптором окна вашей прикладной программы.


1.23 Состояние Показа

В любое данное время, окно может быть активным или неактивным; скрытым или видимым; свернутым, развернутым или восстановленным. Эти качества упоминаются одним словом как состояние показа (show state) окна.


1.23.1 Активное окно

Активное окно (active window) - окно верхнего уровня прикладной программы, с которым пользователь в настоящее время работает. Чтобы позволить пользователю легко идентифицировать активное окно, Windows помещает его вверху Z-последовательности и заменяет цвет его строки заголовка и рамки определенными системой цветами активного окна. Активным окном может быть только окно верхнего уровня. Когда пользователь работает с дочерним окном, Windows активизирует родительское окно верхнего уровня, связанное с дочерним окном.

Одновременно в системе может быть активным только одно окно верхнего уровня. Пользователь активизирует окно верхнего уровня, щелкая мышью по нему (или по одному из его дочерних окон) или используя комбинацию клавиш ALT+ESC или ALT+TAB. Прикладная программа активизирует окно верхнего уровня, вызывая функцию SetActiveWindow. В число других функций, которые могут заставлять Windows активизировать различные окна верхнего уровня, включены SetWindowPos, DeferWindowPos, SetWindowPlacement и DestroyWindow. Хотя прикладная программа может активизировать различное окно верхнего уровня в любое время, чтобы избежать запутывания пользователя, она поступает так только в ответ на действие пользователя. Прикладная программа использует функцию GetActiveWindow, чтобы найти данные о дескрипторе активного окна.

Когда активация переходит от окна верхнего уровня в одной из прикладных программ к окну верхнего уровня другой программы, Windows посылает сообщение WM_ACTIVATEAPP обеим прикладным программам, сообщая им об изменении. Когда активация переходит среди различных окон верхнего уровня в той же самой прикладной программе, Windows посылает обоим окнам сообщение WM_ACTIVATE.

Дополнительные материалы на сайте:

  • "Шаг 71 - Z порядок окон"
  • "1.6 Z-последовательность (Z Order)"
  • "Шаг 315 - Окно поверх всех остальных"
  • "Шаг 316 - Подробнее о CTabCtrl"
  • "Шаг 184 - Создаем хранитель экрана"
  • "Шаг 15 - MCF и OpenGL"
  • "Шаг 139 - Стандартные диалоги Открытия и Сохранения файлов"


1.23.3 Свернутое, развернутое и восстановленное окно

Развернутое окно (maximized window)- окно, которое имеет стиль WS_MAXIMIZE. По умолчанию, Windows увеличивает развернутое окно так, чтобы оно заполнило экран или, в случае дочернего окна, рабочую область родительского окна. Хотя размеры окна могут быть установлены в тех же самых размерах развернутого окна, развернутое окно немного отличается. Windows автоматически перемещает строку заголовка окна в верхнюю часть экрана или в верхнюю часть рабочей области родительского окна. Windows также отключает опцию установки размеров рамки окна и возможность позиционирования окна в строке заголовка (так, чтобы пользователь не мог перемещать окно, перемещая строку заголовка).

Свернутое окно (minimized window) - окно, которое имеет стиль WS_MINIMIZE. По умолчанию, Windows уменьшает свернутое окно до размера его кнопки панели задач и перемещает свернутое окно в панель задач. Восстановленное окно (restored window) - окно, которое было возвращено к его прежним размерам и в позицию до свертывания или до развертывания. Если прикладная программа определяет стиль WS_MAXIMIZE или WS_MINIMIZE в функции CreateWindowEx, окно первоначально развернуто или свернуто. После создания окна, прикладная программа может использовать функцию CloseWindow, чтобы свернуть окно. Функция ArrangeIconicWindows упорядочивает пиктограммы на рабочем столе, или она упорядочивает свернутые дочерние окна в родительском окне. Функция OpenIcon восстанавливает свернутое окно в его предыдущих размерах и позиции.

Функция ShowWindow может свертывать, развертывать, или восстанавливать окно. Она может также устанавливать видимость окна и состояние активности. Функция SetWindowPlacement включает те же самые функциональные возможности, что и ShowWindow, но она может отменять свертывание, развертывание и восстановление позиции окна назначенные по умолчанию.

Функции IsZoomed и IsIconic определяют соответственно, развернуто ли или свернуто данное окно. Функция GetWindowPlacement восстанавливает свернутые, развернутые и восстановленные позиции окна, а также определяет состояние показа окна.

Когда Windows принимает команду, чтобы развернуть или восстановить свернутое окно, Windows посылает окну сообщение WM_QUERYOPEN. Если оконная процедура возвращает значение ЛОЖЬ(FALSE), Windows игнорирует команду Maximize (Развернуть) или Restore(Восстановить).

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


1.23.2 Видимость

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

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

Прикладная программа может определить, является ли окно видимым, используя функцию IsWindowVisible. Прикладная программа может показывать (делать видимым) или скрывать окно, используя функции ShowWindow, SetWindowPos, DeferWindowPos или SetWindowPlacement. Эти функции показывают или скрывают окно, устанавливая или удаляя WS_VISIBLE стиль для окна. Они также посылают сообщение WM_SHOWWINDOW окну перед показом или сокрытием его.

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

Когда родительское окно видимое, связанные с ним дочерние окна также видимы. Точно так же, когда родительское окно скрыто, его дочерние окна также скрыты. Свертывание родительского окна не оказывает никакого эффекта на состояние видимости дочерних окон; то есть дочерние окна свертываются вместе с родителем, но стиль WS_VISIBLE не изменяется.

Даже если окно имеет стиль WS_VISIBLE, пользователь может быть не способен видеть окно на экране; другие окна могут полностью накладываться на него, или оно, возможно, было перемещено за края экрана. А также, видимое дочернее окно подчиненно правилам закрепления, установленными для него родительскими и дочерними взаимоотношениями. Если родительское окно окна не видимо, оно будет также невидимо. Если родительское окно перемещается за краями экрана, дочернее окно также перемещается, потому что дочернее окно выводится относительно верхнего левого угла родителя. Например, пользователь может перемещать родительское окно, содержащее дочернее окно достаточно далеко от края экрана, так что пользователь может быть не способен видеть дочернее окно, даже притом, что дочернее окно и его родительское окно оба имеют WS_VISIBLE стиль.

Дополнительные материалы на сайте:

  • "Шаг 4 - Окно Windows на С"
  • "Шаг 57 - Функции ShowWindow() и UpdateWindow()"
  • "Шаг 30 - Проект библиотека - Подготовка Ввод/Просмотр других сведений"


1.24 Размер и позиция окна

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


1.24.1 Размеры окна

Размеры окна (ширина и высота) даются в пикселях. Окно может иметь нулевую ширину или высоту. Если прикладная программа устанавливает нулевую ширину и высоту окна, Windows устанавливает размеры в заданных по умолчанию минимальных размерах окна. Чтобы узнать заданные по умолчанию минимальные размеры окна, прикладная программа использует функцию GetSystemMetrics с флажками SM_CYMIN и SM_CXMIN.

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

Прикладная программа может установить величину окна так, чтобы оно было чрезвычайно большое; однако, она не должно устанавливать величину окна так, чтобы оно было больше, чем экран. Перед установкой размера окна, прикладная программа должна проверить ширину и высоту экрана, используя GetSystemMetrics с флажками SM_CYSCREEN и SM_CXSCREEN.

Дополнительные материалы на сайте:

  • "Шаг 73 - Функция AdjustWindowRect()"
  • "Шаг 153 - GetSystemMetrics и иконы"
  • "Шаг 314 - Аналог AdjustWindowsRect в MFC (CalcWindowRect)"


1.24.2 Позиция (расположение) окна

Позиция окна определена как координаты его верхнего левого угла. Эти координаты, иногда называемые координатами окна, отсчитываются всегда относительно верхнего левого угла экрана или, для дочернего окна, от верхнего левого угла рабочей области родительского окна. Например, окно верхнего уровня, имеющее координаты (10,10) помещено на 10 пикселей вправо от верхнего левого угла экрана и на 10 пикселей вниз от него. Дочернее окно, имеющее координаты (10,10) помещено на 10 пикселей направо от верхнего левого угла рабочей области его родительского окна и на 10 пикселей вниз от него.

Функция WindowFromPoint отыскивает дескриптор окна, занимающего отдельное место на экране. Точно так же функции ChildWindowFromPoint и ChildWindowFromPointEx отыскивают дескриптор дочернего окна, занимающего отдельное место в рабочей области родительского окна. Хотя функция ChildWindowFromPointEx может игнорировать невидимые, заблокированные и прозрачные дочерние окна, то ChildWindowFromPoint это не может.


1.24.3 Размеры и позиция по умолчанию

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


1.24.4 Устанавливаемые размеры

Windows поддерживает минимальный и максимальный устанавливаемый размер для окна стиля WS_THICKFRAME; окно с этим стилем имеет рамку установки размеров окна. Минимальный устанавливаемый размер (minimum tracking size) - самый маленький размер окна, который пользователь, может сделать, перемещая рамку установки размеров окна. Точно так же максимальный устанавливаемый размер (maximum tracking size) - самый большой размер окна, который пользователь может сделать, перемещая рамку установки размеров окна.

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


1.24.5 Системные команды

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

  • SC_CLOSE - Закрывает окно. Эта команда посылает сообщение WM_CLOSE окну. Окно выполняет любые шаги, необходимые, чтобы очистить и уничтожить себя.
  • SC_MAXIMIZE - Разворачивает окно.
  • SC_MINIMIZE - Свертывает окно.
  • SC_RESTORE - Возвращает свернутое или развернутое окно в его предыдущие размеры и позицию.
  • SC_SIZE - Запускает команду Размер (Size). Пользователь может изменять размеры окна, используя мышь или клавиатуру.


1.24.6 Функции размера и позиции

После создания окна, прикладная программа может устанавливать размер окна или позицию, вызывая одну из нескольких различных функций, среди которых SetWindowPlacement, MoveWindow, SetWindowPos и DeferWindowPos. SetWindowPlacement устанавливает позицию свернутого окна, позицию развернутого окна, восстанавливает размер и позицию окна и показывает его состояние. Функции MoveWindow и SetWindowPos похожи; обе устанавливают размер или позицию отдельного окна прикладной программы. Функция SetWindowPos включает в себя набор флажков, которые воздействуют на состояние показа окна; MoveWindow не включает в себя эти флажки. Используйте функции BeginDeferWindowPos, DeferWindowPos и EndDeferWindowPos, чтобы одновременно установить позицию ряда окон, включая размер, позицию, позицию в Z-последовательности и состояние показа.

Прикладная программа может отыскать координаты ограничительного прямоугольника окна, используя функцию GetWindowRect. GetWindowRect заполняет структуру RECT координатами верхних левых и нижних правых углов окна. Координаты, вычисляемые относительно верхнего левого угла экрана, те же самые для дочернего окна. Функции ScreenToClient или MapWindowPoints отображает экранные координаты ограничительного прямоугольника дочернего окна относительно координат рабочей области родительского окна.

Функция GetClientRect отыскивает координаты рабочей области окна. GetClientRect заполняет структуру RECT координатами верхних левых и нижних правых углов рабочей области, а координаты отсчитываемые относительно рабочей области самостоятельно. Это означает, что координаты верхнего левого угла рабочей области - всегда (0,0), а координаты нижнего правого угла - ширина и высота рабочей области.

Функция CascadeWindows располагает каскадом окна на рабочем столе или располагает каскадом дочерние окна определенного родительского окна. Функция TileWindows располагает окна на рабочем столе или дочерние окна определенного родительского окна в не перекрывающих друг друга положениях ("мозаикой").

Дополнительные материалы на сайте:

  • "Шаг 72 - Функции GetWindowRect() и GetClientRect()"
  • "Шаг 294 - Размер элемента и размер диалога"
  • "Шаг 314 - Аналог AdjustWindowsRect в MFC (CalcWindowRect)"
  • "Шаг 355 - Создание разных окон MDI еще доработаем"


1.24.7 Сообщения о размере и позиции

Windows посылает сообщение WM_GETMINMAXINFO окну, чей размер или позиция должны измениться. Например, сообщение посылается, когда пользователь выбирает из меню окна команду Переместить (Move) или Размер (Size) или щелкает мышью по рамке установки размеров окна или по строке заголовка; сообщение посылается также тогда, когда прикладная программа вызывает функцию SetWindowPos, чтобы переместить или установить величину окна. Сообщение WM_GETMINMAXINFO включает в себя указатель на структуру MINMAXINFO, содержащую по умолчанию развернутый размер и позицию для окна, а также заданные по умолчанию минимальный и максимальный устанавливаемые размеры. Прикладная программа может отменять значения по умолчанию, обрабатывая WM_GETMINMAXINFO и устанавливая соответствующие элементы MINMAXINFO. Чтобы принять WM_GETMINMAXINFO, окно должно иметь стиль WS_THICKFRAME или WS_CAPTION. Окно со стилем WS_THICKFRAME принимает это сообщение в ходе процесса создания окна, а также тогда, когда оно передвигается или устанавливается по размеру.

Windows посылает сообщение WM_WINDOWPOSCHANGING окну, чей размер, позиция, позиция в Z-последовательности или состояние показа собирается измениться. Это сообщение включает в себя указатель на структуру WINDOWPOS, которая определяет новый размер окна, позицию, позицию в Z-последовательности и состояние показа. Устанавливая элементы WINDOWPOS, прикладная программа может воздействовать на новый размер, позицию и вид окна.

После изменения размера окна, позиции, позиции в Z-последовательности или состояния показа, Windows посылает окну сообщение WM_WINDOWPOSCHANGED. Это сообщение включает в себя указатель на WINDOWPOS, который сообщает окну о его новых размерах, позиции, позиции в Z-последовательности и состоянии показа. Установка элементов структуры WINDOWPOS, которая передана вместе с WM_WINDOWPOSCHANGED, не влияет на окно. Окно, которое должно обработать сообщения WM_SIZE и WM_MOVE, должно передать WM_WINDOWPOSCHANGED в функцию DefWindowProc; иначе, Windows не посылает сообщения WM_SIZE и WM_MOVE в окно.

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


1.25 Разрушение окна

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

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

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

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

Когда пользователь выбирает команду Закрыть (Close), окно с меню окна принимает сообщение WM_CLOSE. Обрабатывая это сообщение, прикладная программа может запрашивать пользователя о подтверждении этого действия перед разрушением окна. Если пользователь подтверждает, что окно должно быть разрушено, прикладная программа может вызывать функцию DestroyWindow, чтобы уничтожить окно.

Если разрушаемое окно - активное, то и активность, и состояние фокуса перемещаются в другое окно. Окно, которое становится активным - следующее окно, как определено комбинацией клавиш ALT+ESC. Новое активное окно затем определяет, какое окно принимает фокус клавиатуры.


1.26 Использование окон

Примеры в этом разделе описывают, как выполнить следующие задачи:

  • Создание основного окна
  • Создание, перечисление и установка размеров дочерних окон
  • Разрушение окна


1.26.1 Создание основного окна

Первое окно, которое создает прикладная программа - обычно основное окно(main window). Вы создаете основное окно, используя функцию CreateWindowEx, которая определяет класс, имя , стили окна, размер, позицию, дескриптор меню, дескриптор экземпляра и данные создания. Основное окно принадлежит определенному прикладной программой классу окна, таким образом, Вы должны зарегистрировать класс окна и предоставить оконную процедуру для класса перед созданием основного окна.

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

Следующий пример создает основное окно, принадлежащее к классу окна определенному прикладной программой. Имя окна, " Основное Окно ", появится в строке заголовка окна. Объединяя стили WS_VSCROLL и WS_HSCROLL со стилем WS_OVERLAPPEDWINDOW, прикладная программа создает основное окно с горизонтальными и вертикальными линейками прокрутки в дополнение к компонентам, предоставляемым стилем WS_OVERLAPPEDWINDOW. Четырехкратное повторение константы CW_USEDEFAULT устанавливает начальный размер и позицию окна в зна-чения, определенные системой по умолчанию. Устанавливая значение ПУСТО (NULL), вместо дескриптора меню, окно получит меню, определенное для класса окна.

HINSTANCE 	hinst;
HWND		hwndMain;

// Создание основного окна.

hwndMain = CreateWindowEx(
0,				// расширения стилей нет
"MainWClass",			// имя класса
"Основное окно",			// имя окна
WS_OVERLAPPEDWINDOW | 		// перекрывающее окно
WS_HSCROLL | 			// горизонтальная линейка прокрутки
WS_VSCROLL,			// вертикальная линейка прокрутки
CW_USEDEFAULT,			// горизонтальная позиция по умолчанию
CW_USEDEFAULT,			// вертикальная позиция по умолчанию
CW_USEDEFAULT,			// ширина по умолчанию
CW_USEDEFAULT,			// высота по умолчанию
(HWND) NULL,			// окно не родительское или
                // имеющее в собственности окна
(HMENU) NULL,			// используемый класс меню
hinstance,			// дескриптор экземпляра
NULL);				// нет данных создания окна
if (!hwndMain)
return FALSE;
                // Показывает окно, использующее флажок, определенный программой,
                // которая запускает прикладную программу и передает в приложение
                // сообщение WM_PAINT.
ShowWindow(hwndMain, SW_SHOWDEFAULT);
UpdateWindow(hwndMain);

Обратите внимание, что предшествующий пример вызывает функцию ShowWindow после создания основного окна. Это сделано потому, что Windows автоматически не отображает на экране основное окно после его создания. Передавая флажок SW_SHOWDEFAULT в ShowWindow, прикладная программа позволяет программе, которая запустила приложение, установить начальное состояние показа основного окна. Функция UpdateWindow посылает окну свое первое сообщение WM_PAINT.

Пример на сайте: "Шаг 4 - Окно Windows на С".


1.26.2 Создание, перечисление и изменение размеров дочерних окон

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

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

Основное окно устанавливает величину и позицию дочерних окон в ответ на сообщение WM_SIZE, которое основное окно принимает, когда изменяются его размеры. В ответ на WM_SIZE, основное окно восстанавливает габариты своей рабочей области, используя функцию GetWindowRect, а затем передает габариты в функцию EnumChildWindows. В свою очередь, EnumChildWindows передает дескриптор каждого дочернего окна в определенную прикладной программой функцию повторного вызова EnumChildProc. Эта функция устанавливает размеры и позицию каждого дочернего окна, через вызов функции MoveWindow; размер и позиция основываются на габаритах рабочей области основного окна и на идентификаторе дочернего окна. Позже, EnumChildProc вызывает функцию ShowWindow, чтобы сделать окно видимым.

#define ID_FIRSTCHILD	100
#define ID_SECONDCHILD	101
#define ID_THIRDCHILD	102

LONG APIENTRY MainWndProc(hwnd, uMsg, wParam, lParam)
HWND hwnd;
UINT uMsg;
UINT wParam;
LONG lParam;
{
    RECT rcClient;
    int i;
    switch(uMsg)
    {
    case WM_CREATE:	// создание основного окна
            // Создание трех невидимых дочерних окна
        for (i = 0; i < 3; i++)
        CreateWindowEx(0,"ChildWClass",(LPCTSTR) NULL,WS_CHILD | WS_BORDER,
            0,0,0,0,hwnd,(HMENU) (int) (ID_FIRSTCHILD + i),hinst,NULL);
        return 0;
    case WM_SIZE:	// изменение размеров основного окна
            // Получает габариты рабочей области главного окна и перечисляет дочерние окна.
            // Передает габариты в дочерние окна в ходе перечисления.
    GetClientRect(hwnd, &rcClient);
    EnumChildWindows(hwnd, EnumChildProc,(LPARAM) &rcClient);
    return 0;

    // Создание других сообщений.
    }
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

BOOL CALLBACK EnumChildProc(hwndChild, lParam)
HWND hwndChild;
LPARAM lParam;
{
    LPRECT rcParent;
    int i, idChild;
    // Восстановление идентификатора дочернего окна.
    // Использовать его для установки дочернего окна.
    idChild = GetWindowLong(hwndChild, GWL_ID);
    if (idChild == ID_FIRSTCHILD)
    i = 0;
    else if (idChild == ID_SECONDCHILD)
    i = 1;
    else
    i = 2;
    // Размер и позиция дочернего окна.
    rcParent = (LPRECT) lParam;
    MoveWindow(hwndChild, (rcParent->right / 3) * i,0, rcParent->right / 3,rcParent->bottom,TRUE);
    // Удостоверитесь, что дочернее окно видимо
    ShowWindow(hwndChild, SW_SHOW);
    return TRUE;
}

Пример на сайте: "Шаг 170 - Создание дочерних окон на C".


1.26.3 Разрушение окна

Вы можете использовать функцию DestroyWindow, чтобы уничтожить окно. Как правило, прикладная программа перед разрушением окна посылает сообщение WM_CLOSE, давая окну возможность запросить у пользователя подтверждение перед разрушением его. Окно, которое включает в себя автоматически меню окна, принимает сообщение WM_CLOSE, когда пользователь выбирает команду Закрыть (Close) из меню. Если пользователь подтверждает, что окно должно быть разрушено, прикладная программа вызывает DestroyWindow. Windows посылает окну сообщение WM_DESTROY после удаления его с экрана. В ответ на WM_DESTROY, окно сохраняет свои данные и освобождает любые ресурсы, которые выделила ему система. Основное окно завершает свою обработку WM_DESTROY, вызывая функцию PostQuitMessage, чтобы выйти из прикладной программы.

Следующий пример показывает, как запросить подтверждение у пользователя перед разрушением окна. В ответ на WM_CLOSE, пример отображает на экране диалоговое окно, которое содержит кнопки Да (Yes) , OK и Прекратить (Cancel). Если пользователь щелкает мышью по кнопке Да (Yes), вызывается DestroyWindow; иначе, окно не разрушается. Поскольку разрушаемое окно - основное окно, пример вызывает PostQuitMessage в ответ на WM_DESTROY.

case WM_CLOSE:

// Создаем окно сообщений. Если пользователь щелкает мышью
// по кнопке Да (Yes), основное окна разрушается.

if (MessageBox(hwnd, szConfirm, szAppName,
MB_YESNOCANCEL) == IDYES)
DestroyWindow(hwndMain);
else
return 0;

case WM_DESTROY:

// Регистрирует сообщение WM_QUIT, чтобы завершить выход из программы.

PostQuitMessage(0);
return 0;

Дополнительные материалы на сайте:

  • "Шаг 56 - Основная функция окна"
  • "Шаг 59 - Сообщение WM_CLOSE"
  • "Шаг 60 - Сообщение WM_DESTROY"


1.27 Справочник Окна

Следующие функции, структуры и сообщения связаны с окнами.


1.27.1 Функции окна

Следующие функции используются для создания и управления окнами.

AdjustWindowRect
AdjustWindowRectEx
ArrangeIconicWindows
BeginDeferWindowPos
BringWindowToTop
CascadeWindows
ChildWindowFromPoint
ChildWindowFromPointEx
CloseWindow
CreateWindow
CreateWindowEx
DeferWindowPos
DestroyWindow
EnableWindow
EndDeferWindowPos
EnumChildProc
EnumChildWindows
EnumThreadWindows
EnumThreadWndProc
EnumWindows
EnumWindowsProc
FindWindow
FindWindowEx
GetClientRect
GetDesktopWindow
GetForegroundWindow
GetLastActivePopup
GetNextWindow
GetParent
GetTopWindow
GetWindow
GetWindowPlacement
GetWindowRect
GetWindowText
GetWindowTextLength
GetWindowThreadProcessId
IsChild
IsIconic
IsWindow
IsWindowUnicode
IsWindowVisible
IsZoomed
MoveWindow
OpenIcon
SetForegroundWindow
SetParent
SetWindowLong
SetWindowPlacement
SetWindowPos
SetWindowText
ShowOwnedPopups
ShowWindow
ShowWindowAsync
TileWindows
WindowFromPoint
WinMain

Устаревшие функции:
AnyPopup
EnumTaskWindows
GetSysModalWindow
GetWindowTask
SetSysModalWindow


1.27.1.1 Функция AdjustWindowRect

РегулировкаПрямоугольникаОкна

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

Синтаксис:

BOOL AdjustWindowRect
(
LPRECT lpRect,		// указатель на структуру
            // прямоугольника пользователя
DWORD dwStyle,		// стиль окон
BOOL bMenu 		// флажок показа меню
);

Параметры

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

dwStyle
Определяет стили окна, требуемый размер которого должен быть вычислен.

bMenu
Определяет, имеет ли окно меню.

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

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

Смотри также
AdjustWindowRectEx, CreateWindowEx, RECT

Размещение и совместимость AdjustWindowRect

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется

Примеры использования и дополнения:

  • "Шаг 28 - Список функций из DLL AddressOfNames"
  • "Шаг 73 - Функция AdjustWindowRect()"
  • "Шаг 314 - Аналог AdjustWindowsRect в MFC (CalcWindowRect)"
  • "Шаг 319 - Свой вид на основе CTabCtrl"


1.27.1.2 Функция AdjustWindowRectEx

(РегулировкаПрямоугольникаОкна)

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

Синтаксис:

BOOL AdjustWindowRect
(
LPRECT lpRect,		// указатель на структуру
            // рабочей области
DWORD dwStyle,		// стиль окон
BOOL bMenu 		// флажок показа меню
DWORD dwExStyle		// расширенный стиль
);

Параметры

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

dwStyle
Определяет стили окна, требуемый размер которого должен быть вычислен.

bMenu
Определяет, имеет ли окно меню.

dwExStyle
Определяет расширенный стиль окна, требуемый размер которого должен быть вычислен.

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

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

Смотри также
AdjustWindowRect, CreateWindowEx, RECT

Размещение и совместимость AdjustWindowRect

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.3 Функция ArrangeIconicWindows

(РасположениеВОпределенномПорядкеПиктограммОкон)

Функция ArrangeIconicWindows упорядочивает все свернутые (пиктограммы) дочерние окна определяемого родительского окна.

Синтаксис

UINT ArrangeIconicWindows
(
    HWND hWnd		// дескриптор родительского окна
);

Параметры
hWnd Идентифицирует родительское окно.

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

Замечания
Прикладная программа, которая поддерживает самостоятельно свернутые дочерние окна, может использовать функцию ArrangeIconicWindows, чтобы упорядочить значки в родительском окне. Эта функция может также упорядочивать значки на рабочем столе. Чтобы возвратить дескриптор окна в главное окно программы, используйте функцию GetDesktopWindow. Прикладная программа посылает сообщение WM_MDIICONARRANGE в рабочее окно интерфейса многодокументной среды (MDI), чтобы побудить рабочее окно упорядочить свернутые дочерние окна интерфейса многодокументной среды (MDI).

Смотри также
CloseWindow, GetDesktopWindow

Размещение и совместимость ArrangeIconicWindows

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл		winuser.h
Уникод				Нет
Замечания по платформе		Не имеется


1.27.1.4 Функция BeginDeferWindowPos

(НачалоЗадержкиПозиционирования Окна)

Функция BeginDeferWindowPos распределяет память для структуры многооконной установки и возвращает значение дескриптора структуры.

Синтаксис:

HDWP BeginDeferWindowPos
(
int nNumWindows 	// число окон
);

Параметры
nNumWindows Определяет начальное число окон, для которых сохраняется информация о расположении. Функция DeferWindowPos, в случае необходимости, увеличивает размер структуры.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение идентифицирует структуру многооконной установки. Если доступные ресурсы системы недостаточные, чтобы распределить структуру, возвращаемое значение ПУСТО (NULL).

Замечания
Структура многооконной установки - внутренняя структура; прикладная программа не может обращаться к ней непосредственно. Функция DeferWindowPos заполняет структуру многооконной установки информацией о расположении объекта для одного или большего количества окон, собирающихся быть перемещенными. Функция EndDeferWindowPos принимает дескриптор для этой структуры и снова устанавливает окна, используя информацию, сохраненную в структуре. Если какоелибо из окон в структуре многооконной установки имеет набор флажков SWP_HIDEWINDOW или SWP_SHOWWINDOW, ни одно из окон снова не устанавливается. Если Windows должен увеличить размер структуры многооконной установки за пределы начального размера, определенного параметром nNumWindows, но не может выделить достаточно памяти, чтобы выполнить это, Windows не выполняет задачу установленным порядком для всего окна (BeginDeferWindowPos, DeferWindowPos, и EndDeferWindowPos). Определяя необходимый максимальный размер, прикладная программа может обнаруживать и обрабатывать сбой в начале процесса.

Смотри также
DeferWindowPos, EndDeferWindowPos, SetWindowPos

Размещение и совместимость BeginDeferWindowPos

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.5 Функция BringWindowToTop

(ПереводОкнаВВерх)

Функция BringWindowToTop переносит определенное окно в верхнюю часть Z-последовательности. Если окно - окно верхнего уровня, оно активизируется. Если окно - дочернее окно, родительское окно верхнего уровня, связанное с дочерним окном активизируется.

Синтаксис

BOOL BringWindowToTop
(
    HWND hWnd 			// дескриптор окна
);

Парамертры

hWnd
Идентифицирует окно, которое переносится в верхнюю часть Z-последовательности.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение не ноль. Если функция не выполняет задачу, возвращаемое значение нулевое. Чтобы получить расширенные данные об ошибках, вызовите GetLastError.

Замечания
Используйте функцию BringWindowToTop, чтобы открыть любое окно, которое частично или полностью затенено другими окнами. Вызов этой функции подобен вызову функции SetWindowPos, чтобы изменить позицию окна в Z-последовательности. BringWindowToTop не делает окно окном верхнего уровня. Если прикладная программа не в активном режиме и хочет быть в активном режиме, она должна вызвать функцию SetForegroundWindow.

Смотри также
SetWindowPos, SetActiveWindow, SetForegroundWindow

Размещение и совместимость BringWindowToTop

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.6 Функция CascadeWindows

(ОкнаКаскадом) [Теперь поддерживается в Windows NT]

Функция CascadeWindows располагает каскадом определенные окна или дочерние окна определенного родительского окна.

Синтаксис

WORD WINAPI CascadeWindows
(
HWND hwndParent,			// дескриптор родительского окна
UINT wHow,			// типы окон, которые не упорядочиваются
CONST RECT *lpRect, 		// прямоугольник, в котором
                // упорядочиваются окна
UINT cKids,			// число окон для упорядочивания
const HWND FAR *lpKids		// массив дескрипторов окна
);

Параметры

hwndParent
Идентифицирует родительское окно. Если этот параметр имеет значение ПУСТО (NULL), принимается окно рабочего стола.
wHow
Определяет флажок каскада. В настоящее время доступен единственный флажок, MDITILE_SKIPDISABLED, который предотвращает блокирование дочерних окон MDI (Многодокументального Интерфейса) от каскадирования.
lpRect
Указатель на структуру SMALL_RECT, которая определяет прямоугольную область, в экранных координатах, внутри которой помещены окна. Этот параметр может быть значением ПУСТО (NULL), когда используется рабочая область родительского окна.
cKids
Определяет число элементов в массиве, определенном параметром lpKids. Этот параметр игнорируется, если lpKids - ПУСТО (NULL). lpKids
Указатель на массив дескрипторов окон, которые идентифицируют упорядочиваемые окна. Если этот параметр - ПУСТО (NULL), дочерние окна размещаются в определенном родительском окне (или окне рабочего стола).

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - число упорядочиваемых окон. Если функция не выполняет задачу, возвращаемое значение нулевое.

Смотри также
SMALL_RECT

Размещение и совместимость CascadeWindows

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.7 Функция ChildWindowFromPoint

(ДочернееОкноОтТочки) [Теперь поддерживается в Windows NT]

Функция ChildWindowFromPoint определяет, какие, если таковые вообще имеются, из дочерних окон, принадлежащих родительскому окну, содержат точку установки (фиксированную).

Синтаксис

HWND ChildWindowFromPoint
(
HWND hWndParent,		// дескриптор родительского окна
POINT Point 		// структура с координатами точки
);

Параметры

hWndParent
Идентифицирует родительское окно.
Point
Определяет структуру POINT, которая устанавливает для проверки рабочие координаты точки.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - дескриптор дочернего окна, которое содержит точку, даже если дочернее окно скрыто или заблокировано. Если точка находится за пределами родительского окна, возвращаемое значение - ПУСТО (NULL). Если точка - внутри родительского окна, а не внутри какого-либо дочернего окна, возвращаемое значение - дескриптор родительского окна.

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

Смотри также
ChildWindowFromPointEx, POINT, WindowFromPoint

Размещение и совместимость ChildWindowFromPoint

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.8 Функция ChildWindowFromPointEx

(ДочернееОкноОтТочкиРасширенная) [Теперь поддерживается в Windows NT]

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

Синтаксис

HWND ChildWindowFromPointEx
(
HWND hwndParent, 		// дескриптор родительского окна
POINT pt, 		// структура с координатами точки
UINT uFlags		// флажки пропуска
);

Параметры

hwndParent
Идентифицирует родительское окно.
pt
Определяет структуру POINT, которая определяет для проверки рабочие координаты точки.
uFlags
Определяет, какие дочерние окна пропустить. Этот параметр может быть комбинацией следующих значений:

  • CWP_ALL - Не пропускать все дочерние окна.
  • CWP_SKIPINVISIBLE - Пропускать невидимые дочерние окна.
  • CWP_SKIPDISABLED - Пропускать блокированные дочерние окна .
  • CWP_SKIPTRANSPARENT - Пропускать прозрачные дочерние окна.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - дескриптор первого дочернего окна, которое содержит точку и соответствует критериям, определенным в uFlags. Если точка - внутри родительского окна, а не внутри какого-либо дочернего окна, которое соответствует критериям, возвращаемое значение - дескриптор родительского окна. Если точка находится за пределами родительского окна или если функция не выполнила задачу, возвращаемое значение - ПУСТО (NULL).

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

Смотри также
ChildWindowFromPoint, POINT, WindowFromPoint

Размещение и совместимость ChildWindowFromPointEx

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.9 Функция CloseWindow

(ЗакрытьОкно)

Функция CloseWindow свертывает (но не разрушает) определенное окно.

Синтаксис:

BOOL CloseWindow
(
HWND hWnd 	// дескриптор окна, которое свертывается
);

Параметры

hWnd
Идентифицирует окно, которое должно быть свернуто.

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

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

Смотри также
ArrangeIconicWindows, DestroyWindow, IsIconic, OpenIcon

Размещение и совместимость CloseWindow

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.10 Функция CreateWindow

(СоздатьОкно)

Функция CreateWindow создает перекрывающее, выскакивающее или дочернее окно. Она определяет класс, заголовок, стиль окна и (необязательно) исходное положение и размер окна. Функция также определяет окно родителя или владельца, если таковые вообще имеются, и меню окна.

Синтаксис:

HWND CreateWindow
(
LPCTSTR lpClassName,		// указатель на зарегистрированное имя класса
LPCTSTR lpWindowName,		// указатель на имя окна
DWORD dwStyle,			// стиль окна
int x,				// горизонтальная позиция окна
int y,				// вертикальная позиция окна
int nWidth,			// ширина окна
int nHeight,			// высота окна
HWND hWndParent,			// дескриптор родительского или окна владельца
HMENU hMenu,			// дескриптор меню или идентификатор дочернего окна
HANDLE hInstance,			// дескриптор экземпляра приложения
LPVOID lpParam 			// указатель на данные создания окна
);

Параметры

lpClassName
Указывает на строку с нулевым символом в конце или - на целочисленный атом. Если этот параметр - атом, он должен быть общим атомом, созданным предыдущим обращением к функции GlobalAddAtom. Атом - 16-разрядное значение меньшее, чем 0xC000, должно быть в младшем слове lpClassName; старшее слово должно быть нулевое. Если lpClassName - строка, она определяет имя класса окна. Имя класса может быть любое имя, зарегистрированное функцией RegisterClass или любым из предопределенных имен класса элементов управления. Полный список, см. в следующем разделе Замечания.

lpWindowName
Указывает на строку с нулевым символом на конце, которая определяет имя окна.

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

x
Определяет начальную горизонтальную позицию окна. Для перекрывающего или выскакивающего окна, параметр x - начальная x-координата левого верхнего угла окна, в экранных координатах. Для дочернего окна x - x-координата левого верхнего угла окна относительно левого верхнего угла рабочей области родительского окна. Если этот параметр установлен как CW_USEDEFAULT, Windows выбирает заданную по умолчанию позицию для левого верхнего угла окна и игнорирует параметр y. Параметр CW_USEDEFAULT допустим только для перекрывающих окон; если он определен для выскакивающего или дочернего окна, x и y параметры устанавливаются в нуль.

y
Определяет начальную вертикальную позицию окна. Для перекрывающего или выскакивающего окна, параметр y - начальная y-координата левого верхнего угла окна, в экранных координатах. Для дочернего окна, y - начальная y-координата левого верхнего угла дочернего окна относительно левого верхнего угла рабочей области родительского окна. Для окна со списком, y - начальная y-координата левого верхнего угла рабочей области окна со списком относительно левого верхнего угла рабочей области родительского окна. Если перекрывающее окно создано с установленным битом стиля WS_VISIBLE, а x параметр установлен как CW_USEDEFAULT, Windows игнорирует параметр y.

nWidth

Определяет ширину окна в единицах измерения для устройства. Для перекрывающих окон, nWidth является, или шириной окна в экранных координатах, или параметром CW_USEDEFAULT. Если nWidth - CW_USEDEFAULT, Windows выбирает заданную по умолчанию ширину и высоту для окна; заданная по умолчанию ширина простирается от начальной x-координаты до правого края экрана, а заданная по умолчанию высота простирается от начальной y-координаты до верхней части области пиктограмм. Значение CW_USEDEFAULT допустимо только для перекрывающих окон; если CW_USEDEFAULT определено для выскакивающего или дочернего окна, nWidth и nHeight устанавливаются в нуль.

nHeight
Определяет высоту окна в единицах измерения устройства. Для перекрывающих окон, nHeight - высота окна, в экранных координатах. Если параметр nWidth установлен как CW_USEDEFAULT, Windows игнорирует nHeight.

hWndParent
Идентифицирует окно родителя или владельца создаваемого окна. Правильный дескриптор окна должен быть выдан при создании дочернего окна или окна собственника. Дочернее окно ограничено рабочей областью его родительского окна. Находящееся в собственности окно - перекрывающее окно, разрушается тогда, когда разрушено или скрыто окно его владельца, когда его владелец свернут; оно всегда отображается на верхней части окна своего владельца. Несмотря на то, что этот параметр должен определять допустимый дескриптор, если параметр dwStyle включает в себя стиль WS_CHILD, он необязателен, если в dwStyle включает в себя стиль WS_POPUP.

hMenu
Идентифицирует меню или определяет идентификатор дочернего окна в зависимости от стиля окна. Для перекрывающего или выскакивающего окна, hMenu идентифицирует меню, которое нужно использовать с окном; если должно использоваться меню класса, он может быть значением ПУСТО (NULL). Для дочернего окна, hMenu определяет идентификатор дочернего окна, целочисленное значение, используемое элементом управления диалогового окна, чтобы сообщать своему родителю о событиях. Прикладная программа определяет идентификатор дочернего окна; он должен быть уникальным для всех дочерних окон того же самого родительского окна.

hInstance
Идентифицирует экземпляр модуля, который связан с окном.

lpParam
Указывает на значение, переданное окну через структуру CREATESTRUCT, вызванную при помощи параметра lParam сообщения WM_CREATE. Если прикладная программа вызывает CreateWindow, чтобы создать пользовательское окно интерфейса многодокументной среды(MDI), lpParam должен указывать на структуру CLIENTCREATESTRUCT.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - дескриптор созданного окна. Если функция потерпела неудачу возвращаемое значение - ПУСТО (NULL). Чтобы получить расширенную информацию об ошибке вызовите функцию GetLastError.

Замечания
Перед возвратом значения, CreateWindow посылает сообщение WM_CREATE оконной процедуре.
Для перекрывающих, выскакивающих и дочерних окон CreateWindow посылает окну сообщения WM_CREATE, WM_GETMINMAXINFO и WM_NCCREATE. Параметр lParam сообщения WM_CREATE содержит указатель на структуру CREATESTRUCT. Если определен стиль WS_VISIBLE, CreateWindow посылает окну все сообщения, требующиеся для того, чтобы активизировать и показать окно.
Если стиль окна определяет строку заголовка, заголовок окна, указанный в lpWindowName отображается в строке заголовка. Когда CreateWindow используется, чтобы создать элементы управления, типа кнопок, переключателей и статических элементов управления, lpWindowName используют, чтобы определить текст на элементе управления.
Если при компоновке вашей прикладной программы Вы определяете версию Windows - 4.x, ее окна не могут иметь кнопки в строке заголовка, если они к тому же не имеют меню окна. Этого не требуется для прикладных программ, которым при компоновке Вы определили версию Windows - 3.x.

Следующие предопределенные классы элементов управления могут быть определены в параметре lpClassName:

BUTTON
(КНОПКА) Обозначает маленькое прямоугольное дочернее окно, которое представляет собой кнопку и пользователь может щелкать по ней мышью, чтобы включить или отключить ее. Кнопки управления могут использоваться самостоятельно или в группах, и они могут или быть подписаны или появляться без текста. Кнопки управления обычно изменяют свой вид, когда пользователь щелкает мышью по ним.
COMBOBOX
(КОМБИНИРОВАННОЕ ОКНО) Обозначает элемент управления, состоящий из окна со списком и поля выбора, похожего на элемент редактирования текста. При использовании этого стиля, прикладная программа должна отображать все время или окно со списком или включать раскрывающийся список. В зависимости от стиля комбинированного окна, пользователь сможет или не сможет редактировать содержание поля выбора. Если окно со списком видимо, вводимые символы внутри поля выбора подсвечивают сначала ввод в окно со списком, который соответствует печатаемым символам. Наоборот, выбор элемента в окне со списком отображает выбранный текст в поле выбора.
EDIT
(РЕДАКТИРУЕМОЕ ОКНО) Обозначает прямоугольное дочернее окно, внутри которого пользователь может напечатать с клавиатуры текст. Пользователь выбирает элемент управления и дает ему фокус клавиатуры, щелкая мышью по нему или перемещаясь в него, путем нажатия клавиши ТАБУЛЯЦИИ (TAB). Пользователь может напечатать текст, когда элемент управления редактируемого окна отображает мигающую каретку (caret); используйте мышь, чтобы перемещать курсор, выбирать символы, которые будут заменены, или установите курсор для вставки символов; или используйте КЛАВИШУ ВОЗВРАТА НА ПОЗИЦИЮ (BACKSPACE), чтобы удалять символы. Элементы управления редактируемого окна используют шрифт системы с переменным шагом и показывают на экране символы из символьного набора ANSI. Сообщение WM_SETFONT может также быть послано элементу управления окна редактирования, чтобы изменить заданный по умолчанию шрифт. Элементы управления окна редактирования увеличиваются в соответствии с табуляцией символов стольким количеством пробелов, сколько их требуются, чтобы переместить каретку в следующую позицию табуляции. Позиции табуляции принимаются такими, чтобы быть в каждом восьмом знакоместе.
LISTBOX
(ОКНО СО СПИСКОМ) Обозначает список строк символов. Этот элемент управления определяется всякий раз, когда прикладная программа должна представить список наименований, типа имен файлов, из которых пользователь может выбирать. Пользователь может выбрать строку, щелкая мышью по ней. Выбранная строка выделяется, а уведомительное сообщение передается в родительское окно. Чтобы листать списки, которые являются слишком длинными для элемента управления окна, используются вертикальная или горизонтальная линейки прокрутки окна со списком. Окно со списком автоматически скрывает или показывает линейку прокрутки, по мере необходимости. MDICLIENT
Обозначает рабочее окно МНОГОДОКУМЕНТАЛЬНОГО ИНТЕРФЕЙСА (MDI). Это окно принимает сообщения, которые управляют дочерними окнами прикладной программы МНОГОДОКУМЕНТАЛЬНОГО ИНТЕРФЕЙСА. Рекомендованный стиль содержит - WS_CLIPCHILDREN и WS_CHILD. Чтобы создать рабочее окно MDI, которое позволяет пользователю при появлении листать дочерние окна MDI, определите стили WS_HSCROLL и WS_VSCROLL. SCROLLBAR
(ЛИНЕЙКА ПРОКРУТКИ) Обозначает прямоугольник, который содержит бегунок и имеет стрелки направленные в оба конца. Линейка прокрутки посылает уведомительное сообщение своему родительскому окну всякий раз, когда пользователь щелкает мышью по элементу управления. В случае необходимости, родительское окно ответственно за модификацию позиции бегунка. Элементы управления линейкой прокрутки имеют тот же самый вид и пользуются функциями, что и линейки прокрутки, используемые в обычных окнах. Однако, в отличие от линеек прокрутки окна, линейки прокрутки элемента управления могут быть установлены для использования где-нибудь в окне, при прокрутке вводимой информации необходимой для окна. Класс линейки прокрутки включает также и элементы управления размером окна. Окно с изменяемыми размерами - это маленький прямоугольник, который пользователь может растягивать, чтобы изменить размер окна. STATIC
(СТАТИЧЕСКИЙ ЭЛЕМЕНТ) Обозначает простое текстовое поле, окно или прямоугольник, используемый для надписей, окно или другие отдельные элементы управления. Статические элементы управления не берут никакой вводимой информации и не обеспечивают никакой выводимой информации.

Ниже перечисленные стили окон могут быть определены в параметре dwStyle:

  • WS_BORDER - Создает окно, которое имеет тонкую линию рамки.
  • WS_CAPTION - Создает окно, которое имеет строку заголовка (включает в себя стиль WS_BORDER).
  • WS_CHILD - Создает дочернее окно. Этот стиль не может использоваться со стилем WS_POPUP.
  • WS_CHILDWINDOW - То же самое, что и стиль WS_CHILD.
  • WS_CLIPCHILDREN - Исключает область, занятую дочерними окнами, когда прорисовка происходит внутри родительского окна. Этот стиль используется при создании родительского окна.
  • WS_CLIPSIBLINGS - Закрепляет дочерние окна относительно друг друга, то есть когда отдельное дочернее окно принимает сообщение WM_PAINT, стиль WS_CLIPSIBLINGS закрепляет все другие перекрывающие дочерние окна вне области дочернего окна, которое нужно модифицировать. Если стиль WS_CLIPSIBLINGS не определен, а дочерние окна перекрываются, то, возможно, что при прорисовке внутри рабочей области дочернего окна, будет выводиться внутренняя рабочая область соседнего дочернего окна.
  • WS_DISABLED - Создает окно, которое первоначально заблокировано. Заблокированное окно не может принимать вводимую информацию от пользователя.
  • WS_DLGFRAME - Создает окно, которое имеет стиль рамки, обычно используемый с диалоговыми окнами. Окно с этим стилем не может иметь строку заголовка.
  • WS_GROUP - Определяет первый элемент управления в группе элементов управления. Группа состоит из этого первого элемента управления и всех определенных элементов управления после него, до следующего элемента управления со стилем WS_GROUP. Первый элемент управления в каждой группе обычно имеет стиль WS_TABSTOP, чтобы пользователь мог перемещаться из группы в группу. Пользователь может впоследствии передавать фокус клавиатуры от одной группы элементов управления в следующую группу элементов управления, используя клавиши со стрелками.
  • WS_HSCROLL - Создает окно, которое имеет горизонтальную линейку прокрутки.
  • WS_ICONIC - Создает окно, которое первоначально свернуто. Тот же самый стиль, что и WS_MINIMIZE.
  • WS_MAXIMIZE - Создает окно, которое первоначально развернуто.
  • WS_MAXIMIZEBOX - Создает окно, которое имеет кнопку Развернуть (Maximize). Не может быть объединен со стилем WS_EX_CONTEXTHELP. К тому же должен быть определен стиль WS_SYSMENU.
  • WS_MINIMIZE - Создает окно, которое первоначально свернуто. Тот же самый стиль, что и WS_ICONIC.
  • WS_MINIMIZEBOX - Создает окно, которое имеет кнопку Свернуть (Minimize). Не может быть объединен со стилем WS_EX_CONTEXTHELP. К тому же должен быть определен стиль WS_SYSMENU.
  • WS_OVERLAPPED - Создает перекрывающее окно. Перекрывающее окно имеет строку заголовка и рамку. Тот же самый стиль, что и WS_TILED.
  • WS_OVERLAPPEDWINDOW - Создает перекрывающее окно со стилями WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX и WS_MAXIMIZEBOX. Тот же самый, что и стиль WS_TILEDWINDOW.
  • WS_POPUP - Создает выскакивающее окно. Этот стиль не может использоваться со стилем WS_CHILD.
  • WS_POPUPWINDOW - Создает выскакивающее окно со стилями WS_BORDER, WS_POPUP и WS_SYSMENU. Стили WS_CAPTION и WS_POPUPWINDOW должны быть объединены, чтобы сделать меню окна (window) видимым.
  • WS_SIZEBOX - Создает окно, которое имеет установку размеров рамки окна. Тот же самое, что и стиль WS_THICKFRAME.
  • WS_SYSMENU - Создает окно, которое имеет меню окна (window-menu) в его строке заголовка. К тому же должен быть определен стиль WS_CAPTION.
  • WS_TABSTOP - Определяет элемент управления, который может принимать фокус клавиатуры, когда пользователь нажимает клавишу ТАБУЛЯЦИИ (TAB). Нажатие на клавиши табуляции передает фокус клавиатуры на следующий элемент управления со стилем WS_TABSTOP.
  • WS_THICKFRAME - Создает окно, которое имеет установку размеров рамки окна. То же самое, что и стиль WS_SIZEBOX.
  • WS_TILED - Создает перекрывающее окно. Перекрывающее окно имеет строку заголовка и рамку. То же самое, что и стиль WS_ OVERLAPPED.
  • WS_TILEDWINDOW - Создает перекрывающее окно со стилями WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX и WS_MAXIMIZEBOX. То же самое, что и стиль WS_ OVERLAPPEDWINDOW.
  • WS_VISIBLE - Создает окно, которое является первоначально видимым.
  • WS_VSCROLL - Создает окно, которое имеет вертикальную линейку прокрутки.

Ниже перечисленные стили кнопок (в классе BUTTON), которые могут быть определены в параметре dwStyle:

  • BS_3STATE - Создает кнопку, которая является такой же, как окошко для флажка, за исключением того, что поле окна может стать недоступным так же, как это делается при установке флажка ("галочки") проверки (checked) или при отмене его. Используйте недоступное состояние, чтобы показать, что состояние окошка для флажка не определено.
  • BS_AUTO3STATE - Создает кнопку, которая является таким же переключателем с тремя состояниями, за исключением того, что поле окна изменяет свое состояние, когда пользователь выбирает его. Состояние циклически проходит фазы установки флажка проверки, недоступности и отмены установки.
  • BS_AUTOCHECKBOX - Создает кнопку, которая также является окошком для флажка, за исключением того, что состояние установки флажка проверки автоматически переключается между установленным и не установленным параметром, каждый раз, когда пользователь выбирает эту кнопку.
  • BS_AUTORADIOBUTTON - Создает кнопку, которая то же, что и "радио" кнопка, за исключением того, что, когда пользователь выбирает её, Windows автоматически устанавливает состояние кнопки в режим контроля флажка, отметив ее "галочкой" и автоматически устанавливает проверку состояния для всех других кнопок в той же самой группе без проверки флажка.
  • BS_CHECKBOX - Создает маленькое, пустое окошко для флажка с текстом. По умолчанию, текст отображается справа от окошка. Чтобы отображать текст слева от окошка, объедините этот флажок со стилем BS_LEFTTEXT (или с эквивалентным стилем BS_RIGHTBUTTON).
  • BS_DEFPUSHBUTTON - Создает командную кнопку, которая ведет себя подобно кнопке стиля BS_PUSHBUTTON и к тому же имеет жирную черную рамку. Если кнопка находится в диалоговом окне, пользователь может выбрать кнопку, нажав клавишу ENTER, даже тогда, когда кнопка не имеет фокуса ввода. Этот стиль полезен для предоставления пользователю возможности быстро выбрать наиболее подходящую (заданную по умолчанию) опцию.
  • BS_GROUPBOX - Создает прямоугольник, в котором могут быть сгруппированы другие элементы управления. Любой текст, связанный с этим стилем отображается в верхнем левом угле прямоугольника.
  • BS_LEFTTEXT - Помещает текст слева от "радио" кнопки или окошечка-переключателя, когда объединен со стилем переключателя или "радио" кнопкой. Тот же самое, что и стиль BS_RIGHTBUTTON.
  • BS_OWNERDRAW - Создает кнопку представляемую владельцем. Окно владельца принимает сообщение WM_MEASUREITEM, когда кнопка создана и сообщение WM_DRAWITEM, когда внешний вид кнопки изменился. Не объединяйте стиль BS_OWNERDRAW с любыми другими стилями кнопки.
  • BS_PUSHBUTTON - Создает командную кнопку, которая отправляет сообщение WM_COMMAND окну владельца, когда пользователь выбирает эту кнопку.
  • BS_RADIOBUTTON - Создает маленький кружок с текстом. По умолчанию, текст отображается справа от кружка. Чтобы отображать текст слева от кружка, объедините этот флажок со стилем BS_LEFTTEXT (или его эквивалентом - стилем BS_RIGHTBUTTON). Используйте "радио" кнопки для групп связанного, но взаимоисключающего выбора.
  • BS_USERBUTTON - Устаревшая, но предусматривающая совместимость с 16-разрядными версиями Windows. Базирующиеся на Win32 прикладные программы должны использовать BS_OWNERDRAW взамен этого параметра.
  • BS_BITMAP - Определяет, что кнопка отображает точечный рисунок.
  • BS_BOTTOM - Помещает текст внизу прямоугольника кнопки.
  • BS_CENTER - Выравнивает текст горизонтально по центру в прямоугольнике кнопки.
  • BS_ICON - Определяет, что кнопка отображается как значок.
  • BS_LEFT - Выравнивает слева текст в прямоугольнике кнопки. Однако, если кнопка - окошечко-переключатель или "радио" кнопка, которые не имеет стиля BS_RIGHTBUTTON, текст остается выровненным справа от переключателя или "радио" кнопки.
  • BS_MULTILINE - Переносит по словам текст кнопки в дополнительные строки, если текстовая строка слишком длинна, чтобы поместиться в одной строке в прямоугольнике кнопки.
  • BS_NOTIFY - Дает возможность кнопке послать уведомительные сообщения BN_DBLCLK, BN_KILLFOCUS и BN_SETFOCUS в её родительское окно. Обратите внимание, что кнопки посылают уведомительное сообщение BN_CLICKED независимо от того, имеет ли она этот стиль.
  • BS_PUSHLIKE - Создает кнопку (типа переключателя, переключателя с тремя состояниями или "радио" кнопки) имеющую вид и действующую подобно командной кнопке. Выпуклый вид кнопки, когда она не нажата или не выбрана и притопленый, когда она нажата или выбрана.
  • BS_RIGHT - Выровненный справа текст в прямоугольнике кнопки. Однако, если кнопка - окошко для флажка или "радио" кнопка, которая не имеет стиля BS_RIGHTBUTTON, текст выровнен по правому краю справа от окошка для флажка или "радио" кнопки.
  • BS_RIGHTBUTTON - Устанавливает кружок "радио" кнопки или квадрат окошка для флажка справа от прямоугольника кнопки. Тот же самый стиль, что и BS_LEFTTEXT.
  • BS_TEXT - Определяет, что кнопка отображает текст.
  • BS_TOP - Размешает текст вверху прямоугольника кнопки.
  • BS_VCENTER - Размещает текст в середине (вертикально) прямоугольника кнопки.

Ниже перечислены стили комбинированного окна (в классе COMBOBOX), которые могут быть определены в параметре dwStyle:

  • CBS_AUTOHSCROLL - Автоматически прокручивает текст в поле редактирования текста вправо, когда пользователь вводит с клавиатуры символ в конце строки. Если этот стиль не установлен, принимается только текст, который помещается внутри прямоугольной границы поля.
  • CBS_DISABLENOSCROLL - В окне со списком показывает вертикальную линейку прокрутки заблокированной, когда поле окна содержит не достаточно элементов для прокрутки. Без этого стиля, линейка прокрутки скрыта, если окно со списком содержит не достаточно элементов.
  • CBS_DROPDOWN - Подобен CBS_SIMPLE, за исключением того, что окно со списком не отображается, пока пользователь не выберет значок рядом с полем редактирования текста.
  • CBS_DROPDOWNLIST - Подобен CBS_DROPDOWN, за исключением того, что поле редактирования текста заменено статическим текстовым элементом, который отображает текущий выбор в окне со списком.
  • CBS_HASSTRINGS - Определяет, что представляемое владельцем комбинированное окно содержит элементы, состоящие из строк. Комбинированное окно поддерживает память и адрес для строк, так что прикладная программа может использовать сообщение CB_GETLBTEXT, чтобы восстановить текст для отдельного элемента.
  • CBS_LOWERCASE - Преобразовывает в нижний регистр любые символы верхнего регистра, введенные в поле редактирования текста комбинированного окна.
  • CBS_NOINTEGRALHEIGHT - Определяет, что размер комбинированного окна - это точный размер, определенный прикладной программой, когда она создала комбинированное окно. Обычно, Windows устанавливает размеры комбинированного окна так, чтобы оно не отображало элементы частично.
  • CBS_OEMCONVERT - Преобразует текст, введенный в поле редактирования текста комбинированного окна. Текст преобразуется из набора символов Windows в набор символов OEM, а затем обратно в набор Windows. Это гарантирует соответствующее символьное преобразование, когда прикладная программа вызывает функцию CharToOem, чтобы преобразовать строку Windows в комбинированном окне в символы OEM. Этот стиль наиболее полезен для комбинированных окон, которые содержат имена файлов и применяются только в комбинированных окнах, созданных со стилем CBS_SIMPLE или CBS_DROPDOWN.
  • CBS_OWNERDRAWFIXED - Определяет, что владелец окна со списком ответственен за прорисовку его содержания и что элементы в окне со списком все равной высоты. Окно владельца принимает сообщение WM_MEASUREITEM, когда комбинированное окно создано, а сообщение WM_DRAWITEM, когда внешний вид комбинированного окна изменился.
  • CBS_OWNERDRAWVARIABLE - Определяет, что владелец окна со списком ответственен за прорисовку его содержания и что элементы в окне со списком являются переменными по высоте. Окно владельца принимает сообщение WM_MEASUREITEM для каждого элемента комбинированного окна, когда Вы создаете комбинированное окно; окно владельца принимает сообщение WM_DRAWITEM тогда, когда изменился внешний вид комбинированного окна.
  • CBS_SIMPLE - Всегда отображать окно со списком. Текущий выбор в окне со списком отображается в поле редактирования текста.
  • CBS_SORT - Автоматически сортирует строки, введенные в окно со списком.
  • CBS_UPPERCASE - Преобразовывает любые символы нижнего регистра в символы верхнего регистра, введенные в поле редактирования текста комбинированного окна.

Ниже перечисленные стили поля редактирования текста (в классе EDIT) могут быть определены в параметре dwStyle:

  • ES_AUTOHSCROLL - Автоматически прокручивает текст вправо на 10 символов, когда пользователь напечатает символ в конце строчки. Когда пользователь нажимает клавишу ENTER, управление прокручивает весь текст обратно, чтобы установить нуль.
  • ES_AUTOVSCROLL - Автоматически перемещает текст вверх на одну страницу, когда пользователь нажимает клавишу ENTER на последней строчке.
  • ES_CENTER - Выравнивает по центру текст в многостроковом поле редактирования текста.
  • ES_LEFT - Выравнивание текста слева.
  • ES_LOWERCASE - Преобразовывает все символы в нижний регистр, поскольку они печатаются внутри поля редактирования текста.
  • ES_MULTILINE - Обозначает многостроковое окно редактирования текста. Значение по умолчанию - одностроковое окно редактирования текста. Когда многостроковое поле редактирования находится в диалоговом окне, заданная по умолчанию ответная реакция на нажим клавиши ENTER должна активизировать кнопку по умолчанию. Чтобы использовать клавишу ENTER для перевода строки, стиль используйте ES_WANTRETURN. Когда многостроковое окно редактирования не в диалоговом окне и определен стиль ES_AUTOVSCROLL, поле редактирования показывает столько строчек, сколько это возможно и прокручивает вертикально, когда пользователь нажимает клавишу ENTER. Если Вы не определяете ES_AUTOVSCROLL, окно редактирования показывает столько строчек, сколько это возможно и подает звуковой сигнал, если пользователь нажимает клавишу ENTER, но больше ни строчки не может отобразиться в окне. Если Вы определяете стиль ES_AUTOHSCROLL, многостроковое окно редактирования автоматически горизонтально прокручивается, когда каретка проходит за правый край элемента управления. Чтобы запустить новую строку, пользователь должен нажать клавишу ENTER. Если Вы не определяете ES_AUTOHSCROLL, элемент управления, когда это необходимо, автоматически переносит без разрыва слова в начало следующей строки. Новая строка образуется и тогда, если пользователь нажимает клавишу ENTER. Размер окна определяет позицию перехода слова на новую строку. Если размер окна изменяется, изменяется позиция перехода на новую строку, а текст восстанавливается. Многостроковое окно редактирования текста может иметь линейки прокрутки . Окно редактирования с линейками прокрутки обрабатывают свои собственные сообщения от линейки прокрутки. Обратите внимание, что окно редактирования без линеек прокрутки, прокручивают текст, как описано в предыдущих параграфах и обрабатывают любые сообщений прокрутки, посланные родительским окном.
  • ES_NOHIDESEL - Отрицает заданное по умолчанию поведение для поля редактирования текста. Заданное по умолчанию поведение скрывает выбор, когда элемент управления теряет фокус ввода и инвертирует выбор, когда панель управления принимает фокус ввода. Если Вы определяете ES_NOHIDESEL, выбранный текст инвертируется, даже если панель управления не имеет фокуса.
  • ES_NUMBER - Позволяет ввести в поле редактирования только цифры.
  • ES_OEMCONVERT - Преобразует текст, введенный в окно редактирования. Текст преобразуется из набора символов Windows - в набор символов OEM, а затем обратно - в набор Windows. Это гарантирует соответствующее символьное преобразование, когда из прикладной программы вызывается функция CharToOem, чтобы преобразовать строку Windows в окне редактирования в символы OEM. Этот стиль наиболее полезен для окон редактирования текста, которые содержат имена файлов.
  • ES_PASSWORD - Отображает звездочку (*) вместо каждого символа, введенного с клавиатуры в окно редактирования. Вы можете использовать сообщение EM_SETPASSWORDCHAR, чтобы заменить ею символ, который отображается.
  • ES_READONLY - Не допускает пользователя к вводу или редактированию текста в окне редактирования.
  • ES_RIGHT - Выравнивает по правому краю текст в многострочном окне редактирования.
  • ES_UPPERCASE - Преобразует все символы в символы верхнего регистра, когда они вводятся в окно редактирования.
  • ES_WANTRETURN - Определяет, чтобы служебный код возврата каретки был вставлен тогда, когда пользователь нажимает клавишу ENTER при вводе текста в многострочное поле редактирования текста в диалоговом окне. Если Вы не определяете этот стиль, нажимая клавишу ENTER, вы получите тот же самый эффект, словно нажали заданную по умолчанию командную кнопку диалогового окна. Этот стиль не имеет никакого влияния в однострочном окне редактирования.


1.27.1.10 Функция CreateWindow - продолжение

Следующие стили элемента управления окна со списком (в классе LISTBOX) могут быть определены в параметре dwStyle:

  • LBS_DISABLENOSCROLL - Показывает заблокированную вертикальную линейку прокрутки в окне со списком, когда поле окна не содержит достаточно элементов для прокрутки. Если Вы не определяете этот стиль, линейка прокрутки скрыта, когда окно со списком не содержит достаточно элементов.
  • LBS_EXTENDEDSEL - Позволяет многочисленным элементам быть выбранными, при помощи использования клавиши SHIFT и мыши или специальной комбинации клавиш.
  • LBS_HASSTRINGS - Определяет, что окно со списком содержит элементы, состоящие из строк. Окно со списком сохраняет память и адреса строк, так что прикладная программа может использовать сообщение LB_GETTEXT, чтобы восстановить текст для отдельного элемента. По умолчанию, все окна со списком за исключением окон со списком предоставленных владельцем имеют этот стиль. Вы можете создать предоставляемое владельцем окно со списком с ним или без этого стиля.
  • LBS_MULTICOLUMN - Определяет многостолбцовое окно со списком, которое прокручивается горизонтально. Сообщение LB_SETCOLUMNWIDTH устанавливает ширину столбцов.
  • LBS_MULTIPLESEL - Включает или выключает выбор последовательности символов каждый раз, когда пользователь одним или двойным щелчком мыши активизирует строку символов в окне со списком. Пользователь может выбрать любое число строк.
  • LBS_NODATA - Определяет "отсутствие данных" в окне со списком. Этот стиль определяется тогда, когда число элементов в окне со списком может превысить одну тысячу. Окно со списком с "отсутствующими данными" должно иметь также стиль LBS_OWNERDRAWFIXED, но не должно иметь стилей LBS_SORT или LBS_HASSTRINGS. Окно со списком с "отсутствующими данными" имеет сходство с окном со списком предоставляемым владельцем за исключением того, что оно не содержит ни строковых или растровых данных для элемента. Команды "добавить", "вставить" или "удалить" элемент всегда игнорируют любые передаваемые элементы данных; запрос на поиск строки внутри окна всегда терпит неудачу. Windows посылает сообщение WM_DRAWITEM окну владельцу, когда элемент должен быть прорисован. ЭлементID (itemID) член структуры DRAWITEMSTRUCT, переданный с сообщением WM_DRAWITEM, определяет номер строки элемента, который будет прорисован. Окно списка с "отсутствующими данными" не посылает сообщение WM_DELETEITEM.
  • LBS_NOINTEGRALHEIGHT - Определяет, что размер окна со списком соответствует размеру, определенному прикладной программой, когда она создавала окно со списком. Обычно, Windows устанавливает величину окна со списком так, чтобы оно не отображало элементы частично.
  • LBS_NOREDRAW - Определяет, что вид окна со списком не модифицируется, когда производятся изменения. Вы можете в любое время изменить этот стиль, посылая сообщение WM_SETREDRAW.
  • LBS_NOSEL - Определяет, что окно со списком содержит элементы, которые могут просматриваться, но не выбираться.
  • LBS_NOTIFY - Сообщает родительскому окну о входящем сообщении всякий раз, когда пользователь щелкает мышью или дважды щелкает по строке в окне списка.
  • LBS_OWNERDRAWFIXED - Определяет, что владелец окна со списком ответственен за прорисовку его содержания и что элементы в окне со списком появляются одинаковой высоты. Окно владельца принимает сообщение WM_MEASUREITEM, когда окно со списком создано, а сообщение WM_DRAWITEM, когда внешний вид окна изменился.
  • LBS_OWNERDRAWVARIABLE - Определяет, что владелец окна со списком ответственен за прорисовку его содержания и что элементы в окне со списком появляются переменными по высоте. Окно владельца принимает сообщение WM_MEASUREITEM для каждого элемента в окне со списком, когда оно создано, а сообщение WM_DRAWITEM, когда внешний вид окна изменился.
  • LBS_SORT - Сортирует строки в окне со списком по алфавиту.
  • LBS_STANDARD - Сортирует строки в окне со списком в алфавитном порядке. Родительское окно принимает входящее сообщение всякий раз, когда пользователь щелкает мышью или дважды щелкает по строке. Окно со списком имеет, рамку со всех сторон.
  • LBS_USETABSTOPS - Дает возможность окну списка распознавать и развернуть символы в виде таблицы при прорисовке его строк. По умолчанию таблица занимает 32 единицы измерения диалогового окна. Единица измерения диалогового окна - горизонтальное или вертикальное расстояние. Одна горизонтальная единица диалогового окна равна четвертой части текущей единицы измерения габаритов диалогового окна. Windows вычисляет эти единицы измерения, основанные на высоте и ширине шрифта существующей системы. Функция GetDialogBaseUnits возвращает значение текущей базовой единицы измерения диалогового окна в пикселях.
  • LBS_WANTKEYBOARDINPUT - Определяет, что владелец окна списка принимает сообщения WM_VKEYTOITEM всякий раз, когда пользователь нажимает клавишу, а окно со списком имеет фокус ввода. Это дает возможность прикладной программе выполнить специальную обработку при вводе с клавиатуры.

Следующие стили линейки прокрутки (в классе SCROLLBAR) могут быть определены в dwStyle параметре:

  • SBS_BOTTOMALIGN - Выравнивает нижнюю кромку линейки прокрутки с нижней кромкой прямоугольника, определенного параметрами x, y, nWidth, и nHeight. Линейка прокрутки имеет заданную по умолчанию высоту для системных линеек прокрутки. Используйте этот стиль со стилем SBS_HORZ.
  • SBS_HORZ - Обозначает горизонтальную линейку прокрутки. Если стили ни SBS_BOTTOMALIGN, ни SBS_TOPALIGN не определены, линейка прокрутки имеет высоту, ширину и позицию, определенные x, y, nWidth и nHeight.
  • SBS_LEFTALIGN - Выравнивает левый край линейки прокрутки с левым краем прямоугольника, определенного параметрами x, y, nWidth и nHeight. Линейка прокрутки имеет заданную по умолчанию ширину для системных линеек прокрутки. Используйте этот стиль с SBS_VERT стилем.
  • SBS_RIGHTALIGN - Выравнивает правый край линейки прокрутки с правым краем прямоугольника, определенного параметрами x, y, nWidth, и nHeight. Линейка прокрутки имеет заданную по умолчанию ширину для системных линеек прокрутки. Используйте этот стиль с SBS_VERT стилем.
  • SBS_SIZEBOX - Обозначает размер окна. Если Вы не определяете ни SBS_SIZEBOXBOTTOMRIGHTALIGN, ни SBS_SIZEBOXTOPLEFTALIGN стиль, размер окна имеет высоту, ширину и позицию, определенную параметрами x, y, nWidth и nHeight.
  • SBS_SIZEBOXBOTTOMRIGHTALIGN - Выравнивает размер нижнего правого угла окна с нижним правым углом прямоугольника, определенного параметрами x, y, nWidth, и nHeight. Размер окна имеет заданный по умолчанию размер для системы размера окон. Используйте этот стиль с SBS_SIZEBOX стилем.
  • SBS_SIZEBOXTOPLEFTALIGN - Выравнивает размер верхнего левого угла окна с левым верхним углом прямоугольника, определенного параметрами x, y, nWidth, и nHeight. Размер окна имеет заданный по умолчанию размер для системы размера окон. Используйте этот стиль с SBS_SIZEBOX стилем.
  • SBS_SIZEGRIP - Подобен стилю SBS_SIZEBOX, но с выпуклой рамкой.
  • SBS_TOPALIGN - Выравнивает верхний край линейки прокрутки с верхним краем прямоугольника, определенного параметрами x, y, nWidth, и nHeight. Линейка прокрутки имеет заданную по умолчанию высоту для системы линеек прокрутки. Используйте этот стиль с SBS_HORZ стилем.
  • SBS_VERT - Обозначает вертикальную линейку прокрутки. Если Вы не определяете ни SBS_RIGHTALIGN, ни SBS_LEFTALIGN стиль, линейка прокрутки имеет высоту, ширину и позицию, определенную параметрами x, y, nWidth и nHeight.

Следующие стили статического элемента управления (в классе STATIC) могут быть определены в параметре dwStyle. Статический элемент управления может иметь только один из этих стилей:

  • SS_BITMAP - Определяет, что в статическом элементе управления должен отобразиться точечный рисунок. Текст кода ошибки - имя точечного рисунка (не имя файла) определенного в другом месте файла ресурса. Стиль игнорирует параметры nWidth и nHeight; элемент управления автоматически устанавливает собственные размеры, чтобы поместить точечный рисунок.
  • SS_BLACKFRAME - Определяет окно с рамкой, использующей тот же самый цвет, как и у рамки основного окна. Этот цвет черный по умолчанию в системе цветов Windows.
  • SS_BLACKRECT - Определяет прямоугольник, заполненный текущим цветом рамки окна. По умолчанию этот цвет черный в системе цветов Windows.
  • SS_CENTER - Определяет простой прямоугольник и выравнивает по центру текст кода ошибки в прямоугольнике. Текст форматируется перед отображением его на экране. Слова, которые выходят за пределы конца строки автоматически переносятся в начало следующей центрированной строки.
  • SS_CENTERIMAGE - Определяет, что средняя точка статического элемента управления со стилем SS_BITMAP или SS_ICON должна остаться фиксированной, когда элемент управления изменяется. Четыре стороны корректируются так, чтобы поместить новый точечный рисунок или пиктограмму. Если статический элемент управления имеет стиль SS_BITMAP, а точечный рисунок меньше чем рабочая область элемента управления, рабочая область заполняется цветом пикселя левого верхнего угла точечного рисунка. Если статический элемент управления имеет стиль SS_ICON, пиктограмма появляется, но не окрашивает рабочую область.
  • SS_GRAYFRAME - Определяет поле окна с рамкой, выведенной тем же самым цветом, что и экранный фон (рабочий стол). По умолчанию в системе цветов Windows этот цвет серый.
  • SS_GRAYRECT - Определяет прямоугольник, заполненный текущим экранным цветом фона. По умолчанию в системе цветов Windows этот цвет серый.
  • SS_ICON - Определяет пиктограмму, отображаемую в диалоговом окне. Данный текст - имя пиктограммы (не имя файла) определенный в другом месте файла ресурса. Стиль игнорирует параметры nWidth и nHeight; пиктограмма автоматически устанавливает свою величину.
  • SS_LEFT - Определяет простой прямоугольник и выравнивание по левому краю текста, помещенного в прямоугольнике. Текст форматируется перед его отображением. Слова, которые выходят за пределы конца строки автоматически переносятся в начало следующей выровненной по левой границе строки.
  • SS_LEFTNOWORDWRAP - Определяет простой прямоугольник и выравнивание по левому краю текста, помещенного в прямоугольнике. Планшеты расширяются, но слова не переносятся. Текст, который выходит за пределы конца строки, отсекается.
  • SS_METAPICT - Определяет, что изображение метафайла должно отобразиться в статическом элементе управления. Данный текст - имя изображения метафайла (не имя файла) определенный в другом месте в файле ресурса. Статический элемент управления метафайла имеет фиксированный размер; изображение метафайла масштабируется, чтобы приспособить рабочую область статического элемента управления.
  • SS_NOPREFIX - Предотвращает интерпретацию любого символа амперсанта (&) в тексте элемента управления как символа префикса акселератора. Они отображаются с удаленным амперсантом и следующим за ним подчеркнутым символом в строке. Этот стиль статического элемента управления может быть включен с любым из определенных статических элементов управления. Прикладная программа может объединять SS_NOPREFIX с другими стилями, используя поразрядный оператор OR = ИЛИ (|). Это может быть полезно, когда имена файлов или другие строки, которые могут содержать амперсант (&) должны отображаться в статическом элементе управления диалогового окна.
  • SS_NOTIFY - Посылает родительскому окну уведомительные сообщения STN_CLICKED и STN_DBLCLK, когда пользователь щелкает или дважды щелкает мышью по элементу управления.
  • SS_RIGHT - Определяет простой прямоугольник и выравнивает по правому краю текста помещенный в прямоугольнике. Текст форматируется перед его отображением на экране. Слова, которые выходят за пределы конца строки автоматически переносятся в начало следующей выровненной по правой границе строки.
  • SS_RIGHTIMAGE - Определяет, что угол правой нижней части статического элемента управления со стилем SS_BITMAP или SS_ICON должен остаться фиксированным, когда элемент управления изменяется. Только верхняя и левая стороны корректируются, чтобы поместить новый точечный рисунок или пиктограмму.
  • SS_SIMPLE - Определяет простой прямоугольник и отображает одиночную строку выровненного по левой границе текста в прямоугольнике. Текстовая строка не может быть, сокращена или изменена в любом случае. Родительское окно панели управления или диалоговое окно не должны обрабатывать сообщение WM_CTLCOLORSTATIC.
  • SS_WHITEFRAME - Определяет поле окна с рамкой, выведенной тем же самым цветом как фон окна. По умолчанию, в системе цветов Windows - этот цвет белый.
  • SS_WHITERECT - Определяет прямоугольник, заполненный текущим цветом фона окна. По умолчанию, в системе цветов Windows - этот цвет белый.

Ниже перечислены стили диалогового окна, которые могут быть определены в параметре dwStyle:

  • DS_3DLOOK - Обеспечивает диалоговое окно не полужирным шрифтом и выводит трехмерные рамки вокруг элементов управления окна в блоке диалога.
  • DS_3DLOOK - Этот стиль требуется только базирующимся на Win32 прикладным программам, компилируемым для версий Windows ранее, чем Windows 95 или Windows NT 4.0. Система автоматически применяет трехмерный вид к диалоговым окнам, созданным прикладными программами, компилируемыми для текущих версий Windows.
  • DS_ABSALIGN - Указывает, что координаты диалогового окна - экранные координаты; иначе, Windows принимает их за координаты пользователя.
  • DS_CENTER - Выравнивает по центру диалоговое окно в рабочей области; то есть в области, не загораживаемой панелью.
  • DS_CENTERMOUSE - Выравнивает по центру курсор мыши в диалоговом окне.
  • DS_CONTEXTHELP - Включает вопросительный знак в строке заголовка диалогового окна. Когда пользователь щелкает мышью по вопросительному знаку, курсор изменятся на вопросительный знак со стрелкой-указателем. Если пользователь затем щелкает мышью по элементу управления в диалоговом окне, элемент управления принимает сообщение WM_HELP. Элемент управления должен передать сообщение для диалоговой процедуры, которая должна вызвать функцию WinHelp, использующую команду HELP_WM_HELP. Прикладная программа Справка (Help) отображает выскакивающее окно, которое обычно содержит справку об элементе управления. Обратите внимание, что DS_CONTEXTHELP - только метка - заполнитель. Когда диалоговое окно создано, система проверяет наличие DS_CONTEXTHELP и, если она имеется, добавляет WS_EX_CONTEXTHELP к расширенному стилю диалогового окна. WS_EX_CONTEXTHELP не может использоваться со стилями WS_MAXIMIZEBOX или WS_MINIMIZEBOX.
  • DS_CONTROL - Создает диалоговое окно, которое работает также как дочернее окно другого диалогового окна, очень похожее на страницу в окне свойств. Этот стиль позволяет пользователю перемещаться среди элементов управления дочернего диалогового окна, использовать его клавиши-ускорители, и так далее.
  • DS_FIXEDSYS - Использует SYSTEM_FIXED_FONT вместо SYSTEM_FONT.
  • DS_LOCALEDIT - Применяется только для 16-разрядных прикладных программ. Этот стиль управляет элементами редактирования в диалоговом окне, чтобы зарезервировать память в сегменте данных прикладной программы. Иначе, элементы редактирования резервируют память объекта глобальной памяти.
  • DS_MODALFRAME - Создает диалоговое окно с модальной рамкой диалогового окна, которая может быть объединена со строкой заголовка и меню окна, путем определения стилей WS_CAPTION и WS_SYSMENU.
  • DS_NOFAILCREATE - Создает диалоговое окно, даже если происходят ошибки - например, если дочернее окно не может быть создано или если система не может создать специальный сегмент данных для элементов редактирования.
  • DS_NOIDLEMSG - Подавляет сообщения WM_ENTERIDLE, которое Windows иначе послал бы владельцу диалогового окна, в то время как диалоговое окно отображается на экране.
  • DS_RECURSE - Стиль Диалогового окна для подобно элементу управления диалоговых окон.
  • DS_SETFONT - Указывает, что шаблон диалогового окна (структура DLGTEMPLATE) содержит два дополнительных элемента, определяющих имя шрифта и размер в пунктах. Соответствующий шрифт используется, чтобы отображать текст внутри рабочей области диалогового окна и внутри элементов управления диалогового окна. Windows передает дескриптор шрифта диалоговому окну и каждому элементу управления, посылая им сообщение WM_SETFONT.
  • DS_SETFOREGROUND - Не применяется в16-разрядных версиях Microsoft Windows. Этот стиль приводит диалоговое окно в активный режим. Внутри Windows вызывает для диалогового окна функцию SetForegroundWindow.
  • DS_SYSMODAL - Создает системно-модальное диалоговое окно. Этот стиль заставляет диалоговое окно иметь стиль WS_EX_TOPMOST, но в остальном, он не имеет никакого влияния на диалоговое окно или поведение других окон в системе, когда отображается диалоговое окно.

Windows 95: система может поддерживать максимум 16,364 дескрипторов окна.

Смотри также
CharToOem, CLIENTCREATESTRUCT, CreateDialog, CREATESTRUCT, CreateWindowEx, DialogBox, DLGTEMPLATE, DRAWITEMSTRUCT, GetDialogBaseUnits, GlobalAddAtom, LB_GETTEXT, LB_SETCOLUMNWIDTH, MessageBox, RegisterClass, SetForegroundWindow, WM_COMMAND, WM_CREATE, WM_DELETEITEM, WM_DRAWITEM, WM_ENTERIDLE, WM_GETMINMAXINFO, WM_MEASUREITEM, WM_NCCREATE, WM_PAINT, WM_SETFONT, WM_SETREDRAW, WM_VKEYTOITEM

Размещение и совместимость CreateWindow

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется

Дополнительные материалы на сайте:

  • "Шаг 4 - Окно Windows на С"
  • "Шаг 43 - CreateWindow()"
  • "Шаг 170 - Создание дочерних окон на C"
  • "Шаг 97 - Структура окна на шаг впереди MFC"


1.27.1.11 Функция CreateWindowEx

(СоздатьОкноУлучшенное)

Функция CreateWindowEx создает перекрывающее, выпрыгивающее или дочернее окно с расширенным стилем; иначе, эта функция идентична функции CreateWindow. Для получения дополнительной информации о создании окна и для полного описания других параметров CreateWindowEx, см. статью CreateWindow.

Синтаксис

HWND CreateWindowEx
(
DWORD dwExStyle,			// улучшенный стиль окна
LPCTSTR lpClassName,		// указатель на зарегистрированное имя класса
LPCTSTR lpWindowName,		// указатель на имя окна
DWORD dwStyle,			// стиль окна
int x,				// горизонтальная позиция окна
int y,				// вертикальная позиция окна
int nWidth,			// ширина окна
int nHeight,			// высота окна
HWND hWndParent,			// дескриптор родительского или окна
                // собственника
HMENU hMenu,			// дескриптор меню или идентификатор
                // дочернего окна
HINSTANCE hInstance,		// дескриптор экземпляра прикладной
                // программы
LPVOID lpParam 			// указатель на данные создания окна
);

Параметры

dwExStyle
Определяет расширенный стиль окна. Этот параметр может быть одно из следующих значений:

  • WS_EX_ACCEPTFILES - Определяет, что окно, созданное с этим стилем принимает файлы при помощи информационной технологии "перетащи и вставь".
  • WS_EX_APPWINDOW - Активизирует окно верхнего уровня на панель задач, когда окно свернуто.
  • WS_EX_CLIENTEDGE - Определяет, что окно имеет рамку с углубленным краем.
  • WS_EX_CONTEXTHELP - Включает вопросительный знак в строку заголовка окна. Когда пользователь щелкает мышью по вопросительному знаку, курсор меняется на вопросительный знак с указателем. Если пользователь затем щелкает мышью по дочернему окну, потомок принимает сообщение WM_HELP. Дочернее окно должно передать сообщение родительской оконной процедуре, которая должна вызваться функцией WinHelp, использующей команду HELP_WM_HELP. Прикладная программа Справки показывает выскакивающее окно, которое обычно содержит справку для дочернего окна. WS_EX_CONTEXTHELP не может использоваться со стилями WS_MAXIMIZEBOX или WS_MINIMIZEBOX.
  • WS_EX_CONTROLPARENT - Позволяет пользователю передвигаться среди дочерних окон основного окна, используя клавишу табуляции (TAB).
  • WS_EX_DLGMODALFRAME - Создает окно, которое имеет двойную рамку; окно может быть создано (необязательно) со строкой заголовка, которую определяет стиль WS_CAPTION в параметре dwStyle.
  • WS_EX_LEFT - Окно имеет общеупотребительные свойства "выравнивания по левой границе". Это - по умолчанию.
  • WS_EX_LEFTSCROLLBAR - Если язык оболочки Еврейский, Арабский или другой язык, который придерживается иного порядка чтения, вертикальная линейка прокрутки (если появляется) - слева от рабочей области. Для других языков, этот стиль игнорируется и не обрабатывается как ошибка.
  • WS_EX_LTRREADING - Текст окна отображается, используя свойство порядка чтения Слева - Направо. Это - по умолчанию.
  • WS_EX_MDICHILD - Создает MDI дочернее окно.
  • WS_EX_NOPARENTNOTIFY - Определяет, что дочернее окно, созданное с этим стилем не посылает сообщение WM_PARENTNOTIFY родительскому окну, когда оно создается или разрушается.
  • WS_EX_OVERLAPPEDWINDOW - Объединяет стили WS_EX_CLIENTEDGE и WS_EX_WINDOWEDGE.
  • WS_EX_PALETTEWINDOW - Объединяет стили WS_EX_WINDOWEDGE, WS_EX_TOOLWINDOW и WS_EX_TOPMOST.
  • WS_EX_RIGHT - Окно имеет общеупотребительные свойства "выравнивание по правому краю". Оно зависит от класса окна. Этот стиль имеет эффект только тогда, если язык оболочек Еврейский, Арабский или другой язык, который поддерживает иной порядок выравнивания для чтения; иначе, стиль игнорируется и не обрабатывается как ошибка.
  • WS_EX_RIGHTSCROLLBAR - Вертикальная линейка прокрутки (если появляется) - справа от рабочей области. Это - по умолчанию.
  • WS_EX_RTLREADING - Если язык оболочки Еврейский, Арабский или другой язык, который придерживается иного порядка выравнивания для чтения, текст в окне отображается, используя свойства порядка чтения, Справа - Налево. Для других языков, стиль игнорируется и не обрабатывается как ошибка.
  • WS_EX_STATICEDGE - Создает окно с трехмерным стилем рамки, предполагается использовать для элементов, которые не принимают вводимую информацию от пользователя.
  • WS_EX_TOOLWINDOW - Создает окно инструментальных средств; то есть окно предполагается использовать как плавающую инструментальную панель. Окно инструментальных средств имеет строку заголовка, которая является короче, чем нормальная строка заголовка, а заголовок окна выводится, с использованием меньшего шрифта. Окно инструментальных средств не появляется в панели задач или в диалоговом окне, которое появляется, когда пользователь нажимает ALT+TAB.
  • WS_EX_TOPMOST - Определяет, что окно, созданное с этим стилем должно быть размещено выше всех, не самых верхних окон и должно стоять выше их, даже тогда, когда окно дезактивировано. Чтобы добавить или удалить этот стиль, используйте функцию SetWindowPos.
  • WS_EX_TRANSPARENT - Определяет, что окно, созданное с этим стилем должно быть прозрачным. То есть любые окна, которые появляются из-под окна, не затеняются им. Окно, созданное с этим стилем принимает WM_PAINT сообщения только после того, как все сестринские окна под ним модифицировались.
  • WS_EX_WINDOWEDGE - Определяет, что окно имеет рамку с выпуклым краем.

Использование стиля WS_EX_RIGHT для статического или редактируемого элементов управления имеет тот же самый эффект как и использование стиля SS_RIGHT или ES_RIGHT, соответственно. Использование этого стиля с командными кнопками имеет тот же самый эффект как и использование стилей BS_RIGHT и BS_RIGHTBUTTON.

lpClassName
Указывает на строку с нулевым символом в конце или на целочисленный атом. Если lpClassName - атом, он должен быть глобальным атомом, созданным предыдущим вызовом функции GlobalAddAtom. Атом, 16-разрядное значение меньше чем 0xC000, должно быть младшим словом в lpClassName; старшее слово должно быть нулевое. Если lpClassName - строка, она определяет имя класса окна. Имя класса может быть любое имя, зарегистрированное функцией RegisterClass или любым из предопределенных имен класса элементов управления.

lpWindowName
Указывает на строку с нулевым символом в конце, которая определяет имя окна.

dwStyle
Определяет стиль создаваемого окна. Что касается остального списка стилей окна, которые могут быть определены в dwStyle, см. CreateWindow.

x
Определяет начальную горизонтальную позицию окна. Для перекрывающего или выскакивающего окна параметр x - начальная x-координата левого верхнего угла окна, в экранных координатах устройства. Для дочернего окна x - x-координата левого верхнего угла окна относительно левого верхнего угла рабочей области родительского окна. Если x установлен как CW_USEDEFAULT, Windows выбирает заданную по умолчанию позицию для левого верхнего угла окна и игнорирует y параметр. Стиль CW_USEDEFAULT допустим только для перекрывающих окон; если он определен для всплывающего или дочернего окна параметры x и y устанавливаются в нуль.

y
Определяет начальную вертикальную позицию окна. Для перекрывающего или выскакивающего окна, параметр y - начальная y-координата левого верхнего угла окна, в экранных координатах устройства. Для дочернего окна, y - начальная y-координата левого верхнего угла дочернего окна относительно левого верхнего угла рабочей области родительского окна. Для окна со списком, y - начальная y-координата левого верхнего угла рабочей области окна со списком относительно левого верхнего угла рабочей области родительского окна. Если перекрывающее окно создано в стиле WS_VISIBLE с набором битов, а параметр x установлен как CW_USEDEFAULT, Windows игнорирует параметр y.

nWidth
Определяет ширину окна в единицах измерения устройства. Для перекрывающих окон nWidth - ширина окна в экранной системе координат или CW_USEDEFAULT. Если nWidth - CW_USEDEFAULT, Windows выбирает заданную по умолчанию ширину и высоту для окна; заданная по умолчанию ширина простирается от начальных x-координат до правого края экрана; заданная по умолчанию высота простирается от начальной y-координаты до верхней части области значка. Стиль CW_USEDEFAULT допустим только для перекрывающих окон; если CW_USEDEFAULT определен для выскакивающего или дочернего окна, параметры nWidth и nHeight устанавливаются в нуль.

nHeight
Определяет высоту окна в единицах измерения устройства. Для перекрывающих окон, nHeight - высота окна в экранной системе координат. Если параметр nWidth установлен как CW_USEDEFAULT, Windows игнорирует nHeight.

hWndParent
Идентифицирует родительское окно или владельца создаваемого окна. Допустимый дескриптор окна должен быть дан, когда дочернее окно или находящееся в собственности окно созданы. Дочернее окно ограничено рабочей областью родительского окна. Находящееся в собственности окно - перекрывающее окно, которое разрушается, когда окно его владельца разрушено или скрыто, когда его владелец свернут; оно всегда отображается на верхней части окна его владельца. Несмотря на то, что этот параметр должен определять правильный дескриптор, если параметр dwStyle включает в себя стиль WS_CHILD, это необязательно, если dwStyle включает в себя стиль WS_POPUP.

hMenu
Идентифицирует меню или, в зависимости от стиля окна, определяет идентификатор дочернего окна. Для перекрывающего или выскакивающего окна, hMenu идентифицирует меню, которое будет использоваться окном; этот параметр может быть значением ПУСТО (NULL), если меню класса будет использовано. Для дочернего окна, hMenu определяет идентификатор дочернего окна, целочисленное значение, используемое элементом управления диалогового окна, что-бы сообщать родителю о событиях. Прикладная программа определяет идентификатор дочернего окна; он должно быть уникальным для всех дочерних окон того же самого родительского окна.

hInstance
Идентифицирует экземпляр модуля, который будет связан с окном.

lpParam
Указывает на значение, переданное окну через структуру CREATESTRUCT, вызванную параметром lParam сообщения WM_CREATE. Если прикладная программа вызвала CreateWindow, чтобы создать пользовательское окно многодокументной среды, lpParam должен указывать на структуру CLIENTCREATESTRUCT.

Возвращаемые значения
Если функция успешно завершила работу, возвращаемое значение - дескриптор для созданного окна. Если функция потерпела неудачу, возвращаемое значение - ПУСТО (NULL).

Замечания Функция CreateWindowEx посылает создаваемому окну сообщения WM_NCCREATE, WM_NCCALCSIZE и WM_CREATE. За информацией о классах элементов управления окна, стилях окна и стилях элементов управления, используемых с этой функцией, обращайтесь к описанию функции CreateWindow. Windows 95: система может поддерживать максимум 16,364 дескрипторов окна.

Смотри также
CLIENTCREATESTRUCT, CREATESTRUCT, CreateWindow, GlobalAddAtom, RegisterClass, SetWindowPos, WM_CREATE, WM_NCCALCSIZE, WM_NCCREATE, WM_PAINT, WM_PARENTNOTIFY

Размещение и совместимость CreateWindowEx:

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		hMenu ограничено размером в (СЛОВО) WORD в Win32s


1.27.1.12 Функция DeferWindowPos

(ОтложеннаяПозицияОкна)

Функция DeferWindowPos модифицирует структуру, определяющую позицию множества окон в определенном окне. Функция затем возвращает дескриптор модифицируемой структуре. Функция EndDeferWindowPos использует информацию в этой структуре, чтобы изменить позицию и размер ряда окон одновременно. Функция BeginDeferWindowPos создает структуру.

HDWP DeferWindowPos
(
HDWP hWinPosInfo,		// дескриптор внутренней структуры
HWND hWnd,		// дескриптор размещения окна
HWND hWndInsertAfter,	// дескриптор порядка размещения
int x,			// позиция по горизонтали
int y,			// позиция по вертикали
int cx,			// ширина
int cy,			// высота
UINT uFlags 		// флажки позиционирования окна
);

Параметры

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

hWnd
Идентифицирует окно, для которого информация о модификации сохраняется в структуре.

hWndInsertAfter
Идентифицирует окно, которое предшествует установленному окну в Z-последовательности. Этот параметр должен быть дескриптор окна или одно из следующих значений:

  • HWND_BOTTOM - Размещает окно внизу Z - последовательности. Если параметр hWnd идентифицирует самое верхнее окно, окно теряет свое самое верхнее состояние и помещается внизу всех других окон.
  • HWND_NOTOPMOST - Помещает окно выше всех не самых верхних окон (то есть позади всех самых верхних окон). Этот флажок не имеет никакого эффекта, если окно - уже не самое верхнее окно.
  • HWND_TOP - Помещает окно наверху Z - последовательности.
  • HWND_TOPMOST - Помещает окно выше всех не самых верхних окон. Окно поддерживает самую верхнюю позицию даже, когда оно дезактивировано.

Этот параметр игнорируется, если флажок SWP_NOZORDER установлен в параметре uFlags.

x
Устанавливает x-координату левого верхнего угла окна.

y
Устанавливает y-координату левого верхнего угла окна.

cx
Устанавливает новую ширину окна, в пикселях.

cy
Устанавливает новую высоту окна, в пикселях.

uFlags
Устанавливает комбинацию следующих значений, которые воздействуют на размер и позицию окна:

  • SWP_DRAWFRAME - Выводит рамку (определенную в описании класса окна) вокруг окна.
  • SWP_FRAMECHANGED - Посылает окну сообщение WM_NCCALCSIZE, даже если размер окна не изменяется. Если этот флажок не установлен, WM_NCCALCSIZE посылается только тогда, когда размер окна изменяется.
  • SWP_HIDEWINDOW - Скрывает окно.
  • SWP_NOACTIVATE - Не активизирует окно. Если этот флажок не установлен, окно активизируется и перемещается в верхнюю часть или самой верхней или не самой верхней группы (в зависимости от установки параметра hWndInsertAfter).
  • SWP_NOCOPYBITS - Сбрасывает все содержание рабочей области. Если этот флажок не установлен, допустимое содержание рабочей области сохраняется и копируется обратно в рабочую область после того, как окно установлено по размеру или переустановлено.
  • SWP_NOMOVE - Сохраняет текущую позицию (игнорирует параметры X и Y).
  • SWP_NOOWNERZORDER - Не изменяет позицию окна владельца в Z-последовательности.
  • SWP_NOREDRAW - Не перерисовывает изменения. Если этот флажок установлен, никакой перерисовки любого вида не происходит. Это применяется к рабочей области, нерабочей области (включая область заголовка и полосы прокрутки) и любой части родительского окна, раскрытого в результате перемещения окна. Когда этот флажок установлен, прикладная программа должна явно лишить законной силы или перерисовывать любые части окна и родительского окна, которые необходимо переделать.
  • SWP_NOREPOSITION - То же самое, что и флажок SWP_NOOWNERZORDER.
  • SWP_NOSENDCHANGING - Предохраняет окно от приема сообщения WM_WINDOWPOSCHANGING.
  • SWP_NOSIZE - Сохраняет текущий размер (игнорирует параметры cx и cy).
  • SWP_NOZORDER - Сохраняет текущую Z-последовательность (игнорирует параметр hWndInsertAfter).
  • SWP_SHOWWINDOW - Показывает окно.

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

Замечания
Если обращение к DeferWindowPos не выполняет задачу, прикладная программа должна отказаться от операции позиционирования окна и не вызывать EndDeferWindowPos. Если SWP_NOZORDER не установлен, Windows помещает окно, идентифицированное параметром hWnd в позиции после окна, идентифицированного параметром hWndInsertAfter. Если hWndInsertAfter - ПУСТО (NULL) или HWND_TOP, Windows помещает hWnd окна наверху Z-последовательности. Если hWndInsertAfter установлен в HWND_BOTTOM, Windows помещает hWnd окна внизу Z-последовательности. Все координаты для дочерних окон - относительно левого верхнего угла рабочей области родительского окна. Окно может быть сделано самым верхним окном или установкой в hWndInsertAfter флажка HWND_TOPMOST и гарантируя, что флажок SWP_NOZORDER не установлен, или установкой позиции окна в Z-последовательности так, чтобы оно было выше любого существующего самого верхнего окна. Когда не самое верхнее окно сделано самым верхним, находящиеся в его собственности окна также делаются самыми верхними. Его владельцы, однако, не изменяются. Если ни флажок SWP_NOACTIVATE ни флажок SWP_NOZORDER не установлен (то есть, когда запросы прикладной программы, чтобы одновременно было активизировано окно, а его позиция в Z-последовательности изменена), значение, установленное в hWndInsertAfter, используются только в следующих обстоятельствах:

  • Ни флажок HWND_TOPMOST ни флажок HWND_NOTOPMOST не установлен в hWndInsertAfter.
  • Окно, идентифицированное hWnd - не активное окно.

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

Смотри также
BeginDeferWindowPos, EndDeferWindowPos, ShowWindow

Размещение и совместимость DeferWindowPos

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.13 Функция DestroyWindow

(РазрушитьОкно)

Функция DestroyWindow уничтожает определенное окно. Функция посылает сообщения WM_DESTROY и WM_NCDESTROY окну, чтобы дезактивировать его и удалить фокус клавиатуры из него. Функция также уничтожает меню окна, очищает очередь потоков сообщений, уничтожает таймеры, удаляет монопольное использование буфера обмена и разрывает цепочку просмотра окон буфера обмена (если окно имеет наверху цепочку просмотров). Если определенное окно - родитель или владелец окон, DestroyWindow автоматически уничтожает связанные дочерние или находящиеся в собственности окна, когда она уничтожает окно владельца или родителя. Функция сначала уничтожает дочерние или находящиеся в собственности окна, и затем она уничтожает окно владельца или родителя. DestroyWindow также уничтожает немодальные диалоговые окна, созданные функцией CreateDialog.

Синтаксис

BOOL DestroyWindow
(
HWND hWnd 		// дескриптор для разрушения окна
);

Параметры

hWnd
Идентификатор окна, которое будет разрушено.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение отлично от нуля. Если функция не выполняет задачу, возвращаемое значение нулевое. Чтобы получать расширенные данные об ошибках, вызовите GetLastError.

Замечания
Поток не может использовать DestroyWindow, чтобы уничтожить окно, созданное другим потоком. Если разрушаемое окно - дочернее окно, которое не имеет стиля WS_EX_NOPARENTNOTIFY, сообщение WM_PARENTNOTIFY посылается родителю.

Смотри также
CreateDialog, CreateWindow, CreateWindowEx, WM_DESTROY, WM_NCDESTROY, WM_PARENTNOTIFY

Размещение и совместимость DestroyWindow

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется

Дополнительные материалы на сайте:

  • "Шаг 59 - Сообщение WM_CLOSE"


1.27.1.14 Функция EnableWindow

(ВключитьОкно)

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

Синтаксис

BOOL EnableWindow
(
  HWND hWnd,	// дескриптор окна
  BOOL bEnable 	// флажок для включения или отключения ввода информации
);

Параметры

hWnd
Идентификатор окна, которое будет включено или заблокировано.
bEnable Определяет, включено или отключено окно. Если этот параметр - ИСТИНА (TRUE), окно включено. Если параметр - ЛОЖЬ(FALSE), окно заблокировано.

Возвращаемые значения
Если окно было предварительно заблокировано, возвращаемое значение не ноль. Если окно предварительно не было заблокировано, возвращаемое значение нулевое. Чтобы получить расширенные данные об ошибках, вызовите GetLastError.

Замечания
Если включенное состояние окна изменяется, посылается сообщение WM_ENABLE перед возвратом значения функцией EnableWindow. Если окно уже заблокировано, все его дочерние окна потенциально заблокированы, хотя они и не посылали сообщение WM_ENABLE. Окно должно быть включено прежде, чем оно может быть активизировано. Например, если прикладная программа отображает немодальное диалоговое окно и отключила его основное окно, то прикладная программа должна включить основное окно перед разрушением диалогового окна. Иначе, другое окно примет фокус клавиатуры и будет активизировано. Если дочернее окно заблокировано, это игнорируется, когда Windows пробует определить, которое окно должно принять сообщения мыши. По умолчанию, окно включено, когда оно создается. Чтобы создать окно, которое первоначально заблокировано, прикладная программа, может определить стиль WS_DISABLED в функции CreateWindow или CreateWindowEx. После того, как окно будет создано, прикладная программа может использовать EnableWindow, чтобы включить или отключить окно. Прикладная программа может использовать эту функцию, чтобы включить или отключить элемент управления в диалоговом окне. Заблокированный элемент управление не может принимать фокус клавиатуры, и при этом пользователь не может получить доступ к нему.

Смотри также
CreateWindow, CreateWindowEx, IsWindowEnabled, WM_ENABLE

Размещение и совместимость EnableWindow

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.15 Функция EndDeferWindowPos

(ОкончаниеЗадержкиПозиционированияОкна)

Функция EndDeferWindowPos одновременно модифицирует позицию и размер в одном или большем количестве окон в единственном цикле обновления экрана.

Синтаксис

BOOL EndDeferWindowPos
(
  HDWP hWinPosInfo 	//дескриптор внутренней структуры
);

Параметры

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

Возвращаемые значения
Если функция завершилась успешно, возвращается значение отличное от нуля. Если функция не выполняет задачу, возвращаемое значение нулевое. Чтобы получить расширенные данные об ошибках, вызовите GetLastError.

Замечания
Функция EndDeferWindowPos посылает каждому окну, идентифицированному во внутренней структуре, сообщения WM_WINDOWPOSCHANGING и WM_WINDOWPOSCHANGED.

Смотри также
BeginDeferWindowPos, DeferWindowPos, WM_WINDOWPOSCHANGED, WM_WINDOWPOSCHANGING

Размещение и совместимость EndDeferWindowPos

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.16 Функция EnumChildProc

(ПеречислениеДочернихПроцедур)

Функция EnumChildProc - функция повторного вызова определяемая прикладной программой, которая принимает дескрипторы дочернего окна в результате обращения к функции EnumChildWindows.

Синтаксис

BOOL CALLBACK EnumChildProc
(
HWND hwnd,		// дескриптор дочернего окна
LPARAM lParam 		// значение, определяемое приложением
);

Параметры

hwnd
Идентифицирует дочернее окно родительского окна, определенного в EnumChildWindows.
lParam
Устанавливает значение, определяемое прикладной программой, данное в EnumChildWindows.

Возвращаемые значения.
Чтобы продолжать перечисление, функция повторного вызова должна возвратить значение ИСТИНА (TRUE); чтобы остановить перечисление, она должно возвратить значение ЛОЖЬ(FALSE).

Замечания
Функция повторного вызова может выполнять любую желаемую задачу. Прикладная программа должна зарегистрировать эту функцию повторного вызова, передавая ее адрес в EnumChildWindows. EnumChildProc - метка - заполнитель для имени функции определяемой прикладной программой.

Смотри также
EnumChildWindows

Размещение и совместимость EnumChildProc

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		определяемая пользователем
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		WNDENUMPROC


1.27.1.17 Функция EnumChildWindows

(ПеречислениеДочернихОкон)

Функция EnumChildWindows перечисляет дочерние окна, которые принадлежат определенному родительскому окну, в свою очередь, передавая дескриптор каждого дочернего окна в функцию повторного вызова, определяемую программой. Функция EnumChildWindows работает до тех пор, пока не будет перечислено последнее дочернее окно или функция повторного вызова не возвратит значение ЛОЖЬ (FALSE).

Синтаксис

BOOL EnumChildWindows
(
HWND hWndParent,		// дескриптор родительского окна
WNDENUMPROC lpEnumFunc,	// указатель на функцию обратного вызова
LPARAM lParam		// значение, определяемое программой
);

Параметры

hWndParent
Идентифицирует родительское окно, чьи дочерние окна должны перечисляться.

lpEnumFunc
Указывает на определяемую программой функцию повторного вызова. Для получения дополнительной информации относительно функции повторного вызова, см. функцию повторного вызова EnumChildProc.

lParam
Устанавливает 32-разрядное, определяемое программой значение, которое будет передано в функцию повторного вызова.

Возвращаемые значения
Если функция завершилась успешно, возвращается значение отличное от нуля. Если функция потерпела неудачу, возвращаемое значение - ноль.

Замечания
Функция EnumChildWindows не перечисляет окна верхнего уровня, принадлежащие определенному окну, и при этом не перечисляет любые другие находящиеся в собственности окна. Если дочернее окно создало свои собственные дочерние окна, эта функция перечисляет также и эти окна. Дочернее окно, которое перемещено или снова установлено в Z-последовательности в течение процесса перечисления, будет перечислено правильно. Функция не перечисляет дочернее окно, которое разрушено перед перечислением или оно создано в ходе процесса перечисления. Эта функция более надежна, чем вызов в цикле функции GetWindow. Прикладная программа, которая вызывает GetWindow, чтобы выполнить эту задачу, рискует завязнуть в бесконечном цикле или в повторяющейся ссылке на дескриптор окна, которое было разрушено.

Смотри также
EnumChildProc, EnumThreadWindows, EnumWindows, GetWindow

Размещение и совместимость EnumChildWindows

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.18 Функция EnumThreadWindows

(ПеречислениеПотоковОкон)

Функция EnumThreadWindows перечисляет все не дочерние окна, связанные с потоком, передавая дескриптор каждого окна, в свою очередь, в определенную прикладной программой функцию повторного вызова. EnumThreadWindows действует до тех пор, пока не перечислит последнее окно, или пока функция повторного вызова не возвратит значение ЛОЖЬ (FALSE). Чтобы перечислить дочерние окна отдельного окна, используйте функцию EnumChildWindows. Эта функция заменяет функцию EnumTaskWindows.

Синтаксис

BOOL EnumThreadWindows
(
DWORD dwThreadId,		// идентификатор потока
WNDENUMPROC lpfn,		// указатель на функцию возврата
LPARAM lParam 		// значение, определяемое прикладной программой
);

Параметры

dwThreadId
Идентифицирует поток, окна которого должны быть перечислены.
lpfn
Указывает на определенную прикладной программой функцию повторного вызова. Для получения дополнительной информации о функции повторного вызова, см. функцию повторного вызова EnumThreadWndProc.
lParam
Определяет 32-разрядное значение определенное прикладной программой, которое будет передано в функцию повторного вызова.

Возвращаемые значения
Если функция завершилась успешно, возвращаемое значение отлично от нуля. Если функция потерпела неудачу, возвращаемое значение - ноль.

Смотри также
EnumChildWindows, EnumThreadWndProc, EnumWindows

Размещение и совместимость EnumThreadWindows

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.19 Функция EnumThreadWndProc

(ПеречислениеПроцедурПотоковОкон)

Функция EnumThreadWndProc - определяемая программой функция повторного вызова, которая принимает дескрипторы окна, связанные с потоком в результате обращения к функции EnumThreadWindows.

Синтаксис

BOOL CALLBACK EnumThreadWndProc
(
HWND hwnd,		// дескриптор окна
LPARAM lParam 		// определяемое программой значение
);

Параметры

hwnd
Идентифицирует окно, связанное с потоком, определенным в функции EnumThreadWindows.

lParam
Устанавливает определяемое программой значение, данное в функции EnumThreadWindows.

Возвращаемые значения
Чтобы продолжать перечисление, функция повторного вызова должна возвратить значение ИСТИНА (TRUE); чтобы остановить перечисление, она должна возвратить - ЛОЖЬ (FALSE).

Замечания
Функция повторного вызова может выполнять любую желаемую задачу. Прикладная программа должна зарегистрировать эту функцию повторного вызова, передавая ее адрес в функцию EnumThreadWindows. EnumThreadWndProc - метка - заполнитель для определяемого программой имени функции.

Смотри также
EnumThreadWindows

Размещение и совместимость EnumThreadWndProc

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		Определяется пользователем
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		WNDENUMPROC


1.27.1.20 Функция EnumWindows

(ПеречислениеОкон)

Функция EnumWindows перечисляет все окна верхнего уровня на экране, передавая дескриптор каждого окна, в свою очередь, в определяемую программой функцию повторного вызова. EnumWindows действует до тех пор, пока последнее окно верхнего уровня не будет перечислено, или пока функция повторного вызова не возвратит значение ЛОЖЬ (FALSE).

Синтаксис

BOOL EnumWindows
(
WNDENUMPROC lpEnumFunc,		// указатель на функцию обратного вызова
LPARAM lParam 			// определяемое программой значение
);

Параметры

lpEnumFunc
Указывает на определяемую программой функцию повторного вызова. Для получения дополнительной информации, см. функцию повторного вызова EnumWindowsProc.
lParam
Устанавливает 32-разрядное, определяемое программой значение, которое будет передано в функцию повторного вызова.

Возвращаемые значения
Если функция завершилась успешно, возвращается значение отличное от нуля. Если функция потерпела неудачу, возвращаемое значение - ноль.

Замечания
Функция EnumWindows не перечисляет дочерние окна. Эта функция более надежна, чем вызов функции GetWindow в цикле. Прикладная программа, которая вызывает GetWindow, чтобы выполнить эту задачу, рискует попасть в бесконечный цикл или на ссылку на дескриптор окна, которое было разрушено.

Смотри также
EnumChildWindows, EnumWindowsProc, GetWindow

Размещение и совместимость EnumWindows

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется


1.27.1.21 Функция EnumWindowsProc

(ПеречислениеОконныхПроцедур)

Функция EnumWindowsProc - определяемая программой функция повторного вызова, которая принимает дескрипторы окна верхнего уровня в результате вызова функции EnumWindows или EnumDesktopWindows.

Синтаксис

BOOL CALLBACK EnumWindowsProc
(
    HWND hwnd,	// дескриптор родительского окна
    LPARAM lParam 	// определяемое программой значение
);

Параметры

hwnd
Идендификатор окна верхнего уровня lParam
Устанавливает определяемое программой значение передаваемое в EnumWindows или EnumDesktopWindows.

Возвращаемые значения
Чтобы продолжить перечисление, функция повторного вызова должна возвратить значение ИСТИНА (TRUE); чтобы остановить перечисление, она должна возвратить - ЛОЖЬ (FALSE).

Замечания
Функция повторного вызова может выполнять любую желаемую задачу. Прикладная программа должна зарегистрировать эту функцию повторного вызова, передавая адрес в EnumWindows или EnumDesktopWindows. EnumWindowsProc - метка - заполнитель для определяемого программой имени функции. Тип WNDENUMPROC - указатель на функцию EnumWindowsProc.

Смотри также
EnumWindows, EnumDesktopWindows

Размещение и совместимость EnumWindowsProc

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		определяется пользователем
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		WNDENUMPROC


1.27.1.22 Функция FindWindow

(ПоискОкна)

Функция FindWindow разыскивает данные о дескрипторе окна верхнего уровня, чье имя класса и имя окна соответствуют определенным строкам. Эта функция не ищет дочерние окна.

Синтаксис

HWND FindWindow
(
LPCTSTR lpClassName,	// указатель на имя класса
LPCTSTR lpWindowName 	// указатель на имя окна
);

Параметры

lpClassName
Указывает на строку с нулевым символом в конце, которая определяет имя класса или - атом, который идентифицирует строку имени класса. Если этот параметр - атом, он должен быть общим атомом, созданным предыдущим вызовом функции GlobalAddAtom. Атом - это 16-разрядное значение, в котором должно быть помещено в младшем слове lpClassName; старшее слово должно быть нулевое.
lpWindowName
Указывает на строку с нулевым символом в конце, которая определяет имя окна (заголовок окна). Если этот параметр - ПУСТО (NULL), полное соответствие имени окна.

Возвращаемые значения
Если функция завершилась успешно, возвращаемое значение - дескриптор окна, которое имеет определенное имя класса и имя окна. Если функция терпит неудачу, возвращаемое значение - ПУСТО (NULL). Чтобы получить дополнительные данные об ошибках, вызовите GetLastError.

Смотри также
EnumWindows, FindWindowEx, GetClassName, GlobalAddAtom

Размещение и совместимость FindWindow

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется

Дополнительные материалы на сайте:

  • "Шаг 17 - Посылаем сообщение закрытия приложения"
  • "Шаг 3 - GetMenu"
  • "Шаг 6 - Рисуем в консольном окне"
  • "Шаг 116 - Посылка сообщений между программи"
  • "Шаг 117 - Обмен данными с использованием WM_COPYDATA"
  • "Шаг 6 - Связь окна с сокетом для получения сообщений"


1.27.1.23 Функция FindWindowEx

(ПоискОкнаУлучшенная) [Не поддерживается в Windows NT]

Функция FindWindowEx отыскивает данные о дескрипторе окна, имя класса и имя окна которого соответствуют определенным строкам. Функция поиска дочерних окон начинается с первого до последнего заданного дочернего окна.

Синтаксис

HWND FindWindowEx
(
HWND hwndParent,		// дескриптор родительского окна
HWND hwndChildAfter,	// дескриптор дочернего окна
LPCTSTR lpszClass,		// указатель имени класса
LPCTSTR lpszWindow		// указатель имени окна
);

Параметры

hwndParent
Идентифицирует родительское окно, чьи дочерние окна должны быть найдены. Если hwndParent - ПУСТО (NULL), функция использует окно рабочего стола как родительское окно. Функция ищет среди окон, которые являются дочерними окнами рабочего стола.
hwndChildAfter
Идентифицирует дочернее окно. Поиск начинается со следующего дочернего окна в Z - последовательности. hwndChildAfter должен быть прямое дочернее окно hwndParent, а не простое порожденное окно. Если hwndChildAfter - ПУСТО (NULL), поиск начинается с первого дочернего окна определенного параметром hwndParent. Обратите внимание, что, если и hwndParent и hwndChildAfter - ПУСТО (NULL), функция ищет все окна верхнего уровня.
lpszClass
Указывает на строку с нулевым символом в конце, которая определяет имя класса или - атом, который идентифицирует строку имени класса. Если этот параметр - атом, он должен быть общий атом, созданный предыдущим вызовом к функции GlobalAddAtom. Атом, 16-разрядное значение, в котором должно быть размещено в младшей части слова - lpszClass; старшее слово должно быть нулевое.
lpszWindow
Указывает на строку с нулевым символом в конце, которая определяет имя окна (заголовок окна). Если этот параметр ПУСТО (NULL), имена всех окон соответствующие.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - дескриптор окна, которое имеет определенный класс и имена окон. Если функция потерпит неудачу, возвращаемое значение - ПУСТО (NULL). Чтобы получить дополнительные данные об ошибках, вызовите GetLastError.

Смотри также
EnumWindows, FindWindow, GetClassName, GlobalAddAtom

Размещение и совместимость FindWindowEx

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.24 Функция GetClientRect

(ПолучитьРабочуюОбласть)

Функция GetClientRect извлекает координаты рабочей области окна. Рабочие координаты определяют левый верхний и нижний правый углы рабочей области. Поскольку рабочие координаты определены относительно левого верхнего угла рабочей области окна, координаты левого верхнего угла - (0,0).

Синтаксис

BOOL GetClientRect
(
HWND hWnd,	// дескриптор окна
LPRECT lpRect 	// адрес структуры рабочих координат
);

Параметры

hWnd
Идентифицирует окно, рабочие координаты которого должны быть возвращены.
lpRect
Указывает на структуру RECT, которая принимает рабочие координаты. Левые и верхние элементы - нулевые. Правые и нижние элементы содержат ширину и высоту окна.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение отлично от нуля. Если функция потерпит неудачу, возвращаемое значение нулевое. Чтобы получить расширенные данные об ошибках, вызовите GetLastError.

Смотри также
GetWindowRect, RECT

Размещение и совместимость GetClientRect

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется

Дополнительные материалы на сайте:

  • "Шаг 72 - Функции GetWindowRect() и GetClientRect()"
  • "Шаг 294 - Размер элемента и размер диалога"
  • "Шаг 314 - Аналог AdjustWindowsRect в MFC (CalcWindowRect)"


1.27.1.25 Функция GetDesktopWindow

(ПолучитьОкноРабочегоСтола)

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

Синтаксис

HWND GetDesktopWindow(VOID)

Параметры
У этой функции нет параметров.

Возвращаемые значения
Возвращаемое значение - дескриптор окна рабочего стола.

Смотри также
GetWindow

Размещение и совместимость GetDesktopWindow

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется

Дополнительные материалы на сайте:

  • "Шаг 133 - Рабочий стол Windows маленький обзор"
  • "Шаг 1 - Окна Windows и функции доступа к ним"
  • "Шаг 139 - Перебор шрифтов"
  • "Шаг 5 - GetWindowDC и рабочий стол"
  • "Шаг 209 - Заставка при запуске приложения"
  • "Шаг 77 - Программное выключение монитора"


1.27.1.26 Функция GetForegroundWindow

(ПолучитьПриоритетноеОкно)

Функция GetForegroundWindow возвращает значение дескриптора приоритетного окна (окна, с которым пользователь в настоящее время работает). Система присваивает немного бо-лее высокий приоритет потоку, который создает приоритетное окно, чем тот, который она дает другим потокам.

Синтаксис

HWND GetForegroundWindow(VOID)

Параметры
У этой функции нет параметров.

Возвращаемые значения
Возвращаемое значение - дескриптор приоритетного окна.

Смотри также
SetForegroundWindow

Размещение и совместимость GetForegroundWindow

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.27 Функция GetLastActivePopup

(ПолучитьПоследнееАктивноеВыскакивающееОкно)

Функция GetLastActivePopup определяет, какое самое последнее выскакивающее окно, принадлежащее заданному окну, было активно.

Синтаксис

HWND GetLastActivePopup
(
HWND hWnd 	// дескриптор окна владельца
);

Параметры

hWnd
Идентификатор окна владельца.

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

  • Окно, идентифицированное hWnd, было активно самым последним.
  • Окно, идентифицированное hWnd, не имеет каких-либо выскакивающих окон.
  • Окно, идентифицированное hWnd, не является окном верхнего уровня или оно принадле-жит другому окну.

Смотри также
AnyPopup, ShowOwnedPopups

Размещение и совместимость GetLastActivePopup

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.28 Функция GetNextWindow

(ПолучитьСледующееОкно)

Функция GetNextWindow отыскивает данные о дескрипторе следующего или предыдущего окна в Z - последовательности. Следующее окно - ниже заданного окна; предыдущее окно выше. Если заданное окно - самое верхнее окно, функция отыскивает дескриптор следующего (или пре-дыдущего) самого верхнего окна. Если определяемое окно - окно верхнего уровня, функция отыскивает дескриптор следующего (или предыдущего) окна верхнего уровня. Если определяемое окно - дочернее окно, функция ищет дескриптор следующего (или предыдущего) дочернего окна.

Синтаксис

HWND GetNextWindow
(
HWND hWnd,	// дескриптор текущего окна
UINT wCmd 	// флаг направления
);

Параметры

hWnd
Идентифицирует окно. Найденный дескриптор окна, который относится к этому окну, основан на значении параметра wCmd.

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

  • GW_HWNDNEXT - Возвращает дескриптор окна ниже данного окна.
  • GW_HWNDPREV - Возвращает дескриптор окна выше данного окна.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - дескриптор следующего (или предыдущего) окна. Если нет никакого следующего (или предыдущего) окна, возвращаемое значение - ПУСТО (NULL). Чтобы получить расширенную информацию об ошибках, вызовите GetLastError.

Замечания<
Использование этой функции точно такое же, как вызов функции GetWindow с установленным флажком GW_HWNDNEXT или GW_HWNDPREV.

Смотри также
GetTopWindow

Размещение и совместимость GetNextWindow

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.29 Функция GetParent

(ПолучитьРодителя)

Функция GetParent находит дескриптор родительского окна заданного дочернего окна.

Синтаксис

HWND GetParent
(
HWND hWnd	// дескриптор дочернего окна
);

Параметры

hWnd
Идентифицирует окно, дескриптор родительского окна которого должен быть найден.

Возвращаемые значения
Если функция завершилась успешно, возвращаемое значение - дескриптор родительского окна. Если у окна нет родительского окна, возвращаемое значение - ПУСТО (NULL). Чтобы получить более подробную информацию об ошибке, вызовите GetLastError.

Смотри также
SetParent

Размещение и совместимость GetParent

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					Нет
Замечания по платформе			Не имеется

Дополнительные материалы на сайте:

  • "Шаг 354 - Создание разных окон MDI"
  • "Сообщение от элементов на диалоговом окне"
  • "Подробности - О классах окон"


1.27.1.30 Функция GetTopWindow

(ПолучитьВерхнееОкно)

Функция GetTopWindow исследует Z - последовательность дочерних окон, связанных с определенным родительским окном и возвращает обратно дескриптор дочернего окна с верха Z - последовательности.

Синтаксис

HWND GetTopWindow
(
HWND hWnd 		// дескриптор родительского окна
);

Параметры

hWnd Идентифицирует родительское окно, дочерние окна которого должны быть проверены. Если этот параметр - ПУСТО (NULL), функция возвращает дескриптор окна с верха Z - последовательности.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - дескриптор дочернего окна наверху Z - последовательности. Если заданное окно не имеет дочерних окон, возвращаемое значение - ПУСТО (NULL). Чтобы получать расширенные данные об ошибках, используйте функцию GetLastError.

Смотри также
GetNextWindow, GetWindow

Размещение и совместимость GetTopWindow

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.31 Функция GetWindow

(ПолучитьОкно)

Функция GetWindow отыскивает дескриптор окна, который имеет определенное отношение (Z - последовательность или владелец) к заданному окну.

Синтаксис

HWND GetWindow
(
HWND hWnd,		// дескриптор первоначального окна
UINT uCmd 		// флажок отношения
);

Параметры

hWnd
Идентифицирует окно. Отыскивает дескриптор окна, относящийся к этому окну, основанному на значении параметра uCmd.

uCmd
Определяет отношение между определяемым окном и окном, чей дескриптор должен быть найден. Этот параметр может быть одним из следующих значений:

  • GW_CHILD - Найденный дескриптор идентифицирует дочернее окно наверху Z - последовательности, если определяемое окно - родительское окно; иначе, найденный дескриптор значение ПУСТО (NULL).Функция проверяет только дочерние окна заданного окна. Она не проверяет окна - потомки.
  • GW_HWNDFIRST - Найденный дескриптор идентифицирует окно того же самого типа, которое является самым высоким в Z - последовательности. Если определяемое окно - самое верхнее окно, дескриптор идентифицирует самое верхнее окно, которое является самым высоким в Z - последовательности. Если определяемое окно - окно верхнего уровня, дескриптор идентифицирует окно верхнего уровня, которое является самым высоким в Z - последовательности. Если определенное окно - дочернее окно, дескриптор идентифицирует сестринское окно, которое является самым высоким в Z - последовательности.
  • GW_HWNDLAST - Найденный дескриптор идентифицирует окно того же самого типа, который является самым низким в Z - последовательности. Если определяемое окно - самое верхнее окно, дескриптор идентифицирует самое верхнее окно, которое является самым низким в Z - последовательности. Если определяемое окно - окно верхнего уровня, дескриптор идентифицирует окно верхнего уровня, которое является самым низким в Z - последовательности. Если определяемое окно - дочернее окно, дескриптор идентифицирует сестринское окно, которое является самым низким в Z - последовательности.
  • GW_HWNDNEXT - Найденный дескриптор идентифицирует окно ниже определяемого окна в Z - последовательности. Если определяемое окно - самое верхнее окно, дескриптор идентифицирует самое верхнее окно ниже определяемого окна. Если определяемое окно - окно верхнего уровня, дескриптор идентифицирует окно верхнего уровня ниже определяемого окна. Если определяемое окно - дочернее окно, дескриптор идентифицирует сестринское окно ниже определяемого окна.
  • GW_HWNDNEXT - Найденный дескриптор идентифицирует окно ниже определяемого окна в Z - последовательности. Если определяемое окно - самое верхнее окно, дескриптор идентифицирует самое верхнее окно ниже определяемого окна. Если определяемое окно - окно верхнего уровня, дескриптор идентифицирует окно верхнего уровня ниже определяемого окна. Если определяемое окно - дочернее окно, дескриптор идентифицирует сестринское окно ниже определяемого окна.
  • GW_OWNER - Найденный дескриптор идентифицирует окно владельца определяемого окна, если таковой имеется.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - дескриптор окна. Если окно с заданным отношением к определяемому окну не существует, возвращаемое значение - ПУСТО (NULL). Чтобы получать расширенные данные об ошибках, вызовите GetLastError.

Смотри также
GetActiveWindow, GetNextWindow, GetTopWindow

Размещение и совместимость GetWindow

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.32 Функция GetWindowPlacement

(ПолучитьРазмещениеОкна)

Функция GetWindowPlacement разыскивает данные об установке внешнего вида и позиции восстановления, свертывания и развертывания определяемого окна.

Синтаксис

BOOL GetWindowPlacement
(
HWND hWnd,			// дескриптор окна
WINDOWPLACEMENT *lpwndpl 		// адрес структуры для расположения данных
);

Параметры

hWnd
Идентифицирует окно.
lpwndpl
Указывает на структуру WINDOWPLACEMENT, которая принимает информацию о позиции и состоянии вида. Перед вызовом GetWindowPlacement, установите элемент длины (length) структуры WINDOWPLACEMENT как sizeof (WINDOWPLACEMENT). GetWindowPlacement потерпит неудачу, если lpwndpl-> длина (length) установлена не правильно.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение отлично от нуля. Если функция потерпит неудачу, возвращаемое значение нулевое. Чтобы получить расширенные данные об ошибках, вызовите GetLastError.

Замечания
Элемент флажки (flags) WINDOWPLACEMENT, найденный этой функцией - всегда нуль. Если окно, идентифицированное параметром hWnd, развернуто, элемент showCmd - SW_SHOWMAXIMIZED. Если окно свернуто(минимизировано), showCmd - SW_SHOWMINIMIZED. Иначе, он - SW_SHOWNORMAL. Элемент длины(length) WINDOWPLACEMENT должен быть установлен в sizeof (WINDOWPLACEMENT). Если этот элемент установлен не правильно, функция возвратит значение ЛОЖЬ (FALSE).

Смотри также
SetWindowPlacement,WINDOWPLACEMENT

Размещение и совместимость GetWindowPlacement

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.33 Функция GetWindowRect

(ПолучитьОкноПрямоугольника)

Функция GetWindowRect отыскивает размеры рамки ограничивающей прямоугольник определяемого окна. Размеры даны в экранных координатах, которые расположены относительно левого верхнего угла экрана.

Синтаксис

BOOL GetWindowRect
(
HWND hWnd,		// дескриптор окна
LPRECT lpRect 		// адрес структуры для координат окна
);

Параметры

hWnd
Идентифицирует окно.

lpRect
Указывает на структуру RECT которая принимает экранные координаты левых верхних и нижних правых углов окна.

Возвращаемые значения
Если функция завершилась успешно, возвращается значение отличное от нуля. Если функция потерпела неудачу, возвращаемое значение - ноль. Для получения подробной информации об ошибке вызовите функцию GetLastError.

Смотри также
GetClientRect, RECT

Размещение и совместимость GetWindowRect

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется

Дополнительные материалы на сайте:

  • "Шаг 72 - Функции GetWindowRect() и GetClientRect()"


1.27.1.34 Функция GetWindowText

(ПолучитьТекстОкна)

Функция GetWindowText копирует текст строки заголовка определяемого окна (если оно имеет ее) в буфер. Если определяемое окно - элемент управления, текст элемента управления копируется.

Синтаксис

int GetWindowText
(
HWND hWnd,		// дескриптор окна или элемента управления с текстом
LPTSTR lpString,		// адрес буфера для текста
int nMaxCount 		// максимальное число символов для копирования
);

Параметры

hWnd
Идентифицирует окно или элемент управления, содержащее текст

lpString
Указывает на буфер, который примет текст.

nMaxCount
Устанавливает максимальное число символов для копирования в буфер. Если текст превышает это ограничение, он усекается.

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

Замечания
Эта функция заставляет послать сообщение WM_GETTEXT определяемому окну или элементу управления. Эта функция не может возвращать текст элемента для редактирования в другую прикладную программу.

Смотри также
GetWindowTextLength,SetWindowText, WM_GETTEXT

Размещение и совместимость GetWindowText

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


1.27.1.35 Функция GetWindowTextLength

(ПолучитьДлинуТекстаВОкне)

Функция GetWindowTextLength возвращает обратно длину, в символах, текста строки заголовка определяемого окна (если окно имеет область заголовка). Если определяемое окно - элемент управления, функция возвращает обратно длину текста внутри элемента управления.

Синтаксис

int GetWindowTextLength
(
HWND hWnd 		// дескриптор окна или панели управления с текстом
);

Параметры

hWnd
Идентифицирует окно или элемент управления.

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

Замечания
Эта функция вынуждает послать сообщение WM_GETTEXTLENGTH определяемому окну или элементу управления. При известных условиях, функция GetWindowTextLength может возвращать значение, которое является большим, чем фактическая длина текста. Это происходит с некоторыми смесями ANSI и Unicode и благодаря операционной системе, которая допускает возможное существование символов DBCS внутри текста. Возвращаемое значение, однако, будет всегда, по крайней мере, такого размера, как фактическая длина текста; Вы можете, таким образом, всегда использовать эту функцию, чтобы вести буферное распределение. Это поведение может происходить, когда прикладная программа использует и функции ANSI и общие диалоги, которые использует Unicode. Это может также происходить, когда прикладная программа использует разновидность ANSI GetWindowTextLength с окном, оконная процедура которого - Unicode, или разновидность Unicode с окном, оконная процедура которого - ANSI. Чтобы получить точную длину текста, используйте сообщения WM_GETTEXT, LB_GETTEXT, или CB_GETLBTEXT, или функцию GetWindowText.

Смотри также
CB_GETLBTEXT, GetWindowText, LB_GETTEXT, SetWindowText, WM_GETTEXT, WM_GETTEXTLENGTH

Размещение и совместимость GetWindowTextLength

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


1.27.1.36 Функция GetWindowThreadProcessId

(ПолучитьИдентификаторПотокаСоздавшегоОкно)

Функция GetWindowThreadProcessId возвращает обратно идентификатор потока, который создал определяемое окно и, необязательно, идентификатор процесса, который создал окно. Эта функция заменяет функцию GetWindowTask.

Синтаксис

DWORD GetWindowThreadProcessId
(
HWND hWnd,		// дескриптор окна
LPDWORD lpdwProcessId 	// адрес переменной для идентификатора процесса
);

Параметры

hWnd
Идентифицирует окно.
lpdwProcessId
Указывает на 32-разрядное значение, которое принимает идентификатор процесса. Если этот параметр - не, ПУСТО (NULL), GetWindowThreadProcessId копирует идентификатор процесса в 32-разрядное значение; иначе, она этого не делает.

Возвращаемые значения
Возвращаемое значение - идентификатор потока, который создает окно.

Замечания
Эта функция заменяет функцию GetWindowTask версии 3.x Windows.

Размещение и совместимость GetWindowThreadProcessId

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.37 Функция IsChild

(ЭтоДочернееОкно)

Функция IsChild проверяет, является ли окно дочерним окном или порожденным окном определяемого родительского окна. Дочернее окно - прямой потомок определяемого родительского окна, если это родительское окно находится в цепочке родительских окон; цепочка родительских окон управляет в диапазоне от оригинала перекрывающего или выскакивающего окна до дочернего окна.

Синтаксис

BOOL IsChild
(
HWND hWndParent,			// дескриптор родительского окна
HWND hWnd 			// дескриптор окна для проверки
);

Параметры

hWndParent
Идентифицирует родительское окно.
hWnd
Идентифицирует окно, которое будет проверяться.

Возвращаемые значения
Если окно - дочернее или порожденное окно заданного родительского окна, возвращаемое значение отлично от нуля. Если окно - не дочернее или порожденное окно заданного родительского окна, возвращаемое значение нулевое.

Смотри также
IsWindow, SetParent

Размещение и совместимость IsChild

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.38 Функция IsIconic

(ЭтоПиктограмма)

Функция IsIconic определяет, не свернуто ли (минимизировано) определяемое окно (до вида пиктограммы).

Синтаксис

BOOL IsIconic
(
HWND hWnd 		// дескриптор окна
);

Параметры

hWnd
Идентифицирует окно.

Возвращаемые значения
Если окно в виде пиктограммы, возвращаемое значение отлично от нуля. Если окно не в виде пиктограммы, возвращаемое значение - ноль.

Смотри также
IsZoomed

Размещение и совместимость IsIconic

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.39 Функция IsWindow

(ЭтоОкно)

Функция IsWindow определяет, идентифицирует ли дескриптор определяемого окна существующее окно.

Синтаксис

BOOL IsWindow
(
HWND hWnd 		// дескриптор окна
);

Параметры

hWnd
Устанавливает дескриптор окна.

Возвращаемые значения
Если дескриптор окна идентифицирует существующее окно, возвращаемое значение отлично от нуля. Если дескриптор окна не идентифицирует существующее окно, возвращаемое значение нулевое.

Смотри также
IsWindowEnabled, IsWindowVisible

Размещение и совместимость IsWindow

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.40 Функция IsWindowUnicode

(ЭтоОкноUnicode)

Функция IsWindowUnicode устанавливает, является ли определяемое окно родным окном Unicode.

Синтаксис

BOOL IsWindowUnicode
(
HWND hWnd 		// Дескриптор окна
);

Параметры hWnd
Идентифицирует окно.

Возвращаемые значения
Если окно - родное окно Unicode, возвращаемое значение отлично от нуля. Если окно - не, родное окно Unicode, возвращаемое значение нулевое.

Замечания
Система автоматически делает двухстороннюю трансляцию (Unicode в ANSI-ASCII) для сообщений окна. Например, если сообщение окна ANSI-ASCII послано окну с UNICODE, система преобразует это сообщение в сообщение Unicode перед вызовом оконной процедуры. Система вызывает функцию IsWindowUnicode, чтобы определить, надо ли преобразовывать сообщение. Когда эта функция возвращает значение ЛОЖЬ(FALSE), это окно - родное окно ANSI-ASCII.

Размещение и совместимость IsWindowUnicode

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		Определяет пользователь
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		WNDENUMPROC


1.27.1.41 Функция IsWindowVisible

(ЭтоОкноВидимое)

Функция IsWindowVisible находит данные о состоянии видимости заданного окна.

Синтаксис

BOOL IsWindowVisible
(
HWND hWnd 	// дескриптор окна
);

Параметры

hWnd
Идентифицирует окно.

Возвращаемые значения
Если определяемое окно и его родительское окно имеют стиль WS_VISIBLE, возвращаемое значение отлично от нуля. Если определяемое окно и его родительское окно не имеют стиля WS_VISIBLE, возвращаемое значение нулевое. Поскольку возвращаемое значение определяет, имеет ли окно стиль WS_VISIBLE, оно может быть отлично от нуля, даже если окно полностью затенено другими окнами.

Замечания
Состояние видимости окна обозначено битом стиля WS_VISIBLE. Когда стиль WS_VISIBLE установлен, окно видимое и последующая прорисовка внутри него отображается до тех пор, пока окно имеет стиль WS_VISIBLE. Любая прорисовка окна со стилем WS_VISIBLE не будет отображаться, если окно затенено другими окнами или усечено его родительским окном.

Смотри также
ShowWindow

Размещение и совместимость IsWindowVisible

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.42 Функция IsZoomed

(ОноУвеличено)

Функция IsZoomed определяет, развернуто ли окно.

Синтаксис

BOOL IsZoomed
(
HWND hWnd 	// дескриптор окна
);

Параметры

hWnd
Идентифицирует окно.

Возвращаемые значения
Если окно изменено в масштабе, возвращаемое значение отлично от нуля. Если окно не изменено в масштабе, возвращаемое значение нулевое.

Смотри также
IsIconic

Размещение и совместимость IsZoomed

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.43 Функция MoveWindow

(ПеремещениеОкна)

Функция MoveWindow изменяет позицию и габариты определяемого окна. Для окна верх-него уровня, позиция и габариты - относительно левого верхнего угла экрана. Для дочернего окна, они - относительно левого верхнего угла рабочей области родительского окна.

Синтаксис

BOOL MoveWindow
(
HWND hWnd,			// дескриптор окна
int X,				// позиция по горизонтали
int Y,				// позиция по вертикали
int nWidth,			// ширина
int nHeight,			// высота
BOOL bRepaint 			// флажок перекраски
);

Параметры

hWnd
Идентифицирует окно.
X
Устанавливает новую позицию левой стороны окна.
Y
Устанавливает новую позицию верхней части окна.
nWidth
Устанавливает новую ширину окна.
nHeight
Устанавливает новую высоту окна.
bRepaint
Определяет, должно ли окно быть перекрашено. Если этот параметр - ИСТИНА (TRUE), окно принимает сообщение WM_PAINT. Если параметр - ЛОЖЬ(FALSE), никакого перекрашивания какого-либо сорта не происходит. Это применяется к рабочей области, нерабочей области (включая строку заголовка и линейки прокрутки) и любой части родительского окна, раскрытого в результате перемещения дочернего окна. Если этот параметр - ЛОЖЬ(FALSE), прикладная программа должна явно аннулировать или перерисовать любые части окна и родительского окна, которые нуждаются в перерисовке.

Возвращаемые значения
Если функция завершилась успешно, возвращается значение отличное от нуля. Если функция потерпела неудачу, возвращаемое значение - ноль.

Замечания
Если параметр bRepaint - ИСТИНА (TRUE), Windows посылает сообщение WM_PAINT оконной процедуре немедленно после перемещения окна (то есть функция MoveWindow вызывает функцию UpdateWindow). Если bRepaint - ЛОЖЬ(FALSE), Windows помещает сообщение WM_PAINT в очередь сообщений, связанную с окном. Цикл сообщений посылает сообщение WM_PAINT только после диспетчеризации всех других сообщений в очереди. Функция MoveWindow посылает в окно сообщения WM_WINDOWPOSCHANGING, WM_WINDOWPOSCHANGED, WM_MOVE, WM_SIZE и WM_NCCALCSIZE.

Смотри также
SetWindowPos, UpdateWindow, WM_GETMINMAXINFO, WM_PAINT

Размещение и совместимость MoveWindow

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.44 Функция OpenIcon

(ОткрытьПиктограмму)

Функция OpenIcon восстанавливает свернутое (иконизированное) окно в его предыдущих размерах и позиции; затем она активизирует его.

Синтаксис

BOOL OpenIcon
(
HWND hWnd 	// дескриптор окна
);

Параметры

hWnd
Идентифицирует окно, которое будет восстановлено и активизировано.

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

Замечания
Функция OpenIcon посылает данному окну сообщение WM_QUERYOPEN.

Смотри также
CloseWindow, IsIconic, ShowWindow.

Размещение и совместимость OpenIcon

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.45 Функция SetForegroundWindow

(УстановитьПриоритетноеОкно)

Функция SetForegroundWindow переводит поток, который создал определяемое окно в приоритетный режим и активизирует окно. Ввод с клавиатуры направлен в окно, а различные визуальные ориентиры изменяются для пользователя.

Синтаксис

BOOL SetForegroundWindow
(
HWND hWnd 	// дескриптор окна, которое переводится в приоритетный режим
);

Параметры

hWnd
Идентифицирует окно, которое должно быть активизировано и переведено в приоритетный режим.

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

Замечания
Приоритетное окно - окно наверху Z-последовательности. Это - окно, с которым пользователь работает. В среде приоритетной многозадачности, Вы должны вообще дать возможность управления пользователю, окно которого является приоритетным окном. Однако прикладная программа может вызывать SetForegroundWindow, если требуется перевести себя в активный режим, чтобы отобразить критическую ошибку или информацию, которая требует непосредственного внимания пользователя. Хороший пример - это отладчик, когда он обнаруживает контрольную точку останова программы. Система назначает немного более высокий приоритет потоку, который создал приоритетное окно, чем она делает это по отношению к другим потокам.

Смотри также
GetForegroundWindow

Размещение и совместимость SetForegroundWindow

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.46 Функция SetParent

(УстановитьРодителя)

Функция SetParent заменяет родительское окно заданного дочернего окна.

Синтаксис

HWND SetParent
(
HWND hWndChild,		// Дескриптор окна, родитель которого изменяется
HWND hWndNewParent 	// Дескриптор нового родительского окна
);

Параметры

hWndChild
Идентифицирует дочернее окно.
hWndNewParent
Идентифицирует новое родительское окно. Если этот параметр - ПУСТО (NULL), окно рабочего стола становится новым родительским окном.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - дескриптор предыдущего родительского окна. Если функция не выполняет задачу, возвращаемое значение - ПУСТО (NULL). Чтобы получать дополнительные данные об ошибках, вызовите GetLastError.

Замечания
Прикладная программа может использовать функцию SetParent, чтобы установить родительское окно выскакивающего, перекрывающего или дочернего окна. Новое родительское окно и дочернее окно должны принадлежать той же самой прикладной программе. Если окно, идентифицированное параметром hWndChild видимое, Windows выполняет соответствующее изменение и перерисовку.

Смотри также
GetParent

Размещение и совместимость SetParent

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.47 Функция SetWindowLong

(УстановкаОкнаСДальнимСмещением)

Функция SetWindowLong изменяет атрибуты определяемого окна. Функция также устанавливает 32-разрядное (длинное) значение при заданном смещении в дополнительном пространстве памяти об окне.

Синтаксис

LONG SetWindowLong
(
HWND hWnd,		// дескриптор окна
int nIndex,		// значение смещения, которое устанавливается
LONG dwNewLong 		//новое значение
);

Параметры

hWnd
Идентифицирует окно и, косвенно, класс, которому окно принадлежит.
nIndex
Определяет значение смещения, отсчитываемое от нуля, которое будет установлено. Допустимые значения находятся в диапазоне от нуля до числа байтов дополнительного пространства в памяти, минус 4; например, если бы Вы установили 12 или большее количество байтов памяти дополнительного пространства, значение 8 было бы индексом к третьему 32-разрядному целому числу. Чтобы установить любое другое значение, определите одно из следующих значений:

  • GWL_EXSTYLE - Устанавливает новый расширенный стиль окна.
  • GWL_STYLE - Устанавливает новый стиль окна.
  • GWL_WNDPROC - Устанавливает новый адрес для оконной процедуры.
  • GWL_HINSTANCE - Устанавливает новый дескриптор экземпляра прикладной программы.
  • GWL_ID - Устанавливает новый идентификатор окна.
  • GWL_USERDATA - Устанавливает 32-разрядное значение, связанное с окном. Каждое окно имеет соответствующее 32-разрядное значение, предназначенное для использования прикладной программой, которая создала окно.

Следующие значения также доступны, когда параметр hWnd идентифицирует диалоговое окно:

  • DWL_DLGPROC - Устанавливает новый адрес процедуры диалогового окна.
  • DWL_MSGRESULT - Устанавливает возвращаемое значение сообщения, обработанного в процедуре диалогового окна.
  • DWL_USER - Устанавливает новую дополнительную информацию, которая является частной для прикладной программы, типа дескрипторов или указателей.

dwNewLong
Устанавливает восстановленное значение.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - предыдущее значение заданного 32-разрядного целого числа. Если функция не выполняет задачу, возвращаемое значение нулевое. Чтобы получать расширенные данные об ошибках, вызовите GetLastError. Если предыдущее значение заданного 32-разрядного целого числа нулевое, и функция завершается успешно, возвращаемое значение нулевое, но функция не очищает последние данные об ошибках. Это затрудняет определение успеха или сбоя. Чтобы бороться с этим, Вы должны очистить последние данные об ошибках, вызывая SetLastError (0) перед вызовом SetWindowLong. Тогда, функциональный сбой будет обозначен возвращаемым значением нуля и результата GetLastError, который является отличным от нуля.

Замечания
Функция SetWindowLong не выполняет задачу, если окно, заданное параметром hWnd не принадлежит тому же самому процессу, что и поток вызова. Если Вы используете функцию SetWindowLong и индекс GWL_WNDPROC, чтобы заменить оконную процедуру, оконная процедура должна соответствовать рекомендациям, заданным в описании функции повторного вызова WindowProc. Вызов SetWindowLong с индексом GWL_WNDPROC создает подкласс класса окна, которое используется, чтобы создать окно. Прикладная программа не должна быть подклассом окна, созданного другим процессом. Функция SetWindowLong создает подкласс окна, заменяя оконную процедуру, связанную с отдельным окном, вынуждая Windows вызвать новую оконную процедуру вместо предыдущей. Прикладная программа должна передавать любые сообщения, не обработанные новой оконной процедурой к предыдущей оконной процедуре, вызывая CallWindowProc. Это позволяет прикладной программе создавать цепочку оконных процедур. Резервное дополнительное пространство в памяти, устанавливает значение отличное от нуля в элементе cbWndExtra структуры WNDCLASS, используемой с функцией RegisterClass. Вы не должны вызвать SetWindowLong с индексом GWL_HWNDPARENT, чтобы заменить родителя дочернего окна. Взамен, используйте функцию SetParent.

Смотри также
CallWindowProc, GetWindowLong, GetWindowWord, RegisterClass, SetParent, SetWindowWord, WindowProc, WNDCLASS.

Размещение и совместимость SetWindowLong

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


1.27.1.48 Функция SetWindowPlacement

(УстановкаРазмещенияОкна)

Функция SetWindowPlacement устанавливает в состояние показа и восстанавливает, свертывает и развертывает позиции определяемого окна.

Синтаксис

BOOL SetWindowPlacement
(
HWND hWnd,				// дескриптор окна
CONST WINDOWPLACEMENT *lpwndpl 		// адрес структуры с данными о
                    // позиции
);

Параметры

hWnd
Идентифицирует окно.
lpwndpl
Указывает на структуру WINDOWPLACEMENT, которая устанавливает новое состояние показа и позиции окна. Перед вызовом SetWindowPlacement, установите элемент длины (length ) структуры WINDOWPLACEMENT в значение sizeof (WINDOWPLACEMENT). SetWindowPlacement не выполняет задачу, если lpwndpl-> длина (length ) установлена не правильно.

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

Замечания
Элемент длины (length) WINDOWPLACEMENT должен быть установлен в sizeof (WINDOWPLACEMENT). Если этот элемент установлен не правильно, функция возвращает значение ЛОЖЬ(FALSE).

Смотри также
GetWindowPlacement, WINDOWPLACEMENT

Размещение и совместимость SetWindowPlacement

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.49 Функция SetWindowPos

(УстановитьПозициюОкна)

Функция SetWindowPos изменяет размер, позицию и Z-последовательность дочернего, выскакивающего или верхнего уровня окна. Дочерние, выскакивающие и верхнего уровня окна размещаются по порядку согласно их появлению на экране. Самое верхнее окно принимает самый высокий ранг и становится первым окном в Z-последовательности.

Синтаксис

BOOL SetWindowPos
(
HWND hWnd,			// дескриптор окна
HWND hWndInsertAfter,		// дескриптор порядка размещения
int X,				// позиция по горизонтали
int Y,				// позиция по вертикали
int cx,				// ширина
int cy,				// высота
UINT uFlags 			// флажки позиционирования окна
);

Параметры

hWnd
Идентифицирует окно.
hWndInsertAfter
Идентифицирует окно, которое предшествует установленному окну в Z-последовательности. Этот параметр должен быть дескриптор окна или одно из следующих значений:

  • HWND_BOTTOM - Помещает окно внизу Z-последовательности. Если параметр hWnd идентифицирует самое верхнее окно, окно теряет своё самое верхнее состояние и помещается внизу всех других окон.
  • HWND_NOTOPMOST - Помещает окно перед всеми не в самыми верхними окнами (то есть позади всех самых верхних окон). Этот флажок не имеет никакого влияния, если окно - уже не самое верхнее окно.
  • HWND_TOP - Помещает окно наверху Z-последовательности.
  • HWND_TOPMOST - Помещает окно перед не самыми верхними окнами. Окно сохраняет свою самую верхнюю позицию даже тогда, когда оно неактивное.

Для получения дополнительной информации о том, как использовать этот параметр, см. следующий раздел Замечания.
X
Устанавливает новую позицию с левой стороны окна.
Y
Устанавливает новую позицию верхней части окна.
cx
Устанавливает новую ширину окна, в пикселях.
cy
Устанавливает новую высоту окна, в пикселях.
uFlags
Определяет флажки, устанавливающие размеры и позиционирование окна. Этот параметр может быть комбинацией следующих значений:

  • SWP_DRAWFRAME - Выводит рамку (определенную в описании класса окна) вокруг окна.
  • SWP_FRAMECHANGED - Посылает сообщение WM_NCCALCSIZE окну, даже тогда, когда размер окна не изменяется. Если этот флажок не установлен, WM_NCCALCSIZE посылается только тогда, когда размер окна изменяется.
  • SWP_HIDEWINDOW - Скрывает окно.
  • SWP_NOACTIVATE - Не активизирует окно. Если этот флажок не установлен, окно активизируется и перемещается в верхнюю часть или самой верхней, или не самой верхней группы (в зависимости от установки параметра hWndInsertAfter).
  • SWP_NOCOPYBITS - Сбрасывает все содержание рабочей области. Если этот флажок не установлен, допустимое содержание рабочей области сохраняется и копируется обратно в рабочую область после того, как окно установлено по размеру или переустановлено.
  • SWP_NOMOVE - Сохраняет текущую позицию (игнорирует X и Y параметры).
  • SWP_NOOWNERZORDER - Не изменяет позицию окна владельца в Z-последовательности.
  • SWP_NOREDRAW - Не перерисовывает изменения. Если этот флажок установлен, то не происходит никакой перерисовки любого вида. Это применяется к рабочей области, нерабочей области (включая строку заголовка и линейки прокрутки) и любую часть родительского окна, раскрытого в результате перемещения окна. Когда этот флажок установлен, прикладная программа должна явно лишить законной силы или перерисовывать любые части окна и родительского окна, которые требуют перерисовки.
  • SWP_NOREPOSITION - То же самое, что и флажок SWP_NOOWNERZORDER.
  • SWP_NOSENDCHANGING - Предохраняет окно от приема сообщения WM_WINDOWPOSCHANGING.
  • SWP_NOSIZE - Сохраняет текущий размер (игнорирует cx и cy параметры).
  • SWP_NOZORDER - Сохраняет текущую Z-последовательность (игнорирует параметр hWndInsertAfter).
  • SWP_SHOWWINDOW - Отображает окно.

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

Замечания
Если установлены флажки SWP_SHOWWINDOW или SWP_HIDEWINDOW, окно не может быть перемещено или изменен его размер. Все координаты для дочерних окон - рабочие координаты (относительно левого верхнего угла рабочей области родительского окна). Окно может быть сделано самым верхним окном или, путем установки параметра hWndInsertAfter в HWND_TOPMOST с гарантией того, что флажок SWP_NOZORDER не установлен, или, путем установки позиции окна в Z-последовательности так, чтобы оно было выше любого существующего самого верхнего окна. Когда не самое верхнее окно делается самым верхним, находящиеся в его собственности окна также делаются самыми верхними. Его владельцы, однако, не изменяются. Если ни флажок SWP_NOACTIVATE, ни флажок SWP_NOZORDER не установлен (то есть, когда прикладная программа потребовала, чтобы окно было одновременно, и активизировано, и чтобы его позиция изменилась в Z-последовательности), значение, заданное в hWndInsertAfter, используются только в следующих обстоятельствах:

  • Ни флажок HWND_TOPMOST ни флажок HWND_NOTOPMOST не установлен в hWndInser-tAfter.
  • Окно, идентифицированное hWnd - не активное окно.

Прикладная программа не может активизировать неактивное окно без такого же обеспечения ему в верхней части Z-последовательности. Прикладные программы могут изменять позицию активизированного окна в Z-последовательности без ограничений, или они могут активизировать окно, а затем переместить его в верхнюю часть самых верхних или не самых верхних окон. Если самое верхнее окно переустановлено в нижней части (HWND_BOTTOM) Z-последовательности или после любого не самого верхнего окна, оно больше не самое верхнее. Когда самое верхнее окно сделано не самым верхним, его владельцы и находящиеся в его собственности окна также делаются не самыми верхними окнами. Не самое верхнее окно может владеть самым верхним окном, а наоборот не может происходить. Любое окно (например, диалоговое окно) принадлежащее самому верхнему окну самостоятельно делается самым верхним окном, гарантируя, что все окна находящиеся во владении находятся выше их владельца. Если прикладная программа не в активном режиме, а должна быть в активном режиме, она должна вызвать функцию SetForegroundWindow.

Смотри также
MoveWindow, SetActiveWindow, SetForegroundWindow

Размещение и совместимость SetWindowPos

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.50 Функция SetWindowText

(УстановитьТекстовоеОкно)

Функция SetWindowText изменяет текст строки заголовка заданного окна (если таковая имеется). Если определяемое окно - элемент управления, то его текст изменяется.

Синтаксис

BOOL SetWindowText
(
HWND hWnd,		// дескриптор окна или элемента управления
LPCTSTR lpString 		// адрес строчки
);

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

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

Замечания
Функция SetWindowText вызывает сообщение WM_SETTEXT, которое будет послано определяемому окну или элементу управления. Если окно - элемент управления окна со списком, созданное в стиле WS_CAPTION, то, не смотря на это, SetWindowText устанавливает текст для элемента управления, а не для ввода в окно списка. Функция SetWindowText не увеличивает размер символов табуляции (код ASCII 0x09). Символы табуляции отображаются как символы вертикальной черты (|).

Смотри также
GetWindowText, WM_SETTEXT

Размещение и совместимость SetWindowText

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


1.27.1.51 Функция ShowOwnedPopups

(ПоказатьСобственноеВыскакивающееОкно)

Функция ShowOwnedPopups показывает или скрывает все выскакивающие окна, принадлежащие определяемому окну.

Синтаксис

BOOL ShowOwnedPopups
(
HWND hWnd,	// дескриптор окна
BOOL fShow 	// флажок показа окна
);

Параметры

hWnd
Идентифицирует окно, которое владеет выскакивающими окнами, которые будут показаны или скрыты.
fShow
Устанавливает, должны ли выскакивающие окна быть показаны или скрыты. Если этот параметр - ИСТИНА (TRUE), все скрытые выскакивающие окна показываются. Если этот параметр - ЛОЖЬ(FALSE), все видимые выскакивающие окна скрываются.

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

Замечания
ShowOwnedPopups показывает только окна, которые были скрыты предыдущим обращением к функции ShowOwnedPopups. Например, если выскакивающее окно было скрыто, при помощи использования функции ShowWindow, впоследствии вызыв функции ShowOwnedPopups с установкой в ней параметра fShow в значение ИСТИНА (TRUE) не заставит окно быть показанным.

Смотри также
IsWindowVisible, ShowWindow

Размещение и совместимость ShowOwnedPopups

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.52 Функция ShowWindow

(ПоказатьОкно)

Функция ShowWindow устанавливает состояние показа определяемого окна.

Синтаксис

BOOL ShowWindow
(
HWND hWnd,	// дескриптор окна
int nCmdShow 	// состояние показа окна
);

Параметры hWnd
Идентифицирует окно.
nCmdShow
Определяет, как окно должно быть показано. Этот параметр первоначально игнорируется, когда прикладная программа вызывает ShowWindow, если программа, которая запустила прикладную программу, обеспечивает структуру STARTUPINFO. Иначе, при первом вызове функции ShowWindow, это значение должно быть значением, полученным функцией WinMain в ее параметре nCmdShow. В последующих обращениях, этот параметр может быть одним из следующих значений:

  • SW_HIDE - Скрывает окно и активизирует другое окно.
  • SW_MAXIMIZE - Развертывает определяемое окно.
  • SW_MINIMIZE - Свертывает определяемое окно и активизирует следующее окно верхнего уровня в Z-последовательности.
  • SW_RESTORE - Активизирует и отображает окно. Если окно свернуто или развернуто, Windows восстанавливает в его первоначальных размерах и позиции. Прикладная программа должна установить этот флажок при восстановлении свернутого окна.
  • SW_SHOW - Активизирует окно и отображает его текущие размеры и позицию.
  • SW_SHOWDEFAULT - Устанавливает состояние показа, основанное на флажке SW_, определенном в структуре STARTUPINFO, переданной в функцию CreateProcess программой, которая запустила прикладную программу.
  • SW_SHOWMAXIMIZED - Активизирует окно и отображает его как развернутое окно.
  • SW_SHOWMINIMIZED - Активизирует окно и отображает его как свернутое окно.
  • SW_SHOWMINNOACTIVE - Отображает окно как свернутое окно. Активное окно остается активным.
  • SW_SHOWNA - Отображает окно в его текущем состоянии. Активное окно остается активным.
  • SW_SHOWNOACTIVATE - Отображает окно в его самом современном размере и позиции. Активное окно остается активным.
  • SW_SHOWNORMAL - Активизирует и отображает окно. Если окно свернуто или развернуто, Windows восстанавливает его в первоначальном размере и позиции. Прикладная программа должна установить этот флажок при отображении окна впервые.

Возвращаемые значения
Если функция завершилась успешно, возвращается значение отличное от нуля. Если функция потерпела неудачу, возвращаемое значение - ноль.

Замечания
Первый раз, когда программа вызывает ShowWindow, она использует параметр nCmdShow функции WinMain как свой параметр nCmdShow. Последующие обращения к ShowWindow должны использовать одно из значений в данном списке, вместо того, заданного функцией WinMain параметра nCmdShow. Как отмечено в обсуждении параметра nCmdShow, значение nCmdShow игнорируется при первом обращении к ShowWindow, если программа, которая запустила прикладную программу, определяет информацию автозапуска в структуре STARTUPINFO. В этом случае, ShowWindow использует информацию, заданную в структуре STARTUPINFO, чтобы показать окно. На последующих обращениях, прикладная программа должна вызвать ShowWindow с установкой nCmdShow в SW_SHOWDEFAULT, чтобы использовать информацию автозапуска, обеспеченную программой, которая запустила прикладную программу. Например, программа Program Manager устанавливает, что прикладные программы начинаются со свернутого основного окна. Это поведение разработано для следующих ситуаций:

  • Прикладные программы создают свое основное окно, вызывая CreateWindow с установкой флажка WS_VISIBLE.
  • Прикладные программы создают свое основное окно, вызывая CreateWindow со сброшенным флажком WS_VISIBLE, а при более позднем обращении к ShowWindow с установкой флаж-ка SW_SHOW, чтобы делать его видимым.

Смотри также
CreateProcess, CreateWindow, ShowOwnedPopups, STARTUPINFO, WinMain

Размещение и совместимость ShowWindow

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется

Дополнительные материалы на сайте:

  • "Шаг 57 - Функции ShowWindow() и UpdateWindow()"


1.27.1.53 Функция ShowWindowAsync

(АсинхронныйПоказОкна) [Не поддерживается в Windows NT]

Функция ShowWindowAsync устанавливает состояние показа окна, созданного различными потоками.

Синтаксис

BOOL ShowWindowAsync
(
    HWND hWnd,	// дескриптор окна
    int nCmdShow	// состояние показа окна
);

Параметры

hWnd
Идентифицирует окно.
nCmdShow
Устанавливает, как окно должно быть показано. Для списка возможных значений, см. описание функции ShowWindow.

Возвращаемые значения
Если функция завершилась успешно, возвращается значение отличное от нуля. Если функция потерпела неудачу, возвращаемое значение - ноль.

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

Смотри также
ShowWindow

Размещение и совместимость ShowWindowAsync

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.54 Функция TileWindows

(МозаикаОкон) [Не поддерживается в Windows NT]

Функция TileWindows располагает "мозаикой" определяемые окна или дочерние окна заданного родительского окна.

Синтаксис

WORD WINAPI TileWindows
(
HWND hwndParent,			// дескриптор родительского окна
UINT wHow,			// типы окон, которые не упорядочиваются
CONST RECT *lpRect,		// прямоугольник, где упорядочиваются окна
UINT cKids,			// упорядочиваемое число окон
const HWND FAR *lpKids		// массив дескрипторов окна
);

Параметры

hwndParent
Идентифицирует родительское окно. Если этот параметр - ПУСТО (NULL), предполагается окно рабочего стола.
wHow Определяет типы окон, которые не упорядочиваются, или слева направо или горизонтально. Этот параметр может быть одним из следующих значений, объединенных с нулем или большим количеством значений, перечисленных в функции CascadeWindows:

  • MDITILE_HORIZONTAL - Располагает "мозаикой" окна горизонтально.
  • MDITILE_VERTICAL - Располагает "мозаикой" окна вертикально.

lpRect
Указывает на структуру SMALL_RECT, которая устанавливает прямоугольную область, в экранных координатах, внутри которой помещены окна. Если этот параметр - ПУСТО (NULL), используется рабочая область родительского окна.
cKids
Устанавливает число элементов в массиве, заданном параметром lpKids. Этот параметр игнорируется, если lpKids - ПУСТО (NULL).
lpKids
Указывает на массив дескрипторов окна, идентифицирующих окна, которые упорядочиваются. Если этот параметр - ПУСТО (NULL), размещаются дочерние окна заданного родительского окна (или окна рабочего стола).

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - число размещенных окон. Если функция не выполняет задачу, возвращаемое значение нулевое.

Смотри также
CascadeWindows, SMALL_RECT

Размещение и совместимость TileWindows

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.55 - Функция WindowFromPoint

(ОкноИзПункта)

Функция WindowFromPoint отыскивает дескриптор окна, которое содержит заданный пункт.

Синтаксис

HWND WindowFromPoint
(
POINT Point 	// структура с отметкой
);

Параметры

Point
Определяет структуру POINT, определяющую пункт, которая был отмечен.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - дескриптор окна, которое содержит отметку. Если никакого окна не существует в данной отметке, возвращаемое значение - ПУСТО (NULL).

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

Смотри также
ChildWindowFromPoint, POINT, WindowFromDC

Размещение и совместимость WindowFromPoint

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.56 Функция WinMain

(ГлавноеОкно)

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

Синтаксис:

int WINAPI WinMain
(
HINSTANCE hInstance,		// дескриптор текущего экземпляра окна
HINSTANCE hPrevInstance,		// дескриптор предыдущего экземпляра окна
LPSTR lpCmdLine,			// указатель на командную строку
int nCmdShow 			// показывает состояние окна
);

Параметры

hInstance
Идентифицирует текущий образец прикладной программы.
hPrevInstance
Идентифицирует предыдущий образец прикладной программы. Для базирующейся на Win32 прикладной программы, этот параметр всегда имеет значение ПУСТО (NULL). Если Вам нужно обнаружить, существует ли другой образец уже существующей программы, создайте именованный mutex-объект, используя функцию CreateMutex. Если функция GetLastError возвращает сообщение ERROR_ALREADY_EXISTS, другой образец вашей прикладной программы существует (это создано mutex-объектом).
lpCmdLine
Указывает на строку с нулевым символом в конце, определяющую командную строку для прикладной программы.
nCmdShow
Определяет, как окно должно быть показано. Этот параметр может быть одним из следующих значений:

  • SW_HIDE - Скрывает окно и активизирует другое окно.
  • SW_MINIMIZE - Минимизирует определенное окно и активизирует окно верхнего уровня в списке системы.
  • SW_RESTORE - Активизирует и отображает окно. Если окно минимизировано или развернуто, Windows восстанавливает его в первоначальном размере и позиции (то же самое, что и SW_SHOWNORMAL).
  • SW_SHOW - Активизирует и отображает окно на экране в его текущем размере и позиции.
  • SW_SHOWMAXIMIZED - Активизирует окно и отображает его как развернутое окно.
  • SW_SHOWMINIMIZED - Активизирует окно и отображает его как пиктограмму.
  • SW_SHOWMINNOACTIVE - Отображает окно как пиктограмму. Активное окно остается активным.
  • SW_SHOWNA - Отображает окно в его текущем состоянии. Активное окно остается активным.
  • SW_SHOWNOACTIVATE - Отображает окно в его самых последних размерах и позиции. Активное окно остается активным.
  • SW_SHOWNORMAL - Активизирует и отображает окно. Если окно минимизировано или развернуто, Windows восстанавливает его в первоначальный размер и позицию (то же самое, что и SW_RESTORE).

Возвращаемые значения
Если функция достигла цели, она завершается тогда, когда примет сообщение WM_QUIT, она должно возвратить значение выхода, содержащееся в параметре этого сообщения wParam. Если функция завершается перед вводом цикла сообщения, она должна возвратить 0.

Замечания
WinMain инициализирует прикладную программу, отображает на экране её основное окно и, затем, входит в цикл сообщений " поиск и отправка по назначению (диспетчеризация)", который является управляющей структурой верхнего уровня для остальных элементов выполнения прикладной программы. Цикл сообщений завершается, когда получено сообщение WM_QUIT. В этой точке, WinMain завершает работу прикладной программы, возвращая значение, переданное в параметр wParam сообщения WM_QUIT. Если WM_QUIT было получено в результате вызова PostQuitMessage, значение wParam - значение параметра nExitCode функции PostQuitMessage. Для получения дополнительной информации, см. Создание Цикла Сообщений (Creating a Message Loop).

Смотри также
CreateMutex, DispatchMessage, GetMessage, PostQuitMessage, TranslateMessage

Размещение и совместимость WinMain

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека
Заголовочный файл			winbase.h
Unicode				Нет
Замечания по платформе		Не имеется

Дополнительные материалы на сайте:

  • "Шаг 118 - Функции CreateMutex() и ReleaseMutex()"
  • "Шаг 42 - Функция WinMain()"


1.27.1.57 Функция AnyPopup

(ЛюбоеВыскакивающее)

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

Синтаксис

BOOL AnyPopup(VOID)

Параметры
У этой функции нет параметров

Возвращаемые значения
Если выскакивающее окно существует, возвращаемое значение отлично от нуля, даже если выскакивающее окно полностью перекрыто другими окнами. Если выскакивающее окно не существует, возвращаемое значение - нуль.

Замечания
AnyPopup - функция версии Windows 1.x и сохраняется для целей совместимости. Вообщем-то она бесполезна. Эта функция не обнаруживает, не находящиеся в собственности выскакивающие окна или окна, в которых не установлен бит стиля WS_VISIBLE.

Смотри также
GetLastActivePopup, ShowOwnedPopups

Размещение и совместимость AnyPopup

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.1.58 Функция EnumTaskWindows

(ПеречислениеЗадачОкон)

Функция EnumTaskWindows устаревшая. Она была заменена функцией EnumThreadWindows. Чтобы поддерживать совместимость для 16-разрядных прикладных программ, функция EnumTaskWindows была заменена на макрокоманду, которая вызывает EnumThreadWindows. Более ранние прикладные программы могут продолжать вызывать EnumTaskWindows, как прежде было документировано, но новые прикладные программы должны использовать EnumThreadWindows.


1.27.1.59 Функция GetSysModalWindow

(ПолучитьСистемноеМодальноеОкно)

Функция GetSysModalWindow устаревшая. Эта функция предоставляется только для совместимости с 16-разрядными версиями Windows.


1.27.1.60 Функция GetWindowTask

(ПолучитьЗадачуОкна)

Функция GetWindowTask устаревшая. Эта функция предоставляется только для совместимости с 16-разрядными версиями Windows. Базирующиеся на Win32 прикладные программы должны использовать функцию GetWindowThreadProcessId.


1.27.1.61 Функция SetSysModalWindow

(УстановитьСистемноеМодальное Окно)

Функция SetSysModalWindow устаревшая. Эта функция используется только для совместимости с 16-разрядными версиями Windows. Новая модель ввода данных не принимает во внимание окна System Modal.


1.27.2 Структуры окна

Ниже перечисленные структуры используются для создания и управления окнами.


1.27.2.1 Структура CLIENTCREATESTRUCT

Структура CLIENTCREATESTRUCT содержит информацию о меню и первом рабочем окне дочернего окна многодокументной среды (MDI). Прикладная программа передает указатель на эту структуру как параметр lpvParam функции CreateWindow при создании многодокументального интерфейса (MDI) окна пользователя.

Синтаксис

typedef struct tagCLIENTCREATESTRUCT
{
HANDLE hWindowMenu;
UINT	idFirstChild;
}
CLIENTCREATESTRUCT;

Элементы структуры hWindowMenu
Идентифицирует дескриптор меню Окна MDIMDI окна, используя функцию GetSubMenu.
idFirstChild
Определяет идентификатор дочернего окна первого созданного дочернего окна (MDI). Windows увеличивает идентификатор для каждого дополнительного дочернего окна Многодокументального Интерфейса (MDI), прикладная программа создает и переназначает идентификаторы, когда прикладная программа уничтожает окно, чтобы сохранить диапазон непрерывных идентификаторов. Эти идентификаторы используются в сообщениях WM_COMMAND, посланных рамочному окну (MDI) прикладной программы, когда дочернее окно выбрано из меню Окна; они не должны находиться в противоречии с любыми другими командными идентификаторами.

Смотри также
CreateWindow, GetSubMenu, MDICREATESTRUCT, WM_COMMAND

Размещение и совместимость CLIENTCREATESTRUCT

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.2.2 Структура COPYDATASTRUCT

Структура COPYDATASTRUCT содержит данные, которые будут переданы в другую прикладную программу в соответствии с сообщением WM_COPYDATA.

Синтаксис

typedef struct tagCOPYDATASTRUCT
{
DWORD dwData;
DWORD cbData;
PVOID lpData;
} COPYDATASTRUCT;

Элементы

dwData
Устанавливает до 32 битов данных, которые будут переданы в принимающую прикладную программу.
cbData
Устанавливает размер, в байтах, данных, указанных элементом структуры lpData.
lpData
Указывает на данные, которые будут переданы в принимающую прикладную программу. Этот элемент структуры может быть значением ПУСТО (NULL).

Смотри также WM_COPYDATA

Размещение и совместимость COPYDATASTRUCT

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется

Дополнительные материалы на сайте:

  • "Шаг 117 - Обмен данными с использованием WM_COPYDATA"


1.27.2.3 Структура CREATESTRUCT

Структура CREATESTRUCT определяет параметры инициализации, передаваемые оконной процедуре прикладной программы.

Синтаксис

typedef struct tagCREATESTRUCT
{
LPVOID  lpCreateParams;
HINSTANCE hInstance;
HMENU     hMenu;
HWND      hwndParent;
int       cy;
int       cx;
int       y;
int       x;
LONG      style;
LPCTSTR   lpszName;
LPCTSTR   lpszClass;
DWORD     dwExStyle;
} CREATESTRUCT;

Элементы структуры lpCreateParams
Указывает на данные, которые нужно использовать для создания окна. Windows NT: Этот элемент структуры является значением адреса со спецификатором SHORT (16_bit), которое устанавливает размер, в байтах, данных создания окна. Значение непосредственно сопровождается данными создания. Для получения дополнительной информации, см. следующий раздел Замечаний.
hInstance
Идентифицирует модуль, который владеет новым окном.
hMenu
Идентифицирует меню, которое используется созданным окном.
hwndParent
Идентифицирует родительское окно, если созданное окно - дочернее окно. Если окно является владельцем, этот элемент идентифицирует окно владельца. Если окно - не дочернее или не находящееся в собственности окно, этот элемент - ПУСТО (NULL).
cy
Устанавливает высоту нового окна, в пикселях.
cx
Устанавливает ширину нового окна, в пикселях.
y
Устанавливает y-координату верхнего левого угла нового окна. Если новое окно - дочернее окно, координаты - относительно родительского окна. Иначе, координаты - относительно экранного начала координат.
x
Устанавливает x-координату верхнего левого угла нового окна. Если новое окно - дочернее окно, координаты - относительно родительского окна. Иначе, координаты - относительно экранного начала координат. style
Определяет стиль для нового окна. lpszName
Указывает на строку с нулевым символом в конце, которая определяет имя нового окна.
lpszClass
Указывает на строку с нулевым символом в конце, которая определяет имя класса нового окна.
dwExStyle
Определяет расширенный стиль для нового окна.

Замечания
Windows NT: Ссылаясь на элемент lpCreateParams структуры CREATESTRUCT, поскольку указатель может быть не выровненный по границе ДВОЙНОГО СЛОВА (DWORD), прикладная программа должена обратиться к данным, использующим указатель, который был объявлен с ис-пользованием типа НЕВЫРОВНЕННЫЙ (UNALIGNED), как показано в следующем примере:

typedef struct tagMyData
{
. . .;			// Определите данные для создания окна здесь
} MYDATA;

typedef struct tagMyDlgData {
SHORT  cbExtra;
MYDATA  myData;
} MYDLGDATA, UNALIGNED *PMYDLGDATA;

PMYDLGDATA pMyDlgdata = (PMYDLGDATA) (((LPCREATESTRUCT) lParam)->lpcreateParams);

Смотри также
CreateWindow, CreateWindowEx

Размещение и совместимость CREATESTRUCT

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


1.27.2.4 Структура MDICREATESTRUCT

Структура MDICREATESTRUCT содержит информацию о классе, заголовке, владельце, расположении и размере дочернего окна многодокументной среды (MDI).

Синтаксис

typedef struct tagMDICREATESTRUCT
{
LPCTSTR szClass;
LPCTSTR szTitle;
HANDLE  hOwner;
int     x;
int     y;
int     cx;
int     cy;
DWORD   style;
LPARAM  lParam;
} MDICREATESTRUCT;

Элементы
szClass
Указывает на строку с нулевым символом в конце, которая устанавливает имя класса окна дочернего окна Многодокументального Интерфейса (MDI). Имя класса, должно быть зарегистрировано предыдущим обращением к функции RegisterClass.
szTitle
Указывает на строку с символом нуля в конце, которая представляет собой заголовок дочернего окна Многодокументального Интерфейса (MDI). Windows отображает заголовок в области заголовка дочернего окна.
hOwner
Идентифицирует экземпляр прикладной программы, создающей рабочее окно Многодокументального Интерфейса (MDI).
x
Устанавливает начальную горизонтальную позицию дочернего окна MDI, в координатах пользователя. Если этот элемент - CW_USEDEFAULT, дочернее окно MDI принимает заданную по умолчанию горизонтальную позицию.
y
Устанавливает начальную вертикальную позицию дочернего окна MDI, в координатах пользователя. Если этот элемент - CW_USEDEFAULT, дочернее окно MDI принимает заданную по умолчанию вертикальную позицию.
cx
Устанавливает начальную ширину, в единицах измерения устройства, дочернего окна MDI. Если этот элемент - CW_USEDEFAULT, дочернее окно MDI принимает заданную по умолчанию ширину.
cy
Устанавливает начальную высоту, в единицах измерения устройства, дочернего окна MDI. Если этот элемент - CW_USEDEFAULT, дочернее окно MDI принимает заданную по умолчанию высоту.
style
Определяет стиль дочернего окна Многодокументального Интерфейса (MDI). Если рабочее окно MDI было создано со стилем окна MDIS_ALLCHILDSTYLES, этот элемент может быть любой комбинацией стилей окна, перечисленных в описании функции CreateWindow. Иначе, этот элемент может быть одним или большим количеством следующих значений:

  • WS_MINIMIZE - Создает дочернее окно Многодокументального Интерфейса (MDI), которое первоначально свернуто.
  • WS_MAXIMIZE - Создает дочернее окно MDI, которое первоначально развернуто.
  • WS_HSCROLL - Создает дочернее окно MDI, которое имеет горизонтальную линейку прокрутки.
  • WS_VSCROLL - Создает дочернее окно MDI, которое имеет вертикальную линейку прокрутки .

lParam
Устанавливает определяемое программой 32-разрядное значение.
Замечания Когда дочернее окно многодокументного интерфейса (MDI) создано, Windows посылает окну сообщение WM_CREATE. Параметр lParam WM_CREATE содержит указатель на структуру CREATESTRUCT. Элемент этой структуры lpCreateParams содержит указатель на структуру MDICREATESTRUCT, переданную с сообщением WM_MDICREATE, которое создало дочернее окно многодокументного интерфейса (MDI).

Смотри также CLIENTCREATESTRUCT, CREATESTRUCT, WM_CREATE

Размещение и совместимость MDICREATESTRUCT

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


1.27.2.5 Структура MINMAXINFO

Структура MINMAXINFO содержит информацию о развернутом размере окна и устанавливаемых позициях ее минимального и максимального размера.

Синтаксис

typedef struct tagMINMAXINFO
{
POINT ptReserved;
POINT ptMaxSize;
POINT ptMaxPosition;
POINT ptMinTrackSize;
POINT ptMaxTrackSize;
} MINMAXINFO;

Элементы ptReserved
Зарезервировано, не используется.
ptMaxSize
Устанавливает развернутую ширину (point.x) и развернутую высоту (point.y) окна.
ptMaxPosition
Устанавливает позицию левой стороны развернутого окна (point.x) и позицию верхней части развернутого окна (point.y).
ptMinTrackSize
Определяет минимум устанавливаемой ширины (point.x) и минимум устанавливаемой высоты (point.y) окна.
ptMaxTrackSize
Определяет максимум устанавливаемой ширины (point.x) и максимум устанавливаемой высоты (point.y) окна.

Смотри также
POINT, WM_GETMINMAXINFO

Размещение и совместимость MINMAXINFO

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.2.6 Структура NCCALCSIZE_PARAMS

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

Синтаксис

typedef struct _NCCALCSIZE_PARAMS
{
RECT			 rgrc[3];
PWINDOWPOS	 	lppos;
}
NCCALCSIZE_PARAMS;

Элементы

rgrc
Устанавливает массив прямоугольников. Первый содержит новые координаты окна, которое было перемещено или изменено. Второй содержит координаты окна прежде, чем оно было перемещено или изменено. Третье содержит координаты рабочей области окна прежде, чем окно было перемещено или изменено. Если окно - дочернее окно, координаты - относительно рабочей области родительского окна. Если окно - окно верхнего уровня, координаты - относительно экранного начала координат.
lppos
Указывает на структуру WINDOWPOS, которая содержит размер и значения расположения, установленные в операции, которая передвигала или изменила размеры окна.

Смотри также
MoveWindow, RECT, SetWindowPos, WINDOWPOS, WM_NCCALCSIZE

Размещение и совместимость NCCALCSIZE_PARAMS

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.2.7 Структура STYLESTRUCT

Структура STYLESTRUCT содержит стили для окна.

Синтаксис

typedef struct tagSTYLESTRUCT
{
DWORD styleOld;
DWORD styleNew;
} STYLESTRUCT, * LPSTYLESTRUCT;

Элементы

style
Устанавливает массив стилей окна или флажков улучшенного стиля.

Смотри также
WM_STYLECHANGED, WM_STYLECHANGING

Размещение и совместимость STYLESTRUCT

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.2.8 Структура WINDOWPLACEMENT

Структура WINDOWPLACEMENT содержит информацию о размещении окна на экране.

Синтаксис

typedef struct _WINDOWPLACEMENT
{
UINT  length;
UINT  flags;
UINT  showCmd;
POINT ptMinPosition;
POINT ptMaxPosition;
RECT  rcNormalPosition;
} WINDOWPLACEMENT;

Элементы

length
Устанавливает длину структуры, в байтах. Перед вызовом функций GetWindowPlacement или SetWindowPlacement, установите этот элемент в sizeof (WINDOWPLACEMENT). GetWindowPlacement и SetWindowPlacement потерпят неудачу, если этот элемент не будет установлен правильно.
flags
Устанавливает флажки, которые управляют позицией свернутого окна и методом, которым окно восстанавливается. Этот элемент может иметь несколько из следующих значений:

  • WPF_RESTORETOMAXIMIZED - Определяет, что восстановленное окно будет развернуто, независимо от того, было ли оно развернуто прежде, чем оно было свернуто. Эта установка допустима только в следующий раз, когда окно восстанавливается. Она не изменяет заданное по умолчанию поведение восстановления. Этот флажок правилен только тогда, когда для элемента showCmd установлено значение SW_SHOWMINIMIZED.
  • WPF_SETMINPOSITION - Устанавливает, что координаты свернутого окна могут быть определены. Этот флажок должен быть установлен, если в элементе ptMinPosition установлены координаты.

showCmd
Определяет текущее состояние показа окна. Этот элемент может быть одним из следующих значений:

  • SW_HIDE - Скрывает окно и активизирует другое окно.
  • SW_MINIMIZE - Свертывает определяемое окно и активизирует окно верхнего уровня в списке системы.
  • SW_RESTORE - Активизирует и отображает на экране окно. Если окно свернуто или развернуто, Windows восстанавливает его в первоначальном размере и позиции (то же самое, что и SW_SHOWNORMAL).
  • SW_SHOW - Активизирует окно и отображает его на экране в его текущем размере и позиции.
  • SW_SHOWMAXIMIZED - Активизирует окно и отображает его на экране как развернутое окно.
  • SW_SHOWMINIMIZED - Активизирует окно и отображает его на экране как пиктограмму.
  • SW_SHOWMINNOACTIVE - Отображает окно как пиктограмму. Активное окно остается активным.
  • SW_SHOWNA - Отображает окно в его текущем состоянии. Активное окно остается активным.
  • SW_SHOWNOACTIVATE - Отображает окно в его самом современном размере и позиции. Активное окно остается активным.
  • SW_SHOWNORMAL - Активизирует и отображает окно. Если окно свернуто или развернуто, Windows восстанавливает его в первоначальном размере и позиции (то же самое, что и SW_RESTORE).

ptMinPosition
Устанавливает координаты левого верхнего угла окна, когда оно свернуто.
ptMaxPosition
Устанавливает координаты левого верхнего угла окна, когда оно развернуто.
rcNormalPosition
Устанавливает координаты окна, когда оно находится в восстановленной позиции.

Смотри также
ShowWindow, POINT, RECT

Размещение и совместимость WINDOWPLACEMENT

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.2.9 Структура WINDOWPOS

Структура WINDOWPOS содержит информацию о размерах и позиции окна.

Синтаксис

typedef struct _WINDOWPOS
{
HWND hwnd;
HWND hwndInsertAfter;
int  x;
int  y;
int  cx;
int  cy;
UINT flags;
} WINDOWPOS;

Элементы

hwnd
Идентифицирует окно.
hwndInsertAfter
Определяет позицию окна в Z-последовательности (позиция от начала к концу). Этот элемент может быть дескриптором окна, позади которого это окно помещено, или может быть одно из частных значений, перечисленных с функцией SetWindowPos.
x
Устанавливает позицию левого края окна.
y
Устанавливает позицию верхнего края окна.
cx
Устанавливает ширину окна, в пикселях.
cy
Устанавливает высоту окна, в пикселях.
flags
Устанавливает позицию окна. Этот элемент может быть одним из следующих значений:

  • SWP_DRAWFRAME - Выводит рамку (определенную в описании класса окна) вокруг окна.
  • SWP_FRAMECHANGED - Посылает окну сообщение WM_NCCALCSIZE, даже если размер окна не изменяется. Если этот флажок не установлен, WM_NCCALCSIZE посылается только тогда, когда размер окна изменяется.
  • SWP_HIDEWINDOW - Скрывает окно.
  • SWP_NOACTIVATE - Не активизирует окно. Если этот флажок не установлен, окно активизируется и перемещается в верхнюю часть или самой верхней или не самой верхней группы (в зависимости от установки параметра hWndInsertAfter).
  • SWP_NOCOPYBITS - Сбрасывает все содержание рабочей области. Если этот флажок не установлен, допустимое содержание рабочей области сохраняется и копируется обратно в рабочую область после того, как окно будет установлено по размеру или переустановлено (снова установлено).
  • SWP_NOMOVE - Сохраняет текущую позицию (игнорирует X и Y параметры).
  • SWP_NOOWNERZORDER - Не изменяет позицию окна владельца в Z-последовательности.
  • SWP_NOREDRAW - Не перерисовывает изменения. Если этот флажок установлен, перерисовки любого вида не происходит. Это применяется как к рабочей области, нерабочей области (включая область заголовка и полосы прокрутки), так и к любой части родительского окна, раскрытого в результате перемещения окна. Когда этот флажок установлен, прикладная программа должна явно либо аннулировать или перерисовывать любые части окна и родительского окна, которые надо перерисовать.
  • SWP_NOREPOSITION - То же самое, что и флажок SWP_NOOWNERZORDER.
  • SWP_NOSENDCHANGING - Предохраняет окно от приема сообщения WM_WINDOWPOSCHANGING.
  • SWP_NOSIZE - Сохраняет текущий размер (игнорирует cx и cy параметры).
  • SWP_NOZORDER - Сохраняет текущую Z-последовательность (игнорирует параметр hWndInsertAfter).
  • SWP_SHOWWINDOW - Отображает окно.

Смотри также
EndDeferWindowPos, SetWindowPos, WM_NCCALCSIZE

Размещение и совместимость WINDOWPOS

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3 Сообщения окна

Ниже перечисленные сообщения используются для создания и управления окнами.
WM_ACTIVATE
WM_ACTIVATEAPP
WM_CANCELMODE
WM_CHILDACTIVATE
WM_CLOSE
WM_COMPACTING
WM_COPYDATA
WM_CREATE
WM_DESTROY
WM_ENABLE
WM_ENTERSIZEMOVE
WM_EXITSIZEMOVE
WM_GETICON
WM_GETMINMAXINFO
WM_GETTEXT
WM_GETTEXTLENGTH
WM_INPUTLANGCHANGE
WM_INPUTLANGCHANGEREQUEST
WM_MOVE
WM_MOVING
WM_NCACTIVATE
WM_NCCALCSIZE
WM_NCCREATE
WM_NCDESTROY
WM_PARENTNOTIFY
WM_POWER
WM_QUERYDRAGICON
WM_QUERYOPEN
WM_QUIT
WM_SETICON
WM_SETTEXT
WM_SETTINGCHANGE
WM_SHOWWINDOW
WM_SIZE
WM_SIZING
WM_STYLECHANGED
WM_STYLECHANGING
WM_USERCHANGED
WM_WINDOWPOSCHANGED
WM_WINDOWPOSCHANGING
WM_WININICHANGE


1.27.3.1 Сообщение WM_ACTIVATE

Сообщение WM_ACTIVATE посылается, когда окно активизируется или деактивизируется. Это сообщение посылается сначала оконной процедуре деактивизируемого окна верхнего уровня; затем оно посылается оконной процедуре активизируемого окна верхнего уровня.

Синтаксис

WM_ACTIVATE
fActive = LOWORD(wParam);           	// флажок активизации
fMinimized = (BOOL) HIWORD(wParam); 	// флажок минимизации
hwndPrevious = (HWND) lParam;       	// дескриптор окна

Параметры

fActive
Значение младшего байта слова wParam. Устанавливает, активизируется ли окно или оно деактивизируется. Этот параметр может быть одним из следующих значений:

  • WA_ACTIVE - Активизировано некоторым методом другим, чем щелчок мыши (например, обращением к функции SetActiveWindow или использованием интерфейса клавиатуры для выбора окна).
  • WA_CLICKACTIVE - Активизировано щелчком мыши.
  • WA_INACTIVE - Деактивизировано.

fMinimized
Значение старшего байта слова wParam. Устанавливает свернутое состояние окна, активизируемого или деактивизируемого. Значение, отличающееся от нуля, указывает, что окно свернуто (минимизировано).
hwndPrevious
Значение lParam. Идентифицирует окно, активизируемое или деактивизируемое, в зависимости от значения параметра fActive. Если значение fActive - WA_INACTIVE, hwndPrevious - дескриптор активизируемого окна. Если значение fActive - WA_ACTIVE или WA_CLICKACTIVE, hwndPrevious - дескриптор деактивизируемого окна. Этот дескриптор может быть ПУСТО (NULL).
Возвращаемые значения
Если программа обработала это сообщение, она должна возвратить нуль.

Действие по умолчанию
Если окно активизируется и не свернуто (минимизировано), функция DefWindowProc устанавливает фокус клавиатуры в окно.

Замечания
Если окно активизировано щелчком мыши, оно также принимает сообщение WM_MOUSEACTIVATE.

Смотри также
DefWindowProc, SetActiveWindow, WM_MOUSEACTIVATE, WM_NCACTIVATE

Размещение и совместимость WM_ACTIVATE

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.2 Сообщение WM_ACTIVATEAPP

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

Синтаксис

WM_ACTIVATEAPP
fActive = (BOOL) wParam; 			// активизация флажка
dwThreadID = (DWORD) lParam: 		// идентификатор потока

Параметры

fActive
Значение wParam. Устанавливает, активизируется ли или деактивизируется окно. Этот параметр - ИСТИНА (TRUE), если окно активизируется; ЛОЖЬ(FALSE), если окно деактивизируется.

dwThreadID
Значение lParam. Определяет идентификатор потока. Если параметр fActive - ИСТИНА (TRUE), dwThreadID - идентификатор потока, который владеет деактивизируемым окном. Если fActive - ЛОЖЬ(FALSE), dwThreadID - идентификатор потока, который владеет активизируемым окном.

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

Смотри также
WM_ACTIVATE

Размещение и совместимость WM_ACTIVATEAPP

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.3 Сообщение WM_CANCELMODE

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

Синтаксис

WM_CANCELMODE

Параметры
У этого сообщения нет параметров.

Возвращаемые значения
Если приложение обрабатывает это сообщение, оно должно возвратить нуль.

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

Смотри также
DefWindowProc, ReleaseCapture

Размещение и совместимость WM_CANCELMODE

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.4 Сообщение WM_CHILDACTIVATE

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

Синтаксис

WM_CHILDACTIVATE

Параметры
У этого сообщения нет параметров.

Возвращаемые значения
Если приложение обрабатывает сообщение, оно должно возвратить ноль.

Смотри также
MoveWindow, SetWindowPos

Размещение и совместимость WM_CHILDACTIVATE

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.5 Сообщение WM_CLOSE

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

Синтаксис

WM_CLOSE

Параметры
У этого сообщения нет параметров.

Возвращаемые значения
Если приложение обрабатывает это сообщение, оно должно возвратить ноль.

Действие по умолчанию
Функция DefWindowProc обращается к функции DestroyWindow, чтобы уничтожить окно.

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

Смотри также
DefWindowProc, DestroyWindow

Размещение и совместимость WM_CLOSE

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.6 Сообщение WM_COMPACTING

Сообщение WM_COMPACTING посылается всем окнам верхнего уровня, когда Windows обнаруживает больше чем 12.5 процентов от системного времени в течение от 30 - до 60-секундного интервала, тратится на уплотнение памяти. Это указывает на то, что недостаточно системной памяти.

Синтаксис

WM_COMPACTING
wCompactRatio = wParam; // степень сжатия

Параметры

wCompactRatio
Значение wParam. Устанавливает коэффициент текущего времени центрального процессора (ЦП), потраченного Windows на уплотнение памяти, к текущему времени ЦП, потраченному Windows на выполнение других действий. Например, 0x8000 представляет 50 процентов от потраченного ПРОЦЕССОРНОГО ВРЕМЕНИ на уплотнение памяти.

Возвращаемые значения
Если приложение обрабатывает это сообщение, оно должно возвратить ноль.

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

Размещение и совместимость WM_COMPACTING

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.7 Сообщение WM_COPYDATA

Сообщение WM_COPYDATA передается тогда, когда одна программа пересылает данные в другую программу.

Синтаксис

WM_COPYDATA
wParam = (WPARAM) (HWND) hwnd;            		// дескриптор передающего окна
lParam = (LPARAM) (PCOPYDATASTRUCT) pcds; 		// указатель на структуру с данными

Параметры

hwnd
Идентифицирует окно, которое передает данные.
pcds
Указывает на структуру COPYDATASTRUCT, которая содержит данные для передачи.

Возвращаемые значения
Если принимающая программа обрабатывает это сообщение, она должна возвратить значение ИСТИНА (TRUE); в противном случае она должна возвратить - ЛОЖЬ (FALSE).

Замечания
Для передачи этого сообщения программа должна использовать функцию SendMessage, а не функцию PostMessage. Данные, предназначенные для передачи, не должны содержать указателей или других ссылок на объекты, не доступные для программы, принимающей эти данные.
До тех пор, пока это сообщение действует, вызванные данные не должны быть изменены другим по-током процесса пересылки. Принимающая программа должна принимать во внимание данные только для чтения. Параметр pcds правилен только в течение обработки сообщения. Принимающая программа не должна освобождать память, вызванную pcds. Если принимающая программа обратилась к данным после возврата значения функцией SendMessage, она должно копировать данные в локальный буфер.

Смотри также
PostMessage, SendMessage, COPYDATASTRUCT

Размещение и совместимость WM_COPYDATA

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.8 Сообщение WM_CREATE

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

Синтаксис

WM_CREATE
lpcs = (LPCREATESTRUCT) lParam; // структура с данными создания

Параметры

lParam
Значение lParam. Указывает на структуру CREATESTRUCT, которая содержит информацию относительно создаваемого окна. Члены CREATESTRUCT идентичны параметрам функции CreateWindowEx.

Возвращаемые значения
Если приложение обрабатывает это сообщение, оно возвращает 0, чтобы продолжить создание окна. Если прикладная программа возвращает -1, то окно разрушается, и функция CreateWindowEx или CreateWindow возвращает значение дескриптора ПУСТО (NULL).

Смотри также
CreateWindow, CreateWindowEx, CREATESTRUCT, WM_NCCREATE

Размещение и совместимость WM_CREATE

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.9 Сообщение WM_DESTROY

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

Синтаксис

WM_DESTROY

Параметры
У этого сообщения нет параметров.

Возвращаемые значения
Если программа обрабатывает это сообщение, оно должно возвратить ноль.

Замечания
Если разрушаемое окно - часть цепочки окон просмотра буфера обмена (установленное, вызовом функции SetClipboardViewer), окно должно удаляться из цепочки путем обработки функции ChangeClipboardChain перед возвратом из сообщения WM_DESTROY.

Смотри также
ChangeClipboardChain, DestroyWindow, PostQuitMessage, SetClipboardViewer, WM_CLOSE

Размещение и совместимость WM_DESTROY

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.10 Сообщение WM_ENABLE

Сообщение WM_ENABLE посылается тогда, когда прикладная программа изменяет включенное состояние окна. Оно посылается окну, чьё включенное состояние изменяется. Это сообщение посылается перед возвращением значения функцией EnableWindow , но только после того, как изменилось включенное состояние (бит стиля WS_DISABLED) окна.

Синтаксис

WM_ENABLE
fEnabled = (BOOL) wParam;   // флажок включить/заблокировать

Параметры
fEnabled
Значение wParam. Устанавливает, было ли окно включено или заблокировано. Этот параметр был бы ИСТИНА (TRUE), если бы окно было включено или ЛОЖЬ(FALSE), если бы окно было заблокировано.

Возвращаемые значения
Если программа обрабатывает это сообщение, она должна возвратить ноль.

Смотри также
EnableWindow

Размещение и совместимость WM_ENABLE

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.11 Сообщение WM_ENTERSIZEMOVE

Сообщение WM_ENTERSIZEMOVE посылается только один раз окну, когда оно вводит режим установки размеров или перемещения. Окно вводит режим перемещения или установки размеров, когда пользователь щелкает мышью по области заголовка окна или устанавливает размеры рамки окна, или когда окно передает сообщение WM_SYSCOMMAND в функцию DefWindowProc, а параметр wParam сообщения устанавливает значение SC_MOVE или SC_SIZE. Windows посылает сообщение WM_ENTERSIZEMOVE независимо от того, включено ли перемещение полных окон.

Синтаксис

WM_ENTERSIZEMOVE
wParam = 0;  // не используется, должен быть ноль
lParam = 0;  // не используется, должен быть ноль

Параметры
Это сообщение не имеет параметров.

Возвращаемые значения
Программа должна возвратить ноль, если она обрабатывает это приложение.

Смотри также
DefWindowProc, WM_EXITSIZEMOVE, WM_SYSCOMMAND

Размещение и совместимость WM_ENTERSIZEMOVE

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.12 Сообщение WM_EXITSIZEMOVE

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

Синтаксис

WM_EXITSIZEMOVE
wParam = 0;  // не используется должен быть ноль
lParam = 0;  // не используется, должен быть ноль

Параметры
У этого сообщения нет параметров.

Возвращаемые значения
Программа должна возвратить ноль, если она обрабатывает это сообщение.

Смотри также
WM_ENTERSIZEMOVE

Размещение и совместимость WM_EXITSIZEMOVE

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.13 Сообщение WM_GETICON

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

Синтаксис

WM_GETICON
fType = wParam;  // тип пиктограммы

Параметры

fType
Значение wParam. Устанавливает тип возвращаемой обратно пиктограммы. Этот параметр может быть одним из следующих значений:

  • ICON_BIG - Возвратите обратно большую пиктограмму для окна.
  • ICON_SMALL - Возвратите обратно маленькую пиктограмму для окна.

Возвращаемые значения
Возвращаемое значение - дескриптор большой или маленькой пиктограммы, в зависимости от значения fType. Когда прикладная программа принимает это сообщение, она может возвратить дескриптор большой или маленькой пиктограммы, или передать сообщение в DefWindowProc.

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

Примечания
Когда прикладная программа принимает это сообщение, она может возвратить дескриптор большой или маленькой пиктограммы, или передать сообщение в DefWindowProc.

Смотри также
DefWindowProc, WM_SETICON

Размещение и совместимость WM_GETICON

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.14 Сообщение WM_GETMINMAXINFO

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

Синтаксис

WM_GETMINMAXINFO
lpmmi = (LPMINMAXINFO) lParam; // адрес структуры

Параметры

lpmmi
Значение lParam. Указывает на структуру MINMAXINFO, которая содержит значения позиции и габариты разворачивания по умолчанию и устанавливаемые по умолчанию минимальные и максимальные размеры. Прикладная программа может отменить значения параметров по умолчанию элементовов этой структуры.

Возвращаемые значения
Если приложение обрабатывает это сообщение, оно должно возвратить ноль.

Замечания
Установка максимального размера - самый большой размер окна, который может быть произведен, используя рамки, чтобы установить величину окна. Установка минимального размер - самый маленький размер окна, который может быть произведен, используя рамки, чтобы установить величину окна.

Смотри также
MoveWindow, SetWindowPos, MINMAXINFO

Размещение и совместимость WM_GETMINMAXINFO

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.15 Сообщение WM_GETTEXT

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

Синтаксис

WM_GETTEXT
wParam = (WPARAM) cchTextMax;   	// число копируемых символов
lParam = (LPARAM) lpszText;         // адрес буфера для текста

Параметры

cchTextMax
Значение wParam. Устанавливает максимальное число символов, которое будет скопировано, включая символ завершения ноль-терминатор.
lpszText
Значение lParam. Указывает на буфер, который должен принять текст.

Возвращаемые значения
Возвращаемое значение - скопированное число символов.

Действие по умолчанию
Функция DefWindowProc копирует текст, связанный с окном в заданный буфер и возвращает скопированное число символов.

Замечания
Для элемента редактирования, текст, который будет скопирован - содержит элементы редактирования. Для комбинированного поля, текст - содержание элементов редактирования (или статический текст) часть комбинированного поля. Для кнопки, текст - имя кнопки. Для других окон, текст - заголовок окна. Чтобы копировать текст элемента в окне списка, прикладная программа может использовать сообщение LB_GETTEXT.
Когда сообщение WM_GETTEXT посылается статическому элементу управления со стилем SS_ICON, дескриптор пиктограммы будет возвращен в первых четырех байтах буфера указателя lpszText. Это истинно только тогда, если сообщение WM_SETTEXT использовалось, чтобы установить пиктограмму.

В мощных средствах редактирования, если текст, который будет скопирован, превышает 64КБ, используется сообщение или EM_STREAMOUT или EM_GETSELTEXT.

Смотри также
DefWindowProc, EM_GETSELTEXT, EM_STREAMOUT, GetWindowText, GetWindowTextLength, LB_GETTEXT, WM_GETTEXTLENGTH, WM_SETTEXT

Размещение и совместимость WM_GETTEXT

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.16 Сообщение WM_GETTEXTLENGTH

Прикладная программа посылает сообщение WM_GETTEXTLENGTH, чтобы определить длину текста, в символах, связанного с окном. Длина не включает символа завершения строки (ноль-терминатора).

Синтаксис

WM_GETTEXTLENGTH
wParam = 0; // не используется, должен быть ноль
lParam = 0; // не используется, должен быть ноль

Параметры
У этого сообщения нет параметров.

Возвращаемое значение
Возвращаемое значение - длина текста, в символах.

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

Замечания
Для элементов редактирования, текст, который будет скопирован - содержание элементов редактирования. Для комбинированного блока, текст - содержание элементов редактирования (или статический текст) часть комбинированного блока. Для кнопки, текст - имя кнопки. Для других окон, текст - заголовок окна. Чтобы определять длину элемента в окне списка, прикладная программа может использовать сообщение LB_GETTEXTLEN.
При известных условиях, функция DefWindowProc возвращает значение, которое является большим, чем фактическая длина текста. Это происходит с некоторыми смесями ANSI и Уникода, и из-за операционной системы, которая учитывает возможное существование символов DBCS внутри текста. Возвращаемое значение, однако, будет всегда, по крайней мере, такого размера, как факти-ческая длина текста; Вы можете, таким образом, всегда использовать его, чтобы определить распре-деление в буфере. Это поведение может случаться тогда, когда прикладная программа использует и функции ANSI и общие диалоги, которые используют Уникод. LB_GETTEXT, или CB_GETLBTEXT, или функцию GetWindowText.

Смотри также
CB_GETLBTEXT, DefWindowProc, GetWindowText, GetWindowTextLength, LB_GETTEXT, LB_GETTEXTLEN, WM_GETTEXT.

Размещение и совместимость WM_GETTEXTLENGTH

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.17 Сообщение WM_INPUTLANGCHANGE

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

Синтаксис

WM_INPUTLANGCHANGE
charset = wParam;
hkl = (HKL) lParam;

Параметры
charset
Значение wParam. Определяет набор символов нового расположения символов на клавиатуре.
hkl
Значение lParam. Идентифицирует новое расположение символов на клавиатуре.

Возвращаемые значения
Приложение должно возвратить не нулевое значение, если обрабатывает это сообщение.

Смотри также
DefWindowProc, WM_INPUTLANGCHANGEREQUEST

Размещение и совместимость WM_INPUTLANGCHANGE

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.18 Сообщение WM_INPUTLANGCHANGEREQUEST

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

Синтаксис

WM_INPUTLANGCHANGEREQUEST
fSysCharSet = (BOOL) wParam
hkl = (HKL) lParam;

Параметры wParam
Самый младший бит этого параметра установлен, если дескриптор расположения символов на клавиатуре может использоваться с набором символов системы. Другие биты зарезервированы. Например, в Русскоязычной версии Windows 95, этот параметр устанавливает младший бит для дескрипторов расположения символов на клавиатуре для Английского (США) и Русского языка, но сбрасывает для других дескрипторов.
hkl
Значение lParam. Идентифицирует расположение символов на клавиатуре, чтобы переключать их.

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

Смотри также
DefWindowProc, WM_INPUTLANGCHANGE

Размещение и совместимость WM_INPUTLANGCHANGEREQUEST

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.19 Сообщение WM_MOVE

Сообщение WM_MOVE передается после того, когда окно будет перемещено. Снтаксис

WM_MOVE
xPos = (int) LOWORD(lParam);    // позиция по горизонтали
yPos = (int) HIWORD(lParam);    // позиция по вертикали

Параметры
xPos
Значение младшего байта слова lParam. Устанавливает x-координату левого верхнего угла рабочей области окна.
yPos
Значение старшего слова lParam. Устанавливает y-координату левого верхнего угла рабочей области окна.

Возвращаемые значения
Если программа обрабатывает это сообщение, она должна возвратить ноль.

Замечания
xPos и yPos параметры даны в экранных координатах для перекрывающих и выскакивающих окон и в координатах пользователя - родителя для дочерних окон. Прикладная программа может использовать макрокоманду MAKEPOINTS, чтобы преобразовать параметр lParam для структуры POINTS.

Смотри также
MAKEPOINTS, POINTS

Размещение и совместимость WM_MOVE

Windows NT		Да
Win95			Да
Win32s			Да
Импортируемая библиотека	-
Заголовочный файл		winuser.h
Unicode			Нет
Замечания по платформе	Не имеется


1.27.3.20 Сообщение WM_MOVING

Сообщение WM_MOVING посылается окну, которое пользователь перемещает. Обрабатывая это сообщение, прикладная программа может контролировать размер и позицию перетаскиваемого прямоугольника и, если необходимо, изменять его размер или позицию.

Синтаксис

fwSide = wParam;		// Край окна, которое будет перемещено
lprc = (LPRECT) lParam; 	// Экранные координаты перетаскиваемого прямоугольника

Параметры

fwSide
Значение wParam. Указывает, который край окна передвигается. Этот параметр может быть комбинацией следующих значений:

  • WMSZ_BOTTOM - Нижний край
  • WMSZ_BOTTOMLEFT - Левый нижний угол
  • WMSZ_BOTTOMRIGHT - Правый нижний угол
  • WMSZ_LEFT - Левый край
  • WMSZ_RIGHT - Правый край
  • WMSZ_TOP - Верхний край
  • WMSZ_TOPLEFT - Верхний левый угол
  • WMSZ_TOPRIGHT - Левый правый угол

lprc
Значение lParam. Адрес структуры RECT с экранными координатами перетаскиваемого прямоугольника. Чтобы изменять размер или позицию перетаскиваемого прямоугольника, прикладная программа должна изменять члены этой структуры.

Возвращаемое значение
Программа должна возвратить ИСТИНУ (TRUE), если она обрабатывает это сообщение.

Смотри также
RECT, WM_MOVE, WM_SIZING

Размещение и совместимость WM_MOVING

Windows NT		Да
Win95			Да
Win32s			Нет
Импортируемая библиотека	-
Заголовочный файл		winuser.h
Unicode			Нет
Замечания по платформе	Не имеется


1.27.3.21 Сообщение WM_NCACTIVATE

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

Синтаксис

WM_NCACTIVATE
fActive = (BOOL) wParam;	// новое состояние поля заголовка или пиктограммы

Параметры
fActive
Значение wParam. Устанавливает , когда область заголовка или пиктограмма должны быть изменены, чтобы указать активное или неактивное их состояние. Если активная область заголовка или пиктограмма должны быть выведены на экране, параметр fActive - ИСТИНА (TRUE). Он - ЛОЖЬ(FALSE) для неактивной области заголовка или пиктограммы.

Возвращаемые значения
Когда параметр fActive - ЛОЖЬ(FALSE), прикладная программа должна возвратить ИСТИНА (TRUE), чтобы указать, что Windows должен продолжить обработку значения по умолчанию, или она должно возвратить ЛОЖЬ(FALSE), чтобы предохранить область заголовка или пиктограмму от деактивизации. Когда fActive - ИСТИНА (TRUE), возвращаемое значение игнорируется.

Действие по умолчанию
Функция DefWindowProc выводит область заголовка или заголовок пиктограммы в его активных цветах, когда параметр fActive - ИСТИНА (TRUE) и в его неактивных цветах, когда fActive - ЛОЖЬ(FALSE).

Смотри также
DefWindowProc

Размещение и совместимость WM_NCACTIVATE

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.22 Сообщение WM_NCCALCSIZE

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

Синтаксис

WM_NCCALCSIZE
fCalcValidRects = (BOOL) wParam;		// флажок действующей области
lpncsp = (LPNCCALCSIZE_PARAMS) lParam;  	// указатель на размер
                             // вычисляемых данных или
lpncsp = (LPRECT) lParam;			// указатель на новые координаты окна

Параметры
fCalcValidRects
Значение wParam. Это Булево значение, если ИСТИНА (TRUE), то определяется, что прикладная программа должна указать, какая часть рабочей области содержит допустимую информацию. Операционная система копирует правильную информацию в указанный район внутри новой рабочей области. Также, если этот параметр - ИСТИНА (TRUE), lParam указывает на структуру NCCALCSIZE_PARAMS.Если этот параметр - ЛОЖЬ(FALSE), прикладная программа не должна указывать допустимую часть рабочей области. Также, если этот параметр - ЛОЖЬ(FALSE), lParam указывает на структуру RECT.
lpncsp
Значение lParam. Если wParam - ИСТИНА (TRUE), lParam указывает на структуру NCCALCSIZE_PARAMS, которая содержит информацию, которую прикладная программа может использовать, чтобы вычислить новый размер и позицию прямоугольника пользователя. Если wParam - ЛОЖЬ(FALSE), lParam указывает на структуру RECT, которая содержит новые координаты окна, которое было перемещено или изменено. Этот параметр эквивалентен rgrc [0] из структуры NCCALCSIZE_PARAMS.

Возвращаемые значения
Если параметр fCalcValidRects - ЛОЖЬ(FALSE), прикладная программа должна возвратить нуль. Если fCalcValidRects - ИСТИНА (TRUE), прикладная программа может возвратить нуль или допустимую комбинацию следующих значений:

  • WVR_ALIGNTOP, WVR_ALIGNLEFT, WVR_ALIGNBOTTOM, WVR_ALIGNRIGHT - Эти значения, используемые в комбинаци-ях, определяют, что рабочая область окна должна сохраниться и выравниваться соот-ветственно относительно новой позиции окна. Например, чтобы выровнять рабочую область по левому нижнему углу, возвратите значения WVR_ALIGNLEFT и WVR_ALIGNTOP.
  • WVR_HREDRAW, WVR_VREDRAW - Эти значения, используемые в комбинации с любыми другими значениями, заставляют окно быть полностью повторно выведенным, если прямоугольник пользователя изменяет размер горизонтально или вертикально. Эти значения подобны стилям класса CS_HREDRAW и CS_VREDRAW.
  • WVR_REDRAW - Это значение вынуждает повторно вывести все окно. Это - комбинация значений WVR_HREDRAW и WVR_VREDRAW.
  • WVR_VALIDRECTS - Это значение указывает, что, при возврате из WM_NCCALCSIZE, прямоугольники, заданные элементами rgrc [1] и rgrc [2] структуры NCCALCSIZE_PARAMS содержат правильный источник и области адресования прямоугольников, соответственно. Windows объединяет эти прямоугольники, чтобы вычислить область окна, которую нужно сохранить. Windows копирует любую часть изображения окна, которое является внутри исходного прямоугольника и прикрепляет изображение к прямоугольнику назначения. Оба прямоугольника находятся в окне - относительно родительских или экранных координат. Это возвращаемое значение позволяет прикладной программе выполнять более сложные приемы охраны рабочей области, типа центрирования или сохранения подмножества рабочей области.

Если fCalcValidRects - ИСТИНА (TRUE), а программа возвращает нуль, старая рабочая область сохраняется и выравнивается по левому верхним углом новой рабочей области.

Действия по умолчанию
Окно может быть повторно выведено, в зависимости от того, установлен ли стиль класса CS_HREDRAW или CS_VREDRAW. Это - по умолчанию, совместимая в обратном направлении обработка этого сообщения функцией DefWindowProc (в дополнение к обычному вычислению прямоугольника пользователя, описанному в предшествующей таблице).

Смотри также
DefWindowProc, MoveWindow, SetWindowPos, NCCALCSIZE_PARAMS, RECT

Размещение и совместимость WM_NCCALCSIZE

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.23 Сообщение WM_NCCREATE

Сообщение WM_NCCREATE посылается до сообщения WM_CREATE, когда происходит начало создания окна.

Синтаксис

WM_NCCREATE
lpcs = (LPCREATESTRUCT) lParam; // данные инициализации

Параметры

lpcs
Значение wParam. Указывает на структуру CREATESTRUCT для окна.

Возвращаемые значения
Если приложение обрабатывает это сообщение, оно возвращает значение ИСТИНА (TRUE), чтобы продолжить создание окна. Если программа возвращает значение ЛОЖЬ(FALSE), функция CreateWindow или CreateWindowEx возвратит дескриптор ПУСТО (NULL).

Действия по умолчанию
Функция DefWindowProc возвращает значение ИСТИНА (TRUE).

Смотри также
CreateWindow, CreateWindowEx, DefWindowProc, CREATESTRUCT, WM_CREATE

Размещение и совместимость WM_NCCREATE

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.24 Сообщение WM_NCDESTROY

Сообщение WM_NCDESTROY информирует окно, что его нерабочая область разрушается. Функция DestroyWindow посылает окну сообщение WM_NCDESTROY после сообщения WM_DESTROY. WM_DESTROY используется, чтобы освободить память, в которой помещен объект, связанный с окном.

Синтаксис

WM_NCDESTROY

Параметры
У этого сообщения нет параметров

Возвращаемые значения
Если приложение обрабатывает это сообщение, оно должно возвратить ноль.

Замечания
Это сообщение освобождает любую память, внутренне распределенную для окна.

Смотри также
DestroyWindow,WM_DESTROY, WM_NCCREATE

Размещение и совместимость WM_NCDESTROY

Windows NT		Да
Win95			Да
Win32s			Да
Импортируемая библиотека	-
Заголовочный файл		winuser.h
Unicode			Нет
Замечания по платформе	Не имеется


1.27.3.25 Сообщение WM_PARENTNOTIFY

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

Синтаксис

WM_PARENTNOTIFY
fwEvent = LOWORD(wParam);  // флажки события
idChild = HIWORD(wParam);  // идентификатор дочернего окна
lValue = lParam;           // дочерний дескриптор или координаты курсора

Параметры
fwEvent
Значение младшего байта слова wParam. Определяет событие, о котором сообщают родителю. Этот параметр может быть одним из следующих значений:

  • WM_CREATE - Создается дочернее окно.
  • WM_DESTROY - Дочернее окно разрушается.
  • WM_LBUTTONDOWN - Пользователь поместил курсор над дочерним окном и щелкнул левой кнопкой мыши.
  • WM_MBUTTONDOWN - Пользователь поместил курсор над дочерним окном и щелкнул средней кнопкой мыши.
  • WM_RBUTTONDOWN - Пользователь поместил курсор над дочерним окном и щелкнул правой кнопкой мыши.

idChild
Значение старшего слова wParam. Если параметр fwEvent имеет значение WM_CREATE ИЛИ WM_DESTROY, idChild устанавливает идентификатор дочернего окна. Иначе, idChild не определен.
lValue
Содержит дескриптор дочернего окна, если параметр fwEvent имеет значение WM_CREATE или WM_DESTROY; иначе, lValue содержит x- и y-координаты курсора. x-координата в младшем слове, а y-координата находится в старшем слове.

Возвращаемые значения
Если программа обрабатывает это сообщение, она должна возвратить ноль.

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

Смотри также
CreateWindow, CreateWindowEx, WM_CREATE, WM_DESTROY, WM_LBUTTONDOWN, WM_MBUTTONDOWN, WM_RBUTTONDOWN

Размещение и совместимость WM_PARENTNOTIFY

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.26 Сообщение WM_POWER

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

Синтаксис

WM_POWER
fwPowerEvt = wParam;    // уведомительное сообщение о понижении питания

Параметры
fwPowerEvt
Значение wParam. Определяет уведомительное сообщение о понижении питания. Этот параметр может быть одно из следующих значений:

  • PWR_CRITICALRESUME - Указывает на то, что система возобновляет действие по-сле ввода режима приостановки работы без первоначальной посылки уведомительного сообщения PWR_SUSPENDREQUEST прикладной программе. Прикладная программа должна выполнить любые необходимые действия восстановления.
  • PWR_SUSPENDREQUEST - Указывает, что система собирается ввести режим приостановки работы.
  • PWR_SUSPENDRESUME - Указывает, что система возобновляет работу, после введения режима приостановки работы нормально, то есть система послала уведомительное сообщение PWR_SUSPENDREQUEST прикладной программе прежде, чем работа системы была приостановлена. Прикладная программа должна выполнить любые необходимые действия восстановления.

Возвращаемые значения
Значение, возвращаемое прикладной программой зависит от значения параметра wParam. Если wParam - PWR_SUSPENDREQUEST, возвращаемое значение - PWR_FAIL, чтобы предохранить систему от ввода состояния приостановки работы; иначе, это - PWR_OK. Если wParam - PWR_SUSPENDRESUME или PWR_CRITICALRESUME, возвращаемое значение нулевое.

Замечания
Это сообщение посылается только прикладной программе, которая исполняется системой и соответствует техническим требованиям Улучшенной системы питания (APM) базисная системы ввода -вывода (BIOS). Сообщение посылается драйвером управления питанием каждому окну, возвращен-ному функцией EnumWindows. Режим приостановки работы - состояние, в котором происходит самая большая эффективность сбережения мощности, но все действующие данные и параметры сохраняются. Память с произвольной выборкой (RAM) сохраняет свое содержание, но многие устройства, вероятно, будут выключены.

Смотри также EnumWindows, WM_POWERBROADCAST

Размещение и совместимость WM_POWER

Windows NT		Да
Win95			Да
Win32s			Да
Импортируемая библиотека	-
Заголовочный файл		winuser.h
Unicode			Нет
Замечания по платформе	Не имеется


1.27.3.27 Сообщение WM_QUERYDRAGICON

Сообщение WM_QUERYDRAGICON посылается свернутому (иконизированному) окну. Окно собирается сделать перемещение при помощи пользователя, но не определяет пиктограмму для своего класса. Прикладная программа может возвратить значение дескриптора пиктограммы или курсора. Система отображает этот курсор или пиктограмму, в то время как пользователь перетаскивает пиктограмму.

Синтаксис

WM_QUERYDRAGICON

Параметры
У этого сообщения нет параметров.

Возвращаемые значения
Прикладная программа должна возвратить дескриптор курсора или пиктограммы, которую Windows должен показывать, в то время, когда пользователь перетаскивает пиктограмму. Курсор или пиктограмма должны быть совместимы с разрешающей способностью дисплейного устройства. Если прикладная программа возвращает ПУСТО (NULL), система отображает заданный по умолчанию курсор.

Действия по умолчанию
Функция DefWindowProc возвращает значение дескриптора заданного по умолчанию курсора.

Замечания
Когда пользователь перетаскивает пиктограмму окна без определения класса пиктограммы, Windows меняет пиктограмму на, заданный по умолчанию, курсор. Если прикладная программа требует, чтобы в ходе перемещения отображался отличающийся от системного курсор, она должна возвратить дескриптор курсора или пиктограммы, которые совместимы по разрешающей способности с дисплейным устройством. Если прикладная программа возвращает дескриптор цветного курсора или пиктограммы, система преобразует курсор или пиктограмму в чернобелую. Прикладная программа может вызывать функцию LoadCursor или LoadIcon, чтобы загрузить курсор или пиктограмму из ресурсов своего исполняемого (.EXE) файла и возвратить обратно этот дескриптор.

Смотри также
DefWindowProc, LoadCursor, LoadIcon

Размещение и совместимость WM_QUERYDRAGICON

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.28 Сообщение WM_QUERYOPEN

Сообщение WM_QUERYOPEN посылается пиктограмме тогда, когда пользователь запрашивает, чтобы окно было восстановлено в его предыдущем размере и позиции.

Синтаксис

WM_QUERYOPEN

Параметры
У этого сообщения нет параметров.

Возвращаемые значения
Если пиктограмма может быть открыта, прикладная программа, которая обрабатывает это сообщение, должен возвратить значение ИСТИНА (TRUE); иначе, она должна возвратить значение ЛОЖЬ (FALSE), чтобы предотвратить открытие пиктограммы.

Действия по умолчанию
Функция DefWindowProc возвращает значение ИСТИНА (TRUE).

Замечания
При обработке этого сообщения, прикладная программа не должна выполнять какое-либо действие, которое вынуждает стать активным или изменить фокус (например, создавать диалоговое окно).

Смотри также
DefWindowProc, LoadCursor, LoadIcon

Размещение и совместимость WM_QUERYOPEN

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


2.27.3.29 Сообщение WM_QUIT

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

Синтаксис

WM_QUIT
nExitCode = (int) wParam;   // код завершения

Параметры nExitCode
Значение wParam. Определяет код завершения, данный в функции PostQuitMessage.

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

Смотри также
GetMessage, PostQuitMessage

Размещение и совместимость WM_QUIT

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.30 Сообщение WM_SETICON

Прикладная программа посылает сообщение WM_SETICON, чтобы сопоставить новую большую или маленькую пиктограмму с окном. Windows выводит большую пиктограмму, когда окно свер-нуто (минимизировано) и маленькую пиктограмму в области заголовка окна.

Синтаксис

WM_SETICON
wParam = (WPARAM) fType;          // тип пиктограммы
lParam = (LPARAM) (HICON) hicon;  // дескриптор пиктограммы

Параметры fType
Значение wParam. Определяет устанавливаемый тип пиктограммы. Этот параметр может быть одним из следующих значений:

Значение		Что оно означает
ICON_BIG		Установку большой пиктограммы для окна.
ICON_SMALL	Установку маленькой пиктограммы для окна.

hicon
Значение lParam. Идентифицирует новую большую или маленькую пиктограмму. Если этот параметр - ПУСТО (NULL), пиктограмма, обозначенная в параметре fType, удаляется.

Возвращаемые значения
Возвращаемое значение - дескриптор предыдущей большой или маленькой пиктограммы, в зависимости от значения fType. Оно - ПУСТО (NULL), если окно предварительно не имело никакой пиктограммы типа, обозначенного fType.

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

Смотри также
DefWindowProc, WM_GETICON

Размещение и совместимость WM_SETICON

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.31 Сообщение WM_SETTEXT

Прикладная программа посылает сообщение WM_SETTEXT, чтобы установить текст окна.

Синтаксис

WM_SETTEXT
wParam = 0;                     // не используется, должен быть ноль
lParam = (LPARAM)(LPCTSTR)lpsz; // адрес строки оконного текста

Параметры

lpsz Значение lParam. Указывает на строку с символом нуля в конце, которая является текстом окна.

Возвращаемые значения
Возвращаемое значение - ИСТИНА (TRUE), если текст установлен. Оно - ЛОЖЬ (FALSE) (для средств редактирования), LB_ERRSPACE (для окна списка), или CB_ERRSPACE (для комбинированного блока), если недостаточно доступного пространства, чтобы установить текст в полях редак-тирования. Оно - CB_ERR, если это сообщение послано комбинированному блоку без средств редактирования.

Действия по умолчанию
Функция DefWindowProc устанавливает и отображает текст окна.

Замечания
Для средств редактирования, текст - содержание средств редактирования. Для комбинированного блока, текст - содержание части средств редактирования комбинированного блока. Для кнопки, текст - имя кнопки. Для других окон, текст - заголовок окна. Это сообщение не изменяет текущий выбор в окне списка комбинированного блока. Прикладная программа должна использовать сообщение CB_SELECTSTRING, чтобы выбрать элемент в окне списка, которое соответствует тексту в средствах редактирования.

Смотри также
DefWindowProc, CB_SELECTSTRING, WM_GETTEXT

Размещение и совместимость WM_SETTEXT

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.32 Сообщение WM_SETTINGCHANGE

Система посылает сообщение WM_SETTINGCHANGE всем окнам верхнего уровня, когда функция SystemParametersInfo изменяет установки на системном уровне. Система посылает это сообщение только тогда, если вызывающая функция SystemParametersInfo устанавливает флажок SPIF_SENDCHANGE. Прикладная программа может посылать WM_SETTINGCHANGE всем окнам верхнего уровня, когда она делает изменения для параметров системы. Например, Вы можете посылать это сообщение после обращения к функциям WriteProfileString, WriteProfileSection или SetLocaleInfo, или после создания изменений для параметров системы в системном реестре.Сообщение WM_SETTINGCHANGE - то же самое, что и старое сообщение WM_WININICHANGE.

Синтаксис

WM_SETTINGCHANGE
wParam = wFlag;                         // флажок параметров на системном уровне
lParam = (LPARAM) (LPCTSTR) pszSection; // наименование раздела или реестра

Параметры

wFlag
Значение wParam. Когда система посылает сообщению в результате обращения к System-ParametersInfo, этот параметр - флажок, который указывает параметр системы, который был изменен. О списке значений, см. функцию SystemParametersInfo. Когда прикладная программа посылает со-общение, этот параметр должен быть ПУСТО (NULL).
pszMetrics
Значение lParam. Указатель на строку, которая указывает область, содержащую параметр системы который был изменен. Например, эта строка может быть имя ключа реестра или имя раздела в файле WIN.INI. Этот параметр не особенно полезен в определении, какой изменился параметр системы. Например, когда строка - имя системного реестра, она обычно указывает только вершину в системном реестре, а не весь путь. Кроме того, некоторые прикладные программы посылают это сообщение с установкой параметра lParam в ПУСТО (NULL). Вообще, когда Вы принимаете это сообщение, Вы должны проверять и перезагружать любые настройки параметров системы, которые используются вашей прикладной программой.

Возвращаемые значения
Если вы обрабатываете это сообщение, возвращаемое значение - ноль.

Замечания
Чтобы послать сообщение WM_SETTINGCHANGE всем окнам верхнего уровня, используйте функцию SendMessage с параметром hwnd установленным в HWND_BROADCAST. Вызовите функции, которые изменяют файл WIN.INI, который может быть отображен взамен системного реестра. Это отображение происходит тогда, когда файл WIN.INI и изменяемый раздел установлены в системном реестре под следующими ключами:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\IniFileMapping

Изменение в ячейке памяти не имеет никакого влияния на поведении этого сообщения.

Смотри также
SendMessage, SetLocaleInfo, SystemParametersInfo, WM_WININICHANGE, WriteProfileSection, WriteProfileString

Размещение и совместимость WM_SETTINGCHANGE

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


1.27.3.33 Сообщение WM_SHOWWINDOW

Сообщение WM_SHOWWINDOW посылается окну тогда, когда окно собирается быть скрытым или видимым.

Синтаксис

WM_SHOWWINDOW
fShow = (BOOL) wParam;      // флажок показать/скрыть
fnStatus = (int) lParam;    // флажок состояния

Параметры

fShow
Значение wParam. Определяет, показывается ли окно. ИСТИНА (TRUE), если окно показывается или ЛОЖЬ(FALSE), если окно скрывается.
fnStatus
Значение lParam. Определяет состояние показываемого окна. Параметр fnStatus нулевой, если сообщение послано из-за обращения к функции ShowWindow; иначе, fnStatus - одно из следующих значений:

  • SW_OTHERUNZOOM - Окно раскрывается, потому что развернутое окно было восстановлено или свернуто(минимизировано).
  • SW_OTHERZOOM - Окно покрывается другим окном, которое было развернуто.
  • SW_PARENTCLOSING - Окно владельца окна свертывается.
  • SW_PARENTOPENING - Окно владельца окна восстанавливается.

Возвращаемые значения
Если программа обрабатывает это сообщение, она должна возвратить ноль.

Действия по умолчанию
Функция DefWindowProc скрывает или показывает окно, как установлено в соответствии с сообщением.

Замечания
Если окно, когда оно создается, имеет стиль WS_VISIBLE, окно принимает это сообщение после того, как оно создано, но прежде, чем оно появится. Окно также принимает это сообщение, когда его состояние видимости изменено функцией ShowWindow или ShowOwnedPopups. Сообщение WM_SHOWWINDOW не посылается при следующих обстоятельствах:

  • Когда верхнего уровня, перекрывающее окно создано с WS_MAXIMIZE или WS_MINIMIZE стилем.
  • Когда установлен флажок SW_SHOWNORMAL в обращении к функции ShowWindow.

Смотри также
DefWindowProc, ShowOwnedPopups, ShowWindow

Размещение и совместимость WM_SHOWWINDOW

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


1.27.3.34 Сообщение WM_SIZE

Сообщение WM_SIZE посылается окну после того, как его размер изменился.

Синтаксис

WM_SIZE
fwSizeType = wParam;      // флажок изменения размеров
nWidth = LOWORD(lParam);  // ширина рабочей области
nHeight = HIWORD(lParam); // высота рабочей области

Параметры

fwSizeType
Значение wParam. Определяет тип запрошенного изменения размеров. Этот параметр может принимать одно из следующих значений:

  • SIZE_MAXHIDE - Сообщение посылается всем выскакивающим окнам, когда развернуто некоторое другое окно.
  • SIZE_MAXIMIZED - Окно было развернуто.
  • SIZE_MAXSHOW - Сообщение посылается всем выскакивающим окнам, когда некоторое другое окно было восстановлено в его прежних размерах.
  • SIZE_MINIMIZED - Окно было свернуто(минимизировано).
  • SIZE_RESTORED - Окно было изменено, но ни одно значение SIZE_MINIMIZED ни SIZE_MAXIMIZED не применяется.

nWidth
Значение младшего слова lParam. Устанавливает новую ширину рабочей области.
nHeight
Значение старшего слова lParam. Устанавливает новую высоту рабочей области.

Возвращаемые значения
Если программа обрабатывает это сообщение, она должна возвратить ноль.

Замечания
Если функция SetScrollPos или MoveWindow вызвана для дочернего окна в результате сообщения WM_SIZE, параметр bRedraw должен отличаться от нуля, чтобы заставить окно быть перекрашенным. Хотя ширина и высота окна - 32-разрядные значения, параметры nWidth и nHeight сообщения WM_SIZE содержат только младшие 16 битов.

Смотри также
MoveWindow, SetScrollPos

Размещение и совместимость WM_SIZE

Windows NT		Да
Win95			Да
Win32s			Да
Импортируемая библиотека	-
Заголовочный файл		winuser.h
Unicode			Нет
Замечания по платформе	Не имеется


1.27.3.35 Сообщение WM_SIZING

Сообщение WM_SIZING посылается окну, у которого пользователь изменяет размеры. Обрабатывая это сообщение, прикладная программа может контролировать размер и позицию перетаски-ваемого прямоугольника и, если необходимо, изменять его размер или позицию.

Синтаксис

fwSide = wParam;         		// край устанавливаемого по размеру окна
lprc = (LPRECT) lParam;  		// экранные координаты перетаскиваемого прямоугольника

Параметры

fwSide
Значение wParam. Указывает, который край окна устанавливается по размеру. Этот параметр может быть комбинацией следующих значений:

  • WMSZ_BOTTOM - Нижний край
  • WMSZ_BOTTOMLEFT - Угол левой нижней части
  • WMSZ_BOTTOMRIGHT - Угол правой нижней части
  • WMSZ_LEFT - Левый край
  • WMSZ_RIGHT - Правый край
  • WMSZ_TOP - Верхний край
  • WMSZ_TOPLEFT - Угол левой верхней части
  • WMSZ_TOPRIGHT - Угол правой верхней части

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

Возвращаемые значения
Прикладная программа должна возвратить ИСТИНА (TRUE), если она обрабатывает это сообщение.

Смотри также
RECT, WM_MOVING, WM_SIZE

Размещение и совместимость WM_SIZING

Windows NT		Да
Win95			Да
Win32s			Нет
Импортируемая библиотека	-
Заголовочный файл		winuser.h
Unicode			Нет
Замечания по платформе	Не имеется


1.27.3.36 Сообщение WM_STYLECHANGED

Сообщение WM_STYLECHANGED посылается окну, если после функции SetWindowLong изменилось один или большее количество стилей окна.

Синтаксис

WM_STYLECHANGED
wStyleType = wParam;            	// расширенные или не расширенные стили
lpss = (LPSTYLESTRUCT) lParam;  	// структура, содержащая новые стили

Параметры

wStyleType
Значение wParam. Определяет, изменились ли расширенные или нерасширенные стили окна. Этот параметр может быть комбинацией следующих значений:

  • GWL_EXSTYLE - Расширенные стили окна изменились.
  • GWL_STYLE - Нерасширенные стили окна изменились.

lpss
Значение lParam. Указывает на структуру STYLESTRUCT, которая содержит новые стили для окна. Прикладная программа может исследовать стили, но не может изменять их.

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

Смотри также
SetWindowLong, STYLESTRUCT, WM_STYLECHANGING

Размещение и совместимость WM_STYLECHANGED

Windows NT		Да
Win95			Да
Win32s			Да
Импортируемая библиотека	-
Заголовочный файл		winuser.h
Unicode			Нет
Замечания по платформе	Не имеется


1.27.3.37 Сообщение WM_STYLECHANGING

Сообщение WM_STYLECHANGING посылается окну, когда функция SetWindowLong собирается изменить один или большее количество стилей окна.

Синтаксис

WM_STYLECHANGING
wStyleType = wParam;            		// расширенный и не расширенный стили
lpss = (LPSTYLESTRUCT) lParam; 	 	// структура, содержащая новые стили

Параметры

wStyleType
Значение wParam. Определяет, изменились ли расширенные или нерасширенные стили окна. Этот параметр может быть комбинацией следующих значений:

  • GWL_EXSTYLE - Расширенные стили окна изменяются.
  • GWL_STYLE - Нерасширенные стили окна изменяются.

lpss
Значение lParam. Указывает на структуру STYLESTRUCT, которая содержит предложенные новые стили для окна. Прикладная программа может исследовать стили и, в случае необходимости, изменять их.

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

Смотри также
SetWindowLong, STYLESTRUCT, WM_STYLECHANGED

Размещение и совместимость WM_STYLECHANGING

Windows NT		Да
Win95			Да
Win32s			Да
Импортируемая библиотека	-
Заголовочный файл		winuser.h
Unicode			Нет
Замечания по платформе	Не имеется


1.27.3.38 Сообщение WM_USERCHANGED

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

Синтаксис

WM_USERCHANGED
wParam = 0;       // не используется, должно быть - ноль
lParam = 0;       // не используется, должно быть - ноль

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

Размещение и совместимость WM_USERCHANGED

Windows NT		Да
Win95			Да
Win32s			Нет
Импортируемая библиотека	-
Заголовочный файл		winuser.h
Unicode			Нет
Замечания по платформе	Не имеется


1.27.3.39 Сообщение WM_WINDOWPOSCHANGED

Сообщение WM_WINDOWPOSCHANGED посылается окну, чей размер, позиция, или место в Z-последовательности изменились в результате обращения к функции SetWindowPos или другой функции управления окном.

Синтаксис

WM_WINDOWPOSCHANGED
lpwp = (LPWINDOWPOS) lParam; // указывает на данные о размере и позиции

Параметры

lpwp
Значение lParam. Указывает на структуру WINDOWPOS, которая содержит информацию относительно нового размера окна и позиции.

Возвращаемые значения
Если программа обрабатывает это сообщение, то она должна возвратить ноль.

Действия по умолчанию
Функция DefWindowProc посылает окну сообщения WM_SIZE и WM_MOVE.

Замечания
Сообщения WM_SIZE и WM_MOVE не посылаются, если прикладная программа обрабатывает сообщение WM_WINDOWPOSCHANGED без вызова DefWindowProc. Это более эффективно выполнит любое перемещение или обработку изменения размера в течение сообщения WM_WINDOWPOSCHANGED без вызова DefWindowProc.

Смотри также
DefWindowProc, EndDeferWindowPos, SetWindowPos, WINDOWPOS, WM_MOVE, WM_SIZE, WM_WINDOWPOSCHANGING

Размещение и совместимость WM_WINDOWPOSCHANGED

Windows NT		Да
Win95			Да
Win32s			Да
Импортируемая библиотека	-
Заголовочный файл		winuser.h
Unicode			Нет
Замечания по платформе	Не имеется


1.27.3.40 Сообщение WM_WINDOWPOSCHANGING

Сообщение WM_WINDOWPOSCHANGING посылается окну, чей размер, позиция, или место в Z-последовательности собирается измениться в результате обращения к функции SetWindowPos или другой функции управления окна.

Синтаксис

WM_WINDOWPOSCHANGING
lpwp = (LPWINDOWPOS) lParam; // указывает на данные о позиции и размере

Параметры

lpw
Значение lParam. Указывает на структуру WINDOWPOS, которая содержит информацию от-носительно нового размера окна и позиции.

Возвращаемые значения
Если программа обрабатывает это сообщение, то она должна возвратить ноль.

Действия по умолчанию
Для окна со стилем WS_OVERLAPPED или WS_THICKFRAME, функция DefWindowProc посылает окну сообщение WM_GETMINMAXINFO. Это делается для того, чтобы проверить правильность нового размера и позиции окна и обеспечить исполнение стилей CS_BYTEALIGNCLIENT и CS_BYTEALIGNWINDOW пользователя. Не передавая WM_WINDOWPOSCHANGING сообщение в функцию DefWindowProc, прикладная программа может отменять эти значения по умолчанию.

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

Смотри также
DefWindowProc,EndDeferWindowPos, SetWindowPos, WINDOWPOS, WM_GETMINMAXINFO, WM_MOVE, WM_SIZE, WM_WINDOWPOSCHANGED

Размещение и совместимость WM_WINDOWPOSCHANGING

Windows NT		Да
Win95			Да
Win32s			Да
Импортируемая библиотека	-
Заголовочный файл		winuser.h
Unicode			Нет
Замечания по платформе	Не имеется


1.27.3.41 Сообщение WM_WININICHANGE

WM_WININICHANGE устарело. Оно включено для совместимости с более ранними версиями Windows. Новые прикладные программы должны использовать сообщение WM_SETTINGCHANGE.

Размещение и совместимость WM_WININICHANGE

Windows NT		Да
Win95			Да
Win32s			Да
Импортируемая библиотека	-
Заголовочный файл		winuser.h
Unicode			WinNT
Замечания по платформе	Не имеется
Предыдущий Шаг


Глава 8 - Пиктограммы

Пиктограмма (icon) – это рисунок, который состоит из растрового изображения, объединенного с маской, которая создает прозрачные области на рисунке. Этот краткий обзор описывает создание, показ на экране, разрушение и дублирование пиктограмм.

Следующий Шаг


8.1 - О пиктограммах

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

Информацию об определении пиктограмм для типов файлов, см. в статье Обработчики пиктограмм.

Примечание переводчика: здесь и везде в тексте под термином ярлык (shortcut) подразумевается пиктограмма, которая обозначает комбинацию клавиш («быструю клавишу») пункта какого-либо меню или системного действия.


8.2 - "Горячая точка" пиктограммы

Один из пикселей в пиктограмме обозначен как " горячая точка "(hot spot), которая является точкой, при помощи которой система устанавливает и распознает, например, позицию пиктограммы. " Горячая точка " пиктограммы - обычно пиксель, размещенный в её центре. Если Вы используете функцию CreateIconIndirect, чтобы создать пиктограмму, Вы можете определить любой пиксель, который будет " горячей точкой ".


8.3 - Типы пиктограмм

Операционная система предоставляет набор стандартных пиктограмм (standard icons), которые являются доступными для любой прикладной программы, чтобы использовать их в любое время. Заголовочные файлы Windows содержат идентификаторы для стандартных пиктограмм - идентификаторы начинаются с префикса "IDI_".

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

Пользовательские пиктограммы (custom icons) разрабатываются для использования в конкретной прикладной программе и могут быть любого вида. Ниже показано несколько стандартных и пользовательских пиктограмм.

4_1.gif (7539 b)


8.4 - Размеры пиктограммы

Windows использует четыре размера пиктограмм: системная маленькая, системная большая, маленькая для оболочки и большая для оболочки.

Маленькая системная пиктограмма (system small icon) отображается в заголовке окна. Чтобы изменить размер системной маленькой пиктограммы, запустите апплет «Экран» в Панели управления, щелкните мышью по вкладке Внешний вид, выберите Заголовки Кнопок из списка Элементы, затем установите поле Размер. Чтобы возвратить размер системной маленькой пиктограммы, вызовите функцию GetSystemMetrics с флажком SM_CXSMICON и SM_CYSMICON.

Большая системная пиктограмма (system large icon) главным образом используется прикладными программами, а также она отображается в диалоговом окне переключения программ при помощи Alt+Tab. Функции CreateIconFromResource, DrawIcon, ExtractIcon и LoadIcon все используют большие системные пиктограммы. Размер большой системной пиктограммы определяется видеодрайвером, следовательно, он не может быть изменен. Вы можете возвратить размер большой системной пиктограммы, при помощи вызова GetSystemMetrics с флажками SM_CXICON и SM_CYICON.

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

Маленькая пиктограмма оболочки (shell small icon) используется в Проводнике Windows и стандартных диалоговых окнах. В настоящее время, это значение по умолчанию для системы небольшого размера. Чтобы получить размер маленькой пиктограммы оболочки, используйте функцию SHGetFileInfo с флажками SHGFI_SHELLICONSIZE | SHGFI_SMALLICON, которая возвратит дескриптор списка изображений системы, а затем функцию ImageList_GetIconSize, чтобы получить размер пиктограммы.

Большая пиктограмма оболочки (shell large icon) используется на рабочем столе. Чтобы изменить размер большой пиктограммы, запустите апплет "Экран" в Панели управления, щелкните мышью по вкладке Эффекты (для Windows 98), выберите Пиктограмму из Списка элементов, а затем установите поле Размер (этот размер сохраняется в системном реестре, в каталоге HKEY_CURRENT_USER\CONTROL Panel, Desktop\WindowMetrics\Shell Icon Size). Вы можете также щелкнуть по вкладке Plus! и установить флажок напротив надписи Использовать большие пиктограммы (Use large icons). Чтобы возвратить размер большой пиктограммы оболочки, используйте функцию SHGetFileInfo с SHGFI_SHELLICONSIZE, которая возвратит дескриптор списка изображений системы, а затем функцию ImageList_GetIconSize, чтобы получить размер пиктограммы.

Меню Пуск (Start) использует или маленькие пиктограммы оболочки или большие пиктограммы оболочки, зависимости от того, установлен ли флажок напротив надписи Использовать большие пиктограммы (Use large icons).

Ваша прикладная программа должна обеспечить ресурсы пиктограмм в следующих размерах:

48x48, 256 цветов
32x32, 16 цветов
16x16 пикселей, 16 цветов

При заполнении структуры WNDCLASSEX, которая используется при регистрации класса вашего окна, установите ее член hIcon как пиктограмму 32x32, а член hIconSm как пиктограмму 16x16. Для получения дополнительной информации о классах пиктограмм, см. статью Класс пиктограммы.


8.5 - Создание пиктограммы

Стандартные пиктограммы предопределены, так что нет необходимости создавать их. Чтобы использовать стандартную пиктограмму, прикладная программа может получить ее дескриптор, используя функцию LoadImage. Дескриптор пиктограммы (icon handle) - уникальное значение типа HICON, который идентифицирует стандартную или пользовательскую пиктограмму.

Чтобы создать пользовательскую пиктограмму для прикладной программы, разработчики обычно используют программу для работы с графикой и включают ресурс ПИКТОГРАММЫ (ICON) в файл определения ресурса приложения. Во время запуска, прикладная программа может вызывать LoadIcon или LoadImage, чтобы получить дескриптор пиктограммы. Ресурс пиктограммы содержит данные для нескольких различных устройств отображения. Функции LoadIcon и LoadImage автоматически выбирают данные наиболее соответствующие для текущего устройства отображения.

Прикладная программа может также создать и пользовательскую пиктограмму в период запуска программы, при помощи использования функции CreateIconIndirect, которая создает пиктограмму, основанную на содержании структуры ICONINFO. Функция GetIconInfo заполняет структуру координатами "горячей точки" и информацией о битовой маске и цвете точечного рисунка пиктограммы.

Прикладные программы должны исполнять пользовательские пиктограммы как ресурсы и должны использовать LoadIcon или LoadImage, которые предпочтительнее чем создание пиктограммы в период запуска программы. Использование ресурсов пиктограммы помогает избежать зависимости от устройства, упрощает определение местонахождения и позволяет приложениям совместно использовать образ пиктограммы.

Функция CreateIconFromResourceEx позволяет прикладной программе просматривать ресурсы системы и создавать пиктограммы и курсоры, основанные на данных ресурса. Функция CreateIconFromResourceEx создает пиктограмму, основанную на двоичных данных ресурса из других исполняемых файлов или динамически подключаемых библиотек (DLL). Прикладная программа должна перед обращением к этой функции обратиться к функции LookupIconIdFromDirectoryEx и нескольким функциям ресурса. Функция LookupIconIdFromDirectoryEx возвращает идентификатор наиболее соответствующих данных пиктограммы для текущего устройства отображения. Для получения дополнительной информации о функциях ресурса, см. статью Функции ресурса.


8.6 - Отображение пиктограммы на экране

Прикладная программа может получить изображение пиктограммы, используя функцию GetIconInfo, а может нарисовать ее, используя функцию DrawIconEx. Чтобы нарисовать заданное по умолчанию изображение пиктограммы, установите флажок DI_COMPAT при вызове DrawIconEx. Если Вы не устанавливаете флажок DI_COMPAT, DrawIconEx рисует пиктограмму, используя изображение, которое определил пользователь.


8.7 - Разрушение пиктограммы

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


8.8 - Дублирование пиктограммы.

Функция CopyIcon копирует дескриптор пиктограммы. Это позволяет прикладной программе или динамически подключаемой библиотеке (DLL) получить свой собственный дескриптор пиктограммы, принадлежащей другому модулю. Затем, если другой модуль освобождается, приложение, которое скопировало пиктограмму, будет все еще получать возможность, чтобы использовать ее.

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

За информации о добавлении, удалении или замене ресурса пиктограммы в исполняемом (.EXE) файле, обратитесь к статье Ресурсы.


8.9 - Использование пиктограмм

Эти ниже следующие темы описывают, как выполнять некоторые задачи, связанные пиктограммами:
Создание пиктограмм
Показ пиктограмм на экране
Совместное использование ресурсов пиктограммы


8.9.1 - Создание пиктограммы

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

HICON hIcon1;   // дескриптор пиктограммы
HICON hIcon2;   // дескриптор пиктограммы
// Создаем стандартную пиктограмму со знаком вопроса.
hIcon1 = LoadIcon(NULL, IDI_QUESTION);
// Создаем пользовательскую пиктограмму, основанную на ресурсе.
hIcon2 = LoadIcon(hinst, MAKEINTRESOURCE(460));
// Создаем индивидуальную пиктограмму периода выполнения программы.

Прикладная программа должна исполнять пользовательские пиктограммы как ресурсы и должна использовать функцию LoadIcon или LoadImage, предпочтительнее, а не создавать пиктограммы периода выполнения программы. Этот подход позволяет избежать зависимости от устройства, упрощает определение местонахождения и позволяет программам совместно использовать точечные рисунки пиктограммы. Тем не менее, следующий пример использует CreateIcon, чтобы создать пользовательскую пиктограмму в период выполнения программы, основанную на растровых битовых масках; это включено для того, чтобы иллюстрировать, как система интерпретирует битовые маски точечного рисунка пиктограммы.

HICON hIcon3;      // дескриптор пиктограммы
// светлая(yang) битовая маска AND пиктограммы

BYTE ANDmaskIcon[] = {
    0xFF, 0xFF, 0xFF, 0xFF,   // строка 1
    0xFF, 0xFF, 0xC3, 0xFF,   // строка 2
    0xFF, 0xFF, 0x00, 0xFF,   // строка 3
    0xFF, 0xFE, 0x00, 0x7F,   // строка 4

    0xFF, 0xFC, 0x00, 0x1F,   // строка 5
    0xFF, 0xF8, 0x00, 0x0F,   // строка 6
    0xFF, 0xF8, 0x00, 0x0F,   // строка 7
    0xFF, 0xF0, 0x00, 0x07,   // строка 8

    0xFF, 0xF0, 0x00, 0x03,   // строка 9
    0xFF, 0xE0, 0x00, 0x03,   // строка 10
    0xFF, 0xE0, 0x00, 0x01,   // строка 11
    0xFF, 0xE0, 0x00, 0x01,   // строка 12

    0xFF, 0xF0, 0x00, 0x01,   // строка 13
    0xFF, 0xF0, 0x00, 0x00,   // строка 14
    0xFF, 0xF8, 0x00, 0x00,   // строка 15
    0xFF, 0xFC, 0x00, 0x00,   // строка 16

    0xFF, 0xFF, 0x00, 0x00,   // строка 17
    0xFF, 0xFF, 0x80, 0x00,   // строка 18
    0xFF, 0xFF, 0xE0, 0x00,   // строка 19
    0xFF, 0xFF, 0xE0, 0x01,   // строка 20

    0xFF, 0xFF, 0xF0, 0x01,   // строка 21
    0xFF, 0xFF, 0xF0, 0x01,   // строка 22
    0xFF, 0xFF, 0xF0, 0x03,   // строка 23
    0xFF, 0xFF, 0xE0, 0x03,   // строка 24

    0xFF, 0xFF, 0xE0, 0x07,   // строка 25
    0xFF, 0xFF, 0xC0, 0x0F,   // строка 26
    0xFF, 0xFF, 0xC0, 0x0F,   // строка 27
    0xFF, 0xFF, 0x80, 0x1F,   // строка 28

    0xFF, 0xFF, 0x00, 0x7F,   // строка 29
    0xFF, 0xFC, 0x00, 0xFF,   // строка 30
    0xFF, 0xF8, 0x03, 0xFF,   // строка 31
    0xFF, 0xFC, 0x3F, 0xFF};  // строка 32

// Светлая (yang) битовая маска XOR пиктограммы

BYTE XORmaskIcon[] = {
    0x00, 0x00, 0x00, 0x00,   // строка 1
    0x00, 0x00, 0x00, 0x00,   // строка 2
    0x00, 0x00, 0x00, 0x00,   // строка 3
    0x00, 0x00, 0x00, 0x00,   // строка 4

    0x00, 0x00, 0x00, 0x00,   // строка 5
    0x00, 0x00, 0x00, 0x00,   // строка 6
    0x00, 0x00, 0x00, 0x00,   // строка 7
    0x00, 0x00, 0x38, 0x00,   // строка 8

    0x00, 0x00, 0x7C, 0x00,   // строка 9
    0x00, 0x00, 0x7C, 0x00,   // строка 10
    0x00, 0x00, 0x7C, 0x00,   // строка 11
    0x00, 0x00, 0x38, 0x00,   // строка 12

    0x00, 0x00, 0x00, 0x00,   // строка 13
    0x00, 0x00, 0x00, 0x00,   // строка 14
    0x00, 0x00, 0x00, 0x00,   // строка 15
    0x00, 0x00, 0x00, 0x00,   // строка 16

    0x00, 0x00, 0x00, 0x00,   // строка 17
    0x00, 0x00, 0x00, 0x00,   // строка 18
    0x00, 0x00, 0x00, 0x00,   // строка 19
    0x00, 0x00, 0x00, 0x00,   // строка 20

    0x00, 0x00, 0x00, 0x00,   // строка 21
    0x00, 0x00, 0x00, 0x00,   // строка 22
    0x00, 0x00, 0x00, 0x00,   // строка 23
    0x00, 0x00, 0x00, 0x00,   // строка 24

    0x00, 0x00, 0x00, 0x00,   // строка 25
    0x00, 0x00, 0x00, 0x00,   // строка 26
    0x00, 0x00, 0x00, 0x00,   // строка 27
    0x00, 0x00, 0x00, 0x00,   // строка 28

    0x00, 0x00, 0x00, 0x00,   // строка 29
    0x00, 0x00, 0x00, 0x00,   // строка 30
    0x00, 0x00, 0x00, 0x00,   // строка 31
    0x00, 0x00, 0x00, 0x00};  // строка 32

hIcon3 = CreateIcon(hinst,    // экземпляр приложения
    32,	// ширина пиктограммы
    32,	// высота пиктограммы
    1,	// число плоскостей XOR
    1,	// число битов на пиксель
    ANDmaskIcon,	// битовая маска AND
    XORmaskIcon);	// битовая маска XOR

Чтобы создать пиктограмму, CreateIcon применяет следующую таблицу истинности битовым маскам XOR и AND.

AND битовая маска | XOR битовая маска | Изображение
0 | 0 | Черное
0 | 1 | Белое
1 | 0 | Экранное
1 | 1 | Противоположное экранному

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


8.9.2 - Отображение пиктограммы на экране

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

HICON hIcon1;	// дескриптор пиктограммы
HDC hdc;		// дескриптор устройства отображения
DrawIcon(hdc, 10, 20, hIcon1);

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

HINSTANCE hinst;	// дескриптор текущего экземпляра
HWND hwnd;	// дескриптор основного окна

// Изменяем пиктограмму для класса окна hwnd's

SetClassLong(hwnd,	// дескриптор окна изменяет пиктограмму
    GCL_HICON,
    (LONG) LoadIcon(hinst, MAKEINTRESOURCE(480))
);

Для получения дополнительной информации о классах окна, см. Классы окна.


8.9.3 - Совместное использование ресурсов пиктограммы

Следующий код использует функции CreateIconFromResourceEx, DrawIcon и LookupIconIdFromDirectoryEx и некоторые из функций ресурса, чтобы создать дескриптор пиктограммы, основанный на ее данных из другого исполняемого файла. Затем, он показывает на экране пиктограмму в окне.

HICON hIcon1;	// дескриптор пиктограммы
HINSTANCE hExe;	// дескриптор загружаемого .EXE файла
HRSRC hResource;	// дескриптор для FindResource (поиска ресурса)
HRSRC hMem;	// дескриптор для LoadResource (загрузки ресурса)
BYTE *lpResource;	// адрес данных ресурса
int nID;		// ID (идентификатор ресурса, который лучше всего
        // соответствует текущему экрану

HDC hdc;		// дескриптор контекста дисплея

// Загрузка файла, из которого копируется пиктограмма.
hExe = LoadLibrary("myapp.exe");

// Поиск каталога пиктограммы, идентификатор которой - 440.
hResource = FindResource(hExe,
    MAKEINTRESOURCE(440),
    RT_GROUP_ICON);

// Загрузка и просмотр каталога пиктограммы.
hMem = LoadResource(hExe, hResource);

lpResource = LockResource(hMem);

// Получаем идентификатор пиктограммы, которая должна соответствовать
// видеодисплею.
nID = LookupIconIdFromDirectoryEx((PBYTE) lpResource, TRUE,
    CXICON, CYICON, LR_DEFAULTCOLOR);

// Находим биты nID (идентификатора) пиктограммы.

hResource = FindResource(hExe,
    MAKEINTRESOURCE(nID),
    MAKEINTRESOURCE(RT_ICON));

// Загружаем и просматриваем пиктограмму.
hMem = LoadResource(hExe, hResource);

lpResource = LockResource(hMem);

// Создаем дескриптор пиктограммы.

hIcon1 = CreateIconFromResourceEx((PBYTE) lpResource,
    SizeofResource(hExe, hResource), TRUE, 0x00030000,
    CXICON, CYICON, LR_DEFAULTCOLOR);

// Рисуем пиктограмму в рабочей области.
DrawIcon(hdc, 10, 20, hIcon1);


8.10 - Справочник по пиктограммам

Ниже перечисленные функции структуры и сообщения используются с пиктограммами.


8.10.1 - Функции пиктограммы

Ниже перечислены функции, которые используются пиктограммами:
CopyIcon
CreateIcon
CreateIconFromResource
CreateIconFromResourceEx
CreateIconIndirect
DestroyIcon
DrawIcon
DrawIconEx
GetIconInfo
LoadIcon
LookupIconIdFromDirectory
LookupIconIdFromDirectoryEx


8.10.1.1 - Функция CopyIcon

(КопироватьПиктограмму)

Функция CopyIcon копирует определяемую пиктограмму из другого модуля в текущий модуль.

Синтаксис

HICON CopyIcon
(
    HICON hIcon	// дескриптор пиктограммы, которая копируется
);

Параметры
hIcon
Идентифицирует пиктограмму, которая будет скопирована.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - дескриптор дубликата пиктограммы.
Если функция не выполняет задачу, величина возвращаемого значения - ПУСТО (NULL). Чтобы получить дополнительные данные об ошибках, вызовите GetLastError.

Замечания
Функция CopyIcon позволяет прикладной программе или динамически компонуемой библиотеке (DLL) получить свой собственный дескриптор для пиктограммы, принадлежащей другому модулю. Если другой модуль освобождается, пиктограмма программы будет все еще получать возможность использовать пиктограмму.

Смотри также
CopyCursor, DrawIcon, DrawIconEx

Размещение и совместимость CopyIcon

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Уникод					Нет
Замечания по платформе			Не имеется


8.10.1.2 - Функция CreateIcon

(СоздатьПиктограмму)

Функция CreateIcon создает пиктограмму, которая имеет определенный размер, цвет и битовые шаблоны.

Синтаксис

HICON CreateIcon
{
    HINSTANCE hInstance,	// дескриптор экземпляра приложения
    int nWidth,		// ширина пиктограммы
    int nHeight,		// высота пиктограммы
    BYTE cPlanes,		// число плоскостей в битовой маске XOR
    BYTE cBitsPixel,		// число битов на пиксель в битовой маске XOR
    CONST BYTE *lpbANDbits,	// указатель на массив битовой маски AND
    CONST BYTE *lpbXORbits	// указатель на массив битовой маски XOR
);

Параметры
hInstance
Идентифицирует экземпляр модуля, создающего пиктограмму.
nWidth
Определяет ширину пиктограммы, в пикселях.
nHeight
Определяет высоту пиктограммы, в пикселях.
cPlanes
Определяет число плоскостей в битовой маске XOR пиктограммы.
cBitsPixel
Определяет число битов на пиксель в битовой маске XOR пиктограммы.
lpbANDbits
Указывает на массив байтов, который содержит битовые значения для битовой маски AND пиктограммы. Эта битовая маска описывает одноцветный точечный рисунок.
lpbXORbits
Указывает на массив байтов, который содержит битовые значения для битовой маски XOR пиктограммы. Эта битовая маска описывает одноцветный или аппаратно-зависимый цветной точечный рисунок.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - дескриптор пиктограммы.
Если функция не выполняет задачу, величина возвращаемого значения ПУСТО (NULL). Чтобы получать расширенные данные об ошибках, вызовите GetLastError.

Замечания
Параметры nWidth и nHeight должны определить ширину и высоту, поддерживаемую текущим драйвером дисплея, потому что система не может создавать пиктограммы, других размеров. Чтобы определить ширину и высоту, поддерживаемую драйвером дисплея, используйте функцию GetSystemMetrics, определяя значение SM_CXICON или SM_CYICON.
CreateIcon применяет следующую таблицу истинности к битовым маскам XOR и AND:

Битовая маска AND | Битовая маска XOR | Изображение
0 | 0 | Черное
0 | 1 | Белое
1 | 0 | Экранное
1 | 1 | Обратное экранному

Смотри также
GetSystemMetrics

Размещение и совместимость CreateIcon

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Уникод					Нет
Замечания по платформе			Не имеется


8.10.1.3 - Функция CreateIconFromResource

(СоздатьПиктограммуИзРесурса)

Функция CreateIconFromResource создает пиктограмму или курсор из битов ресурса, описывающих пиктограмму.

Синтаксис

HICON CreateIconFromResource
(
    PBYTE presbits,	// указатель на биты пиктограммы или курсора
    DWORD dwResSize,	// число байтов в буфере битов
    BOOL fIcon,	// флажок пиктограммы или курсора
    DWORD dwVer	// версия формата Windows
);

Параметры
presbits
Указывает на буфер, содержащий биты ресурса пиктограммы или курсора. Эти биты обычно загружаются при помощи вызова функций LookupIconIdFromDirectory (в Windows 95, Вы можете также вызвать LookupIconIdFromDirectoryEx) и LoadResource.
dwResSize
Определяет размер, в байтах, набор битов, указанных параметром presbits.
fIcon
Определяет, что должно быть создано - пиктограмма или курсор. Если этот параметр - ИСТИНА (TRUE), должна быть создана пиктограмма. Если он - ЛОЖЬ (FALSE), должен быть создан курсор.
dwVer
Определяет номер версии формата пиктограммы или курсора для битов ресурса, указанных параметром presbits. Этот параметр может быть одним из следующих значений:

Формат		dwVer
Windows 2.x	0x00020000
Windows 3.x	0x00030000

Все прикладные программы, базирующиеся на Microsoft Win32, использует для пиктограмм и курсоров формат Windows 3.x.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - дескриптор пиктограммы или курсора.
Если функция не выполняет задачу, величина возвращаемого значения - ПУСТО (NULL). Чтобы получать расширенные данные об ошибках, вызовите GetLastError.

Замечания
Функции CreateIconFromResource, CreateIconIndirect, GetIconInfo и LookupIconIdFromDirectory (и в Windows 95 функции CreateIconFromResourceEx и LookupIconIdFromDirectoryEx) позволяют оболочке прикладной программы и программе просмотра пиктограммы проверять и использовать ресурсы по всей системе.

Смотри также
CreateIconFromResource, CreateIconFromResourceEx, CreateIconIndirect, GetIconInfo, LoadResource, LookupIconIdFromDirectory, LookupIconIdFromDirectoryEx

Размещение и совместимость CreateIconFromResource

Windows NT				Да
Win95					Да
Win32s					Нет
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Уникод					Нет
Замечания по платформе			Не имеется


8.10.1.4 - Функция CreateIconFromResourceEx

(СоздатьПиктограммуИзРесурсаРасширенная)

[Теперь поддерживается в Windows NT]

Функция CreateIconFromResourceEx создает пиктограмму или курсор из битов ресурса, описывающих пиктограмму.

Синтаксис

HICON CreateIconFromResourceEx
(
    PBYTE pbIconBits,	// указатель на биты пиктограммы или курсора
    DWORD cbIconBits,	// число байтов в буфере битов
    BOOL fIcon,	// флажок пиктограммы или курсора
    DWORD dwVersion,	// версия формата Windows
    int cxDesired,	// желаемая ширина пиктограммы или курсора
    int cyDesired,	// желаемая высота пиктограммы или курсора
    UINT uFlags	// флажки загружаемого ресурса
);

Параметры
pbIconBits
Указывает на буфер, содержащий биты ресурса пиктограммы или курсора. Эти биты обычно загружаются при помощи вызова функций LookupIconIdFromDirectoryEx и LoadResource.
cbIconBits
Определяет размер, в байтах, набора битов, указанных параметром pbIconBits.
fIcon
Определяет, что должно быть создано - пиктограмма или курсор. Если этот параметр - ИСТИНА (TRUE), должна быть создана пиктограмма. Если это - ЛОЖЬ (FALSE), должен быть создан курсор.
dwVersion
Определяет номер версии формата пиктограммы или курсора для битов ресурса, указанных параметром pbIconBits. Этот параметр может быть одним из следующих значений:

Формат 		dwVersion
Windows 2.x	0x00020000
Windows 3.x	0x00030000

Все прикладные программы, базирующиеся на Win32, используют формат Windows 3.x для пиктограмм и курсоров.
cxDesired
Определяет желаемую ширину, в пикселях, пиктограммы или курсора. Если этот параметр нулевой, функция использует, чтобы установить ширину, значение показателя системы SM_CXICON или SM_CXCURSOR.
cyDesired
Определяет желаемую высоту, в пикселях, пиктограммы или курсора. Если этот параметр нулевой, функция использует, чтобы установить высоту, значение показателя системы SM_CYICON или SM_CYCURSOR.
uFlags
Определяет комбинацию следующих значений:

  • LR_DEFAULTCOLOR - Использует заданный по умолчанию формат цвета.
  • LR_MONOCHROME - Создает одноцветную пиктограмму или курсор.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - дескриптор пиктограммы или курсора.
Если функция не выполняет задачу, величина возвращаемого значения - ПУСТО (NULL). Чтобы получать расширенные данные об ошибках, вызовите GetLastError.

Замечания
Функции CreateIconFromResourceEx, CreateIconFromResource, CreateIconIndirect, GetIconInfo и LookupIconIdFromDirectoryEx позволяют оболочке прикладной программы и программе просмотра пиктограммы проверять и использовать ресурсы по всей системе.

Смотри также
BITMAPINFOHEADER, CreateIconFromResource, CreateIconIndirect, GetIconInfo, LoadResource, LookupIconIdFromDirectoryEx

Размещение и совместимость CreateIconFromResourceEx

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Уникод				Нет
Замечания по платформе		Не имеется


8.10.1.5 - Функция CreateIconIndirect

(ПиктограммуСоздатьКосвенно)

Функция CreateIconIndirect создает пиктограмму или курсор из структуры ICONINFO.

Синтаксис

HICON CreateIconIndirect
(
    PICONINFO piconinfo	// указатель на структуру информации о пиктограмме
);

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

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - дескриптор пиктограммы или курсора, который создан.
Если функция не выполняет задачу, величина возвращаемого значения - ПУСТО (NULL). Чтобы получать расширенные данные об ошибках, вызовите GetLastError.

Замечания
Система копирует точечные рисунки в структуру ICONINFO перед созданием пиктограммы или курсора. Прикладная программа должна продолжить управлять первоначальными точечными рисунками и удалять их, когда они больше не нужны.
Когда Вы заканчиваете использовать пиктограмму, уничтожьте её, используя функцию DestroyIcon.

Смотри также
DestroyIcon, ICONINFO

Размещение и совместимость CreateIconIndirect

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Уникод				Нет
Замечания по платформе		Не имеется


8.10.1.6 - Функция DestroyIcon

(РазрушитьПиктограмму)

Функция DestroyIcon уничтожает пиктограмму и освобождает любую память, занятую ею.

Синтаксис

BOOL DestroyIcon
(
    HICON hIcon	// дескриптор пиктограммы, которую надо уничтожить
);

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

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

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

Смотри также
CreateIconIndirect

Размещение и совместимость DestroyIcon

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Уникод				Нет
Замечания по платформе		Не имеется


8.10.1.7 - Функция DrawIcon

(РисуемПиктограмму)

Функция DrawIcon рисует пиктограмму в рабочей области окна заданным контекстом устройства.

Синтаксис

BOOL DrawIcon
(
    HDC hDC,	// дескриптор контекста устройства
    int X,	// x-координата верхнего левого угла
    int Y,	// y- координата верхнего левого угла
    HICON hIcon	// дескриптор иконы, которую надо нарисовать
);

Параметры
hDC
Идентифицирует контекст устройства для окна.
X
Определяет логическую x-координату левого верхнего угла пиктограммы.
Y
Определяет логическую y-координату левого верхнего угла пиктограммы.
hIcon
Идентифицирует пиктограмму, которая будет нарисована.

Windows NT: ресурс пиктограммы должен быть предварительно загружен, при помощи использования функции LoadIcon.
Windows 95: ресурс пиктограммы, должен быть предварительно загружен, при помощи использования функции LoadIcon или LoadImage.

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

Замечания
DrawIcon помещает левый верхний угол пиктограммы в расположение, определяемое X и Y параметрами. Расположение подчиненно текущему режиму отображения контекста устройства.

Смотри также
CreateIcon, DrawIconEx, LoadIcon

Размещение и совместимость DrawIcon

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Уникод				Нет
Замечания по платформе		Не имеется


8.10.1.8 - Функция DrawIconEx

(РисуемПиктограммуРасширенная)

Функция DrawIconEx рисует пиктограмму или курсор в рабочей области окна, определившего контекст устройства, выполняя определяемые растровые действия, и, растягивая или сжимая пиктограмму или курсор как задано.

Синтаксис

BOOL DrawIconEx
(
    HDC hdc,			// дескриптор контекста устройства
    int xLeft,			// x-координата верхнего левого угла
    int yTop,			// y-координата верхнего левого угла
    HICON hIcon,			// дескриптор пиктограммы, которую надо рисовать
    int cxWidth,			// ширина пиктограммы
    int cyWidth,			// высота пиктограммы
    UINT istepIfAniCur,		// индекс фрейма в живом указателе
    HBRUSH hbrFlickerFreeDraw,	// дескриптор кисти фона
    UINT diFlags			// флажки рисуемой пиктограммы
);

Параметры
hdc
Идентифицирует контекст устройства для окна.
xLeft
Определяет логическую x-координату левого верхнего угла пиктограммы или курсора.
yTop
Определяет логическую y-координату левого верхнего угла пиктограммы или курсора. hIcon
Идентифицирует пиктограмму или курсор, который будет нарисован. Этот параметр может идентифицировать живой указатель. Ресурс пиктограммы или курсора, должны быть предварительно загружены при помощи использования функции LoadImage.
cxWidth
Определяет логическую ширину пиктограммы или курсора. Если этот параметр нулевой, а параметр diFlags - DI_DEFAULTSIZE, функция, чтобы установить ширину, использует метрическое значение SM_CXICON или SM_CXCURSOR системы. Если этот параметр нулевой, а DI_DEFAULTSIZE не использован, функция использует фактическую ширину ресурса.
cyWidth
Определяет логическую высоту пиктограммы или курсора. Если этот параметр нулевой, а diFlags параметр - DI_DEFAULTSIZE, функция, чтобы установить высоту, использует метрическое значение SM_CYICON или SM_CYCURSOR системы. Если этот параметр нулевой, а DI_DEFAULTSIZE не использован, функция использует фактическую высоту из ресурса.
istepIfAniCur
Определяет индекс кадра для рисования, если hIcon идентифицирует живой указатель. Этот параметр игнорируется, если hIcon не идентифицирует живой указатель.
hbrFlickerFreeDraw
Идентифицирует кисть, которую система использует для немерцающего рисунка. Если hbrBkgnd - допустимый дескриптор кисти, система создает вне экрана точечный рисунок, используя заданную кисть для цвета фона, рисует пиктограмму или курсор в виде точечного рисунка, а затем копирует его в контекст устройства, идентифицированный при помощи hdc. Если hbrBkgnd имеет значение ПУСТО (NULL), система рисует пиктограмму или курсор непосредственно в контекст устройства.
diFlags
Определяет флажки рисунка. Этот параметр может быть одним из следующих значений:

  • DI_COMPAT - Рисует пиктограмму или курсор, используя изображение определяемое системой по умолчанию, а не изображение определяемое пользователем.
  • DI_DEFAULTSIZE - Если в параметрах cxWidth и cyWidth установлен нуль, рисует пиктограмму или курсор, используя ширину и высоту определяемую метрическими значениями системы для курсоров или пиктограмм. Если этот флажок не установлен, а в параметры cxWidth и cyWidth установлены в нуль, функция использует фактический размер из ресурса.
  • DI_IMAGE - Выполняет растровую операцию, определяемую элементом ropImage.
  • DI_MASK - Выполняет растровую операцию, определяемую элементом ropMask.
  • DI_NORMAL - Комбинация DI_IMAGE и DI_MASK.

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

Замечания
Функция DrawIconEx помещает левый верхний угол пиктограммы в позицию, определяемую параметрами xLeft и yTop. Расположение подчиненно текущему режиму отображения контекста устройства.

Смотри также
CopyImage, DrawIcon, LoadImage

Размещение и совместимость DrawIconEx

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Уникод				Нет
Замечания по платформе		Не имеется


8.10.1.9 - Функция GetIconInfo

(ПолучитьИнформациюПиктограммы)

Функция GetIconInfo получает информацию о заданной пиктограмме или курсору.

Синтаксис

BOOL GetIconInfo
(
    HICON hIcon,		// дескриптор пиктограммы
    PICONINFO piconinfo 	// адрес структуры пиктограммы
);

Параметры
Идентифицирует пиктограмму или курсор. Чтобы получить информацию о стандартной пиктограмме или курсору, определите одно из следующих значений:

  • IDC_ARROW - Курсор в виде стрелки
  • IDC_IBEAM - Курсор в виде прямой линии – I
  • IDC_WAIT - Курсор в виде песочных часов
  • IDC_CROSS - Курсор в виде креста
  • IDC_UPARROW - Курсор в виде стрелки вверх
  • IDC_SIZENWSE - Установка размеров курсором, указывает на северо-запад и юго-восток
  • IDC_SIZENESW - Установка размеров курсором, указывает на северо-восток и юго-запад
  • IDC_SIZEWE - Установка размеров курсором, указывает на запад и восток
  • IDC_SIZENS - Установка размеров курсором, указывает на север и юг
  • IDC_SIZEALL - Установка размеров курсором, указывает на север, юг, восток, и запад
  • IDC_NO - Курсор "Нет"
  • IDC_APPSTARTING - Курсор запуска приложения (стрелка и песочные часы)
  • IDC_HELP - Курсор справки (стрелка и знак вопроса)
  • IDI_APPLICATION - Пиктограмма приложения
  • IDI_HAND - Пиктограмма с сигналом "Стоп"
  • IDI_QUESTION - Пиктограмма со знаком вопроса
  • IDI_EXCLAMATION - Пиктограмма со знаком восклицания
  • IDI_ASTERISK - Пиктограмма со звездочкой (буква "i" в круге)
  • IDI_WINLOGO - Пиктограмма с логотипом Windows

piconinfo
Указывает на структуру ICONINFO. Функция заполняет члены структуры.

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

Замечания
Функция GetIconInfo создает точечные рисунки для членов hbmMask и hbmColor структуры ICONINFO. Вызывающая прикладная программа должна управлять этими точечными рисунками и удалять их, когда они больше не нужны.

Смотри также
CreateIcon, CreateIconFromResource, CreateIconIndirect, DestroyIcon, DrawIcon, DrawIconEx, ICONINFO, LoadIcon, LookupIconIdFromDirectory

Размещение и совместимость GetIconInfo

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Уникод					Нет
Замечания по платформе			Не имеется


8.10.1.10 - Функция LoadIcon

(ЗагрузитьПиктограмму)

Функция LoadIcon загружает определяемый ресурс пиктограммы из исполняемого (.EXE) файла, связанного с экземпляром прикладной программы.

Синтаксис

HICON LoadIcon
(
    HINSTANCE hInstance,		// дескриптор экземпляра приложения
    LPCTSTR lpIconName 		// строка с именем или идентификатор ресурса пиктограммы
);

Параметры
hInstance
Идентифицирует экземпляр модуля, исполняемый файл которого содержит пиктограмму, которая будет загружена. Этот параметр должен иметь значение ПУСТО (NULL), когда загружается стандартная пиктограмма.
lpIconName
Указывает на строку с символом нуля в конце, которая содержит название ресурса пиктограммы, которая будет загружена. Альтернативно, этот параметр может содержать идентификатор ресурса в младшем слове и нули в старшем слове. Используйте макрокоманду MAKEINTRESOURCE, чтобы создать это значение.
Чтобы использовать одну из предопределенных пиктограмм Windows, установите параметр hInstance в значение ПУСТО (NULL), а параметр lpIconName в одно из следующих значений:

  • IDI_APPLICATION - Пиктограмма приложения по умолчанию.
  • IDI_ASTERISK - Звездочка (используется в информационных сообщениях).
  • IDI_EXCLAMATION - Восклицательный знак (используется в предупреждающих сообщениях).
  • IDI_HAND - Пиктограмма, имеющая форму руки (используется в серьезных предупреждающих сообщениях).
  • IDI_QUESTION - Вопросительный знак (используется в подсказках).
  • IDI_WINLOGO - Логотип Windows.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - дескриптор недавно загруженной пиктограммы.
Если функция не выполняет задачу, величина возвращаемого значения - ПУСТО (NULL). Чтобы получать расширенные данные об ошибках, вызовите GetLastError.

Замечания
LoadIcon загружает ресурс пиктограммы, только в том случае, если он не был загружен; иначе, функция получает дескриптор существующего ресурса. Функция ищет ресурс пиктограммы, которая наиболее соответствует для текущего дисплея. Ресурс пиктограммы может быть цветной или одноцветный точечный рисунок.
LoadIcon может загрузить только пиктограмму, размер которой соответствует метрическим значениям системы SM_CXICON и SM_CYICON. Используйте функцию LoadImage, чтобы загружать пиктограммы, которые другого размера.

Смотри также
CreateIcon, LoadImage, MAKEINTRESOURCE

Размещение и совместимость LoadIcon

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Уникод				WinNT
Замечания по платформе		Не имеется


8.10.1.11 - Функция LookupIconIdFromDirectory

(ПодстановкаПиктограммыИзКаталога)

Функция LookupIconIdFromDirectory ищет среди пиктограмм или курсоров данные, которые лучше всего соответствует текущему устройству отображения.

Синтаксис

int LookupIconIdFromDirectory
(
    PBYTE presbits,	// адрес ресурса с данными
    BOOL fIcon	// внешний вид иконы или курсора
);

Параметры
presbits
Указывает на каталог данных пиктограммы или курсора. Так как эта функция не проверяет правильность данных ресурса, она может стать причиной ошибки общей защиты (GP) или возвращает неопределенное значение, если presbits указывает на не правильные данные ресурса.
fIcon
Определяет, что разыскивается, пиктограмма или курсор. Если этот параметр - ИСТИНА (TRUE), функция ищет пиктограмму; если параметр - ЛОЖЬ (FALSE), функция ищет курсор.

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

Замечания
Файл ресурса типа RT_GROUP_ICON (RT_GROUP_CURSOR обозначающий курсоры) содержит данные пиктограммы (или курсора) в нескольких аппаратно-зависимых и не зависящих от устройства форматах. LookupIconIdFromDirectory ищет файл ресурса пиктограммы (или курсора), которые лучше всего соответствуют текущему устройству отображения и возвращает целочисленный идентификатор. Функции FindResource и FindResourceEx с этим идентификатором используют макрокоманду MAKEINTRESOURCE, чтобы определить ресурс в модуле.
Каталог пиктограммы загружается из файла ресурса с типом ресурса RT_GROUP_ICON (или RT_GROUP_CURSOR для курсоров) и целочисленным значением названия ресурса для конкретной пиктограммы, которая будет загружена. LookupIconIdFromDirectory возвращает целочисленный идентификатор, который является названием ресурса пиктограммы, которая лучше всего соответствует текущему устройству отображения.
Функции LoadIcon, LoadCursor и LoadImage (в Windows 95) используют эту функцию, чтобы найти заданные данные ресурса для пиктограммы или курсора, которые лучше всего соответствуют текущему устройству отображения.

Смотри также
CreateIconFromResource, CreateIconIndirect, FindResource, FindResourceEx, GetIconInfo, LoadCursor, LoadIcon, LoadImage, LookupIconIdFromDirectoryEx, MAKEINTRESOURCE

Размещение и совместимость LookupIconIdFromDirectory

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Уникод				Нет
Замечания по платформе		Не имеется


8.10.1.12 - Функция LookupIconIdFromDirectoryEx

(ПодстановкаПиктограммыИзКаталогаРасширеная)

[Теперь поддерживается Windows NT]

Функция LookupIconIdFromDirectoryEx ищет среди пиктограмм или курсоров данные, которые лучше всего соответствует текущему устройству отображения.

Синтаксис

int LookupIconIdFromDirectoryEx
(
    PBYTE presbits,	// адрес данных ресурса
    BOOL fIcon,	// флажок пиктограммы или курсора
    int cxDesired,	// желаемая ширина пиктограммы или курсора
    int cyDesired,	// желаемая высота пиктограммы или курсора
    UINT Flags	// флажки ресурса
);

Параметры
presbits
Указывает на каталог данных пиктограммы или курсора. Так как эта функция не проверяет правильность данных ресурса, она может стать причиной ошибки общей защиты (GP) или возвращает неопределенное значение, если presbits указывает на не допустимые данные ресурса.
fIcon
Определяет, что разыскиваются, пиктограмма или курсор. Если этот параметр - ИСТИНА (TRUE), функция ищет пиктограмму; если параметр - ЛОЖЬ (FALSE), функция ищет курсор.
cxDesired
Определяет желаемую ширину пиктограммы, в пикселях. Если этот параметр нулевой, функция использует метрическое значение системы SM_CXICON или SM_CXCURSOR.
cyDesired
Определяет желаемую высоту пиктограммы, в пикселях. Если этот параметр нулевой, функция использует метрическое значение системы SM_CYICON или SM_CYCURSOR.
Flags
Определяет комбинацию следующих значений:

Флажок 			Что он означает
LR_DEFAULTCOLOR		Использует заданный по умолчанию формат цвета.
LR_MONOCHROME		Создает одноцветную пиктограмму или курсор.

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

Замечания
Файл ресурса типа RT_GROUP_ICON (RT_GROUP_CURSOR обозначает курсоры) содержит данные о пиктограмме (или курсоре) в нескольких аппаратно-зависимых и не зависящих от устройства форматах. LookupIconIdFromDirectoryEx ищет файл ресурса пиктограммы (или курсора), который лучше всего соответствует текущему устройству отображения и возвращает целочисленный идентификатор. Функции FindResource и FindResourceEx используют макрокоманду MAKEINTRESOURCE с этим идентификатором, чтобы определить ресурс в модуле.
Каталог пиктограммы загружается из файла ресурса с типом ресурса RT_GROUP_ICON (или RT_GROUP_CURSOR для курсоров) и целочисленным значением названия ресурса для конкретной пиктограммы, которая будет загружена. Функция LookupIconIdFromDirectoryEx возвращает целочисленный идентификатор, который является названием ресурса пиктограммы, которая лучше всего соответствует текущему устройству отображения.
Функции LoadIcon, LoadImage и LoadCursor используют эту функцию, чтобы найти данные заданного ресурса для пиктограммы или курсора, который лучше всего соответствует текущему устройству отображения.

Смотри также
CreateIconFromResourceEx, CreateIconIndirect, FindResource, FindResourceEx, GetIconInfo, LoadCursor, LoadIcon, LoadImage, LookupIconIdFromDirectory, MAKEINTRESOURCE

Размещение и совместимость LookupIconIdFromDirectoryEx

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Уникод				Нет
Замечания по платформе		Не имеется


8.10.2 - Структуры пиктограмм

Нижеследующие структуры используются с пиктограммами.
ICONINFO
ICONMETRICS


8.10.2.1 - Структура ICONINFO

Структура ICONINFO содержит информацию о пиктограмме или курсоре.

Синтаксис

typedef struct _ICONINFO
{
    BOOL fIcon;
    DWORD xHotspot;
    DWORD yHotspot;
    HBITMAP hbmMask;
    HBITMAP hbmColor;
} ICONINFO;

Члены структуры
fIcon
Устанавливает, что определяет эта структура, пиктограмму или курсор. Значение ИСТИНА (TRUE) определяет пиктограмму; ЛОЖЬ (FALSE) определяет курсор.
xHotspot
Определяет x-координату острия ("горячей точки") курсора. Если эта структура определяет пиктограмму, острие - всегда в центре пиктограммы, а этот член игнорируется.
yHotspot
Определяет y-координату острия ("горячей точки") курсора. Если эта структура определяет пиктограмму, острие - всегда в центре пиктограммы, а этот член игнорируется.
hbmMask
Устанавливает точечный рисунок битовой маски пиктограммы. Если эта структура определяет черно-белую пиктограмму, эта битовая маска оформляется так, чтобы верхняя половина была битовая маска AND пиктограммы, а нижняя половина - битовая маска XOR пиктограммы. При этом условии, высота должна быть четной множителю два. Если эта структура определяет цветную пиктограмму, эта маска определяет только битовую маску AND пиктограммы.
hbmColor
Идентифицирует битовый образ цвета пиктограммы. Этот член может быть необязательный, если эта структура определяет черно-белую пиктограмму. Битовая маска AND члена структуры hbmMask применяется с флажком SRCAND по назначению; впоследствии, битовый образ цвета применяется (используя XOR) по назначению при помощи использования флажка SRCINVERT.

Смотри также
CreateIconIndirect, GetIconInfo

Размещение и совместимость ICONINFO

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Уникод				Нет
Замечания по платформе		Не имеется


8.10.2.2 - Структура ICONMETRICS

Структура ICONMETRICS содержит масштабируемую метрику, связанную с пиктограммами. Эта структура используется функцией SystemParametersInfo, когда определяется действие SPI_GETICONMETRICS или SPI_SETICONMETRICS.

Синтаксис

typedef struct tagICONMETRICS {
    UINT cbSize;
    int iHorzSpacing;
    int iVertSpacing;
    int iTitleWrap;
    LOGFONT lfFont;
} ICONMETRICS, FAR *LPICONMETRICS;

Члены структуры
cbSize
Устанавливает размер структуры, в байтах.
iHorzSpacing и iVertSpacing
Горизонтальное и вертикальное пространство, в пикселях, для каждой распложенной пиктограммы.
iTitleWrap
Флажок переноса заголовка на новую строку. Если этот член не нуль, заголовки пиктограмм автоматически переходят на новую строку. Если этот член нулевой, заголовки, не переходят на новую строку.
lfFont
Устанавливает шрифт, который используется для заголовков пиктограммы.

Смотри также
SystemParametersInfo

Размещение и совместимость ICONMETRICS

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Уникод				WinNT
Замечания по платформе		Не имеется


8.10.3 - Сообщения пиктограмм

Пиктограммами используются следующие сообщения.
WM_ERASEBKGND
WM_ICONERASEBKGND
WM_PAINTICON


8.10.3.1 - Сообщение WM_ERASEBKGND

Прикладная программа отправляет сообщение WM_ERASEBKGND, когда фон окна должен быть стерт (например, когда окно изменяет размеры). Сообщение отправляется, чтобы приготовить аннулированную часть окна для перекрашивания.

Синтаксис

WM_ERASEBKGND
hdc = (HDC) wParam; // дескриптор контекста устройства

Параметры
hdc
Значение wParam. Идентифицирует контекст устройства.

Возвращаемые значения
Прикладная программа должна возвратить значение отличное от нуля, если оно стирает фон; иначе, оно должно возвратить нуль.

Замечания
Функция DefWindowProc стирает фон при помощи использования кисти фона класса, определяемого членом hbrBackground структуры WNDCLASS. Если hbrBackground имеет значение ПУСТО (NULL), прикладная программа должна обработать сообщение WM_ERASEBKGND и стереть фон.
Прикладная программа должна возвратить значение отличное от нуля в ответ на WM_ERASEBKGND, если она обрабатывает сообщение и стирает фон; это означает, что никакое дальнейшее стирание не требуется. Если программа возвращает нуль, окно останется отмеченным для очистки. (Обычно, это обозначает, что элемент fErase структуры PAINTSTRUCT будет ИСТИНА (TRUE).)

Смотри также
BeginPaint, DefWindowProc, PAINTSTRUCT, WM_ICONERASEBKGND, WNDCLASS

Размещение и совместимость WM_ERASEBKGND

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Уникод				Нет
Замечания по платформе		Не имеется


8.10.3.2 - Сообщение WM_ICONERASEBKGND

Сообщение WM_ICONERASEBKGND отправляется в свернутое окно, когда фон пиктограммы должен быть заполнен перед рисованием её. Окно получает это сообщение, только в том случае, если для окна определена пиктограмма класса; иначе, посылается WM_ERASEBKGND.

Синтаксис

WM_ICONERASEBKGND
hdc = (HDC) wParam; // дескриптор контекста устройства

Параметры
hdc
Значение wParam. Идентифицирует контекст устройства пиктограммы.

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

Замечания
Функция DefWindowProc заполняет фон пиктограммы кистью фона класса родительского окна.

Смотри также
DefWindowProc, WM_ERASEBKGND

Размещение и совместимость WM_ICONERASEBKGND

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	-
Заголовочный файл			winuser.h
Уникод					Нет
Замечания по платформе		Не имеется


8.10.3.3 - Сообщение WM_PAINTICON

Сообщение WM_PAINTICON отправляется в свернутое окно, когда должна быть изображена пиктограмма, но только в том случае, если прикладная программа, написана для Windows 3.x. Окно получает это сообщение, только в том случае, если для окна определена пиктограмма класса; иначе, вместо него посылается WM_PAINT.

Синтаксис

WM_PAINTICON

Параметры
У этого сообщения нет параметров.

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

Замечания
Функция DefWindowProc рисует пиктограмму класса. Для совместимости с Windows 3.x, wParam должен быть ИСТИНА (TRUE). Однако это значение не имеет никакого значения.

Смотри также
DefWindowProc, WM_ICONERASEBKGND, WM_PAINT

Размещение и совместимость WM_PAINTICON

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Уникод				Нет
Замечания по платформе		Не имеется
Предыдущий Шаг


Глава 4 - Библиотека стандартных диалоговых окон

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

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

Следующий Шаг


4.1 - Об общих диалоговых окнах

Этот краткий обзор описывает стандартные диалоговые окна и объясняет, как использовать их в прикладных программах, разработанных при помощи Microsoft ® Win32 ® API. Стандартные диалоговые окна включают в себя диалоговые окна работы с файлом Открыть (Open) и Сохранить как (Save As), редактирующие диалоговые окна Найти (Find) и Заменить (Replace), диалоговые окна для печати Печать (Print), Параметры Печати (Print Setup) и Параметры Страницы (Page Setup) и диалоговые окна Шрифт (Font) и Цвет(Color).

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

Начиная с версии 4.0 Windows NT ® Microsoft, поддержка стандартных диалоговых окон - та же самая, что и в Windows ® 95 Microsoft.


4.2 - Типы Диалоговых окон

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

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

Цвет (Color) Показывает доступные цвета и позволяет пользователю создавать необязательные дополнительные цвета. Пользователь может выбирать основной или дополнительный цвет. Используется функция ChooseColor и структура CHOOSECOLOR.

Найти (Find) Показывает диалоговое окно, в котором пользователь может вводить с клавиатуры строку для поиска. Пользователь может также устанавливать параметры поиска, такие как направление поиска и поиск по принципу чувствительности к регистру. Используется функция FindText и структура FINDREPLACE.

Шрифт (Font) Показывает списки доступных шрифтов, размеров (кеглей) в пунктах, и другие атрибуты шрифта, которые пользователь может выбирать. Используется функция ChooseFont и структура CHOOSEFONT.

Открыть (Open) Отображает на экране перечни дисков, каталогов и имен файлов с расширением, из которых пользователь может выбрать для показа список имен файлов. Пользователь может ввести с клавиатуры имя файла или выбрать его из списка, который определяет файлы предназначенные для открытия. Используется функция GetOpenFileName и структура OPENFILENAME.

Печать (Print) Показывает на экране информацию об установленном принтере и его конфигурации. Пользователь может выбирать параметры задания по выводу на печать, такие как диапазон страниц для печати и число копий и запускать процесс печатания. Используется функция PrintDlg и структура PRINTDLG.

Параметры страницы (Page Setup) Показывает на экране конфигурацию текущей страницы. Пользователь может выбирать параметры конфигурации страницы, такие как ориентация бумаги, размер, источник и поля. Используется функция PageSetupDlg и структура PAGESETUPDLG.

Заменить (Replace) Показывает диалоговое окно, в котором пользователь может ввести с клавиатуры строку, которую надо найти и строку замены. Пользователь может устанавливать параметры поиска, такие как, является ли поиск чувствительным к регистру и параметры замены, такие как область замены. Используется функция ReplaceText и структура FINDREPLACE.

Сохранить как (Save As) Показывает списки дисков, каталогов и имен файлов с расширениями, из которых пользователь может выбрать для показа список имен файлов. Пользователь может ввести с клавиатуры имя файла или выбрать его из списка, чтобы определить имя под которым сохранится файл. Используется функция GetSaveFileName и структура OPENFILENAME.

Замечание: Хотя диалоговое окно Параметры печати (Print Setup) тоже доступно, оно было заменено диалоговым окном Параметры страницы (Page Setup). Новые прикладные программы, написанные для Windows 95 или Windows NT версии 3.51 или позже как правило должны использовать диалоговое окно Параметры страницы (Page Setup), а не диалоговое окно Параметры печати (Print Setup).

Все стандартные диалоговые окна модальные, за исключением диалоговых окон Найти (Find) и Заменить (Replace). Модальные диалоговые окна должны быть закрыты пользователем до того, как функция, используемая, чтобы создать диалоговое окно, сможет возвратить значение. Диалоговые окна Найти (Find) и Заменить (Replace) немодальные; функция возвращает значение перед закрытием блока диалога. Если вы используете диалоговые окна Найти (Find) и Заменить (Replace), вы должны тоже использовать функцию IsDialogMessage в основном цикле обработки сообщений вашей прикладной программы, чтобы гарантировать, что эти диалоговые окна правильно обрабатывают ввод данных с клавиатуры, таких как клавиши TAB и ESC.


4.3 - Флажки инициализации стандартных диалоговых окон

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

Например, вы устанавливаете значение CF_EFFECTS в элементе Flags структуры CHOOSEFONT, чтобы предписать диалоговому окну Шрифт (Font) показывать на экране набор элементов управления. Эти средства управления позволяют пользователю выбирать цвет логического шрифта, а также использовать эффекты перечеркивания и подчеркивания.

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


4.4 - Настройки стандартного диалогового окна

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

В этом разделе обсуждаются следующие методы настройки общего диалогового окна:

  1. Обеспечение настроек шаблона блока диалога, который определяет, дополнительные элементы управления или изменяет стандартные средства управления
  2. Создание фильтра (hook), чтобы контролировать и фильтровать сообщения, пересылаемые в процедуру диалогового окна
  3. Использование зарегистрированных сообщений, чтобы принимать или передавать информацию в диалоговое окно
  4. Обеспечение поддержки справки для стандартного диалогового окна


4.5 - Настройка шаблонов

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

Для всех общих диалоговых окон за исключением диалоговых окон в стиле Проводника (Explorer-style) Открыть (Open ) и Сохранить как (Save As), вы изменяете заданный по умолчанию шаблон, чтобы создать пользовательский шаблон, который заменит заданный по умолчанию. Пользовательский шаблон определяет тип и позицию стандартных элементов управления также как и любых дополнительных элементов управления.

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

Тип диалогового окна				Файл шаблона	Включаемый файл
Цвет (Color)					COLOR.DLG		COLORDLG.H
Найти (Find)					FINDTEXT.DLG	DLGS.H
Шрифт (Font)					FONT.DLG		DLGS.H
Открыть (Open) (многократный выбор)			FILEOPEN.DLG	DLGS.H
Открыть (Open) (однократный выбор)			FILEOPEN.DLG	DLGS.H
Параметры страницы (Page Setup)			PRNSETUP.DLG	DLGS.H
Печатать (Print)					PRNSETUP.DLG	DLGS.H
Параметры печати (Print Setup) (устаревший)		PRNSETUP.DLG	DLGS.H
Заменить (Replace)					FINDTEXT.DLG	DLGS.H

Чтобы включить пользовательский шаблон, вы должны установить флажок в элементе Flags соответствующей структуры для диалогового окна. Если шаблон - ресурс в прикладной программе или в динамически компонуемой библиотеке, установите флажок ENABLETEMPLATE в элементе Flags, а элементы структуры hInstance и lpTemplateName используйте, чтобы идентифицировать имя ресурса и модуль. Если шаблон уже в памяти, установите флажок ENABLETEMPLATEHANDLE в элементе Flags и используйте элемент hInstance, чтобы идентифицировать объект памяти, который содержит шаблон.

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

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


4.6 - Фильтр (hook) - процедуры для общих диалоговых окон

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

1. Стандартный фильтр (hook) - процедура, используется с наиболее общими диалоговыми окнами

2. Фильтр (hook) - процедура, поддерживающая диалоговые окна Открыть (Open) и Сохранить как (Save As) в стиле Проводника

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

  • WM_INITDIALOG - Заданная по умолчанию процедура диалогового окна обрабатывает сообщение перед передачей его в фильтр - процедуру. Параметр сообщения lParam является указателем на структуру инициализации, определяя, когда диалоговое окно было создано.
  • Все другие сообщения - Фильтр - процедура сначала принимает сообщение. Затем, возвращаемое значение фильтр(hook) - процедуры определяет, обрабатывает ли заданная по умолчанию процедура сообщение диалогового окна или она игнорирует его.

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

Чтобы включить фильтр - процедуру, установите значение ENABLEHOOK в элементе Flags соответствующей структуры для диалогового окна. Если флажок ENABLEHOOK установлен, элемент lpfnHook структуры должен определить адрес фильтр - процедуры.

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

Тип общего диалогового окна						Фильтр - процедура
Цвет (Color)							CCHookProc
Найти или Заменить (Find or Replace)					FRHookProc
Шрифт (Font)							CFHookProc
Открыть или Сохранить как (Open or Save As) (стиль Проводника)		OFNHookProc
Открыть или Сохранить как (Open or Save As) (Старый стиль)		OFNHookProcOldStyle
Печатать (Print)							PrintHookProc
Параметры Страницы (Page Setup)					PageSetupHook

Для диалогового окна Параметры страницы (Page Setup), вы можете также определить фильтр - процедуру PagePaintHook. Это - специальная фильтр - процедура, которую вы можете использовать, чтобы настроить вид макета страницы, отображаемой диалоговым окном Page Setup.

Обратите внимание, что диалоговое окно Print Setup было заменено диалоговым окном Page Setup, которое должно использоваться новыми прикладными программами, написанными для Windows 95 или для Windows NT версии 3.51 или позже. Однако для совместимости с более ранними версиями Windows, функция PrintDlg продолжает поддерживать показ диалогового окна Print Setup. Вы можете дать фильтр - процедуру SetupHookProc для диалогового окна Параметры страницы (Page Setup).


4.7 - Сообщения стандартного диалогового окна

Общие диалоговые окна используют сообщения, чтобы информировать вашу оконную или фильтр - процедуру, когда происходят определенные события. Кроме того, имеются сообщения, которые вы можете пересылать в стандартное диалоговое окно, чтобы извлечь информацию или управлять поведением или видом диалогового окна. Этот раздел описывает сообщения стандартного диалогового окна, регистрируемые функцией RegisterWindowMessage, сообщения, используемые диалоговыми окнами Шрифт (Font) и Параметры страницы (Page Setup) и сообщения, используемые диалоговыми окнами в стиле Проводника Открыть (Open) и Сохранить как … (Save As).

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

  • COLOROKSTRING - Диалоговое окно Цвет (Color) посылает это сообщение фильтр - процедуре, когда пользователь выбирает цвет и щелкает мышью по кнопке OK. Фильтр - процедура может принять цвет или отклонить его и заставить диалоговое окно оставаться открытым.
  • FILEOKSTRING - Диалоговое окно Открыть (Open) или Сохранить как (Save As) посылает это сообщение фильтр - процедуре, когда пользователь выбирает имя файла и щелкает мышью по кнопке OK. Фильтр - процедура может принять имя файла или отклонить его и заставить диалоговое окно оставаться открытым. Для диалоговых окон в стиле Проводника Открыть (Open) и Сохранить как (Save As), это сообщение было заменено уведомительным сообщением CDN_FILEOK.
  • FINDMSGSTRING - Диалоговое окно Найти (Find) или Заменить (Replace) передает это сообщение оконной процедуре своего родительского окна, когда пользователь щелкает мышью по кнопке Искать дальше (Find Next), Заменить (Replace) или Заменить Все (Replace All), или закрывает диалоговое окно. Параметр сообщения lParam указывает на структуру FINDREPLACE, которая содержит информацию, введенную пользователем.
  • HELPMSGSTRING - Все стандартные диалоговые окна посылают это сообщение оконной процедуре своего родительского окна, когда пользователь щелкает мышью по кнопке Справка (Help). Для диалоговых окон в стиле Проводника Открыть (Open) и Сохранить как (Save As), это сообщение было заменено уведомительным сообщением CDN_HELP.
  • LBSELCHSTRING - Диалоговые окна Открыть (Open) или Сохранить как (Save As) передают это сообщение в фильтр - процедуру, когда пользователь изменяет выбор в окне со списком Имя файла (Filename). Для диалоговых окон в стиле Проводника Открыть (Open) и Сохранить как (Save As) это сообщение было заменено уведомительным сообщением CDN_SELCHANGE.
  • SETRGBSTRING - Фильтр - процедура может посылать это сообщение диалоговому окну Цвет (Color), чтобы установить выбор текущего цвета.
  • SHAREVISTRING - Диалоговое окно Открыть (Open) или Сохранить как (Save As) посылает это сообщение фильтр - процедуре, если происходит ошибка совместного доступа для выбранного файла, когда пользователь щелкает мышью по кнопке OK. Для диалоговых окон в стиле Проводника Открыть (Open) и Сохранить как (Save As) это сообщение было заменено уведомительным сообщением CDN_SHAREVIOLATION.

Некоторые стандартные диалоговые окна посылают и принимают другие сообщения окна. Фильтр - процедура для диалогового окна Шрифт (Font) может посылать любое из сообщений WM_CHOOSEFONT_* в диалоговое окно Шрифт (Font). Для получения дополнительной информации, см. Диалоговое окно Шрифт (Font). Диалоговое окно Page Setup, если вы включили фильтр - процедуру PagePaintHook, посылает сообщения WM_PSD_*. Для получения дополнительной информации, см. Диалоговое окно Параметры страницы (Page Setup).

Диалоговые окна в стиле Проводника Открыть (Open) и Сохранить как (Save As) поддерживают набор предопределенных сообщений. Они включают в себя уведомительные сообщения, передаваемые в форме сообщения WM_NOTIFY в вашу фильтр - процедуру, и сообщения, которые ваша фильтр - процедура может пересылать в диалоговое окно. Полный список этих сообщений, см. Фильтр - процедуры для стиля Проводника.


4.8 - Поддержка Справки

Стандартные диалоговые окна обеспечивают контекстно-зависимой Справкой стандартные средства управления диалоговым окном. Чтобы дать дополнительную справку для стандартного диалогового окна, вы можете показать кнопку Справка (Help) и обрабатывать создаваемые сообщения, когда пользователь щелкает мышью по этой кнопке. Кнопка Справка (Help) - добавление к заданной по умолчанию контекстно-зависимой Справке. Кнопка Справка (Help) полезна для описания общего предназначения диалогового окна, поскольку она применяется в вашей прикладной программе.


4.9 - Контекстно-зависимая Справка

Все стандартные диалоговые окна обеспечивают контекстно-зависимую Справку для стандартных средств управления диалоговым окном. Пользователь может показать Справку для индивидуальных элементов управления любым из следующих методов:

  1. Путем выбора элемента управления и нажатия клавиши F1
  2. Щелчком мыши по кнопке ? в области заголовка, а затем щелчком мыши по элементу управления
  3. Щелчком правой кнопки мыши над элементом управления

Если вы настраиваете диалоговое окно, при помощи добавления новых элементов управления, вы должны также расширить поддержку справки для этих средств управления, обрабатывая запросы о справке в фильтр - процедуре. Фильтр - процедура принимает следующие сообщения, когда пользователь запрашивает справку.

Действие пользователя				Сообщение
Пользователь щелкнул правой кнопкой мыши
над элементом управления. 				WM_CONTEXTMENU
Пользователь нажал на клавишу F1. 			WM_HELP
Пользователь щелкнул мышью по кнопке ? в
области заголовка окна, а затем щелкнул
мышью по элементу управления.			WM_HELP

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


4.10 - Кнопка Справка

Вы можете показать кнопку Справка (Help) в любом из стандартных диалоговых окон, устанавливая значение SHOWHELP в элементе Flags структуры инициализации для диалогового окна. Если вы показываете кнопку Справка (Help), вы должны обработать запрос пользователя о справке. Обработка может быть выполнена или в одной из оконных процедур вашей прикладной программы или в фильтр - процедуре для диалогового окна. Обычно, запрос о справке вы должны обрабатывать, вызывая функцию WinHelp.

Чтобы обработать сообщения справки в одной из ваших оконных процедур, вы должны получить идентификатор сообщения для строки, определенный значением HELPMSGSTRING и идентифицировать окно, которое принимает сообщения. Чтобы получить идентификатор сообщения, установите HELPMSGSTRING как параметр в вызываемой функции RegisterWindowMessage. Когда вы создаете стандартное диалоговое окно, используйте элемент hwndOwner структуры инициализации диалогового окна, чтобы идентифицировать окно, которое должно принять сообщения. Процедура диалогового окна посылает сообщение оконной процедуре всякий раз, когда пользователь выбирает кнопку Справка (Help).

Чтобы обрабатывать сообщения справки в фильтр - процедуре, вы должны обработать сообщение WM_COMMAND. Фильтр - процедура обеспечивает справку, если параметр wParam этого сообщения указывает, что пользователь нажал кнопку Справка (Help). Идентификатор кнопки Справка (Help) - константа pshHelp, определена в файле .

Фильтр - процедуры для стандартных диалоговых окон в стиле Проводника Открыть и Сохранить как, не принимают сообщения WM_COMMAND для кнопки Справка (Help). Вместо этого, диалоговое окно посылает уведомительное сообщение CDN_HELP фильтр - процедуре, когда нажата кнопка Справка (Help).


4.11 - Диалоговое окно Цвет

Диалоговое окно Цвет (Color) возвращает значения RGB цвета, выбранного пользователем. Пользователь может выбирать из набора основных цветов, определенных драйвером дисплея или из набора дополнительных цветов. Вы должны определить начальную установку дополнительных цветов, но вы можете дать возможность пользователям создавать свои собственные дополнительные цвета.

Вы создаете и показываете диалоговое окно Цвет (Color), инициализируя структуру CHOOSECOLOR и передавая параметры структуры в функцию ChooseColor.

Вы можете открыть часть диалогового окна Цвет (Color), чтобы показать основные и дополнительные цвета, из которых пользователь может выбирать, или можете полностью открыть диалоговое окно, чтобы показать дополнительные элементы управления, которые дают возможность пользователю создавать дополнительные цвета. Иллюстрация ниже показывает полностью открытое диалоговое окно Цвет (Color).

12_1.gif (14650 b)

Если пользователь щелкает мышью по кнопке OK, ChooseColor возвращает значение ИСТИНА (TRUE). Элемент rgbResult структуры CHOOSECOLOR содержит значения RGB цвета, выбранного пользователем. Значение цвета RGB устанавливает индивидуальную интенсивность красного, зеленого и синего цветов, которые создают выбранный цвет. Индивидуальные значения находятся в пределах от 0 до 255. Используйте макрокоманды GetRValue, GetBValue и GetGValue, чтобы извлечь индивидуальные значения цвета из RGB цвета.

Если пользователь отменяет диалоговое окно Цвет (Color) или происходит ошибка, ChooseColor возвращает значение ЛОЖЬ (FALSE>), а элемент rgbResult не определяется. Чтобы определять причину ошибки, вызовите функцию CommDlgExtendedError, чтобы получить расширенное значение ошибки.


4.12 - Основное и улучшенное диалоговые окна Цвет (Color)

Диалоговое окно Цвет (Color) имеет базисную версию и улучшенную модификацию. Базисная версия имеет элементы управления, которые показывают базисные и дополнительные цвета, из которых пользователь может выбирать. Улучшенная модификация включает базисные элементы управления и дополнительные, которые позволяют пользователю создавать дополнительные цвета. Базисная версия диалогового окна Цвет (Color) включает кнопку Определение дополнительных цветов (Define Custom Colors). Пользователь может щелкать мышью по этой кнопке, чтобы отобразить улучшенную версию. Вы можете дать указание диалоговому окну Цвет (Color), чтобы всегда показывать это улучшение, установив флажок CC_FULLOPEN в элементе Flags структуры CHOOSECOLOR. Чтобы запретить пользователю создание дополнительных цветов, вы можете установить флажок CC_PREVENTFULLOPEN, чтобы отключить кнопку Define Custom Colors.

13_1.gif (5459 b)

Основные цвета представляют собою выбор цветов, доступных на данном устройстве. Фактическое число отображаемых цветов определяется драйвером дисплея. Например, драйвер VGA показывает 48 цветов, а драйвера дисплея с черно-белым изображением показывает только 16.

Дополнительные цвета -это цвета, которые вы устанавливаете или которые создает пользователь. Когда вы создаете цветное диалоговое окно, вы должны использовать элемент lpCustColors структуры CHOOSECOLOR, чтобы установить начальные исходные значения для 16 дополнительных цветов. Если улучшенная версия диалогового окна Цвет (Color) открыта, пользователь может создавать дополнительный цвет одним из следующих методов:

  1. Перемещением курсора мыши в элементе управления цветом спектра и плавной регулировки яркости
  2. Вводя с клавиатуры значения красного, зеленого и синего (RGB) в полях редактирования Красный, Зеленый и Синий
  3. Вводя с клавиатуры значения оттенка, насыщенности и яркости (HSL) в редактируемые поля элементов управления Оттенок (Hue), Насыщенность (Sat), и Яркость (Lum)

Чтобы добавить новый дополнительный цвет в поддерживаемой цветовой гамме дисплея, пользователь может щелкнуть по кнопке Добавить дополнительные цвета (Add to Custom Colors). Это также заставляет диалоговое окно копировать значение RGB нового цвета в соответствующий элемент в массиве, указанном элементом lpCustColors. Чтобы сохранить новые дополнительные цвета между обращениями к функции ChooseColor, вы должны отвести статическую память для массива. Для получения дополнительной информации о цветовых моделях RGB и HSL, см. Цветовые модели, используемые диалоговым окном Цвет (Color).


4.13 - Настройка диалогового окна Цвет (Color)

Чтобы настроить диалоговое окно Цвет (Color), вы можете использовать любой из нижеследующих следующих методов:

  1. Установить значения в структуре CHOOSECOLOR, когда создаете диалоговое окно.
  2. Обеспечить пользовательским шаблоном.
  3. Обеспечить фильтром - процедурой.

Вы можете изменять вид и поведение диалогового окна Цвет (Color), устанавливая флажки в элементе Flags структуры CHOOSECOLOR. Например, вы можете установить флажок CC_SOLIDCOLOR, чтобы предназначить диалоговое окно для показа только плотных тонов. Чтобы заставить диалоговое окно первоначально выбрать цвет, отличающийся от черного, установите флажок CC_RGBINIT и определите цвет в элементе rgbResult.

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

Чтобы обеспечить пользовательским шаблоном для диалогового окна Цвет (Color)

  1. Создайте пользовательский шаблон, изменяя заданный по умолчанию шаблон, определяемый в файле COLOR.DLG. Идентификаторы элементов управления, используемые в заданном по умолчанию шаблоне диалогового окна Цвет (Color), определены в заголовочном файле COLORDLG.H.
  2. Используйте структуру CHOOSECOLOR, чтобы включить шаблон, как указано ниже:

Если ваш пользовательский шаблон - ресурс в прикладной программе или динамически компонуемой библиотеке, уставите флажок CC_ENABLETEMPLATE в элементе Flags. Используйте элементы структуры hInstance и lpTemplateName, чтобы идентифицировать модуль и имя ресурса.

Или

Если ваш пользовательский шаблон - уже в памяти, установите флажок CC_ENABLETEMPLATEHANDLE. Используйте элемент hInstance, чтобы идентифицировать объект памяти, который содержит шаблон.

Вы можете обеспечить диалоговое окно Цвет (Color) фильтром - процедурой CCHookProc. Фильтр - процедура может обрабатывать сообщения, пересылаемые в диалоговое окно. Она может также использовать зарегистрированные сообщения, которые управляют поведением диалогового окна. Если вы используете пользовательский шаблон, чтобы определить дополнительные средства управления, вы должны обеспечить фильтром - процедурой, чтобы обрабатывать вводимую информацию для ваших элементов управления.

Чтобы включить фильтр - процедуру для диалогового окна Цвет (Color)

1. Установите флажок CC_ENABLEHOOK в элементе Flags структуры CHOOSECOLOR.

В элементе lpfnHook определите адрес фильтра - процедуры.

После обработки сообщения WM_INITDIALOG, процедура диалогового окна посылает сообщение WM_INITDIALOG фильтру - процедуре. Параметр этого сообщения lParam - указатель на структуру CHOOSECOLOR, используемую, чтобы инициализировать диалоговое окно.

Диалоговое окно посылает зарегистрированное сообщение COLOROKSTRING фильтру - процедуре, когда пользователь щелкает мышью по кнопке OK. Фильтр - процедура может отклонить выбранный цвет и заставить диалоговое окно оставаться открытым, возвращая нуль, когда оно принимает это сообщение. Фильтр - процедура может заставить диалоговое окно выбрать специфический цвет, посылая зарегистрированное сообщение SETRGBSTRING диалоговому окну. Чтобы использовать эти зарегистрированные сообщения, вы должны передать константы COLOROKSTRING и SETRGBSTRING в функцию RegisterWindowMessage, чтобы получить идентификатор сообщения. Вы можете затем использовать идентификатор, чтобы обнаружить и обработать сообщения, посланные из диалогового окна, или посылать сообщения диалоговому окну.


4.14 - Цветовые модели, используемые диалоговым окном Цвет (Color)

Расширение дополнительными цветами диалогового окна Цвет (Color) позволяет пользователю установить цвет, используя значения RGB или HSL. Однако, структура CHOOSECOLOR использует только значения RGB, чтобы сообщать цвета, созданные или выбранные пользователем.

Цветовая модель RGB

Цветовая модель RGB используется, чтобы обозначить цвета для дисплеев и других устройств, которые излучают свет. Допустимые значения красного, зеленого и синего цвета располагаются в диапазоне от 0 до 255, где 0 указывает на минимум интенсивности, а 255 указывает на максимум интенсивности. Следующая иллюстрация показывает, как основные цвета красный, зеленый, и синий могут быть объединены, чтобы произвести четыре дополнительных цвета. (Для устройств отображения, черный цвет - это результат того, когда значения красного, зеленого и синего цветов установлены в 0. В технологии дисплея, черный цвет - это отсутствие всех цветов).

15_1.gif (2694 b)

Ниже перечислены восемь цветов и их связанные значения системе RGB.

Цвет 			Значения RGB
Красный (Red)		255, 0, 0
Зеленый (Green)		0, 255, 0
Синий (Blue)		0, 0, 255
Голубой (Cyan)		0, 255, 255
Фиолетовый (Magenta)	255, 0, 255
Желтый (Yellow)		255, 255, 0
Белый (White)		255, 255, 255
Черный (Black)		0, 0, 0

Windows сохраняет внутренние цвета как 32-разрядные значения RGB, которые имеют следующую шестнадцатеричную форму:

0x00bbggrr

Младший байт содержит значение для относительной интенсивности красного; второй байт содержит значение для зеленого и третий байт содержит значение для синего цвета. Старший байт должен быть нулевой.

Вы можете использовать RGB макрокоманду, чтобы получить значение RGB, основанное на определяемых интенсивностях для красных, зеленых и синих компонентов. Используйте макрокоманды GetRValue, GetBValue и GetGValue, чтобы извлечь индивидуальные цвета из значений цветов RGB.

Цветовая модель HSL

Диалоговое окно Цвет (Color) предоставляет средства управления для определения значений HSL. Следующая иллюстрация показывает управление цветовым спектром и плавной регулировкой яркости, которые появляются в диалоговом окне Цвет (Color). Иллюстрация также показывает диапазоны значений, которые пользователь может устанавливать с этими средствами управления.

15_2.gif (4823 b)

В диалоговом окне Цвет (Color), насыщенность и значения яркости должна быть в диапазоне 0 до 240, и значение оттенка должно быть в диапазоне 0 до 239.

Преобразование значений HSL в значения RGB

Процедура диалогового окна, данная в файле COMDLG32.DLL для диалогового окна Цвет (Color) содержит код, который преобразовывает значения HSL в соответствующие значения RGB. Ниже - несколько цветов и их связанные значения HSL и RGB.

Цвет 			Значения HSL	Значения RGB
Красный (Red)		(0, 240, 120)	(255, 0, 0)
Зеленый (Green)		(40, 240, 120)	(255, 255, 0)
Синий (Blue)		(80, 240, 120)	(0, 255, 0)
Голубой (Cyan)		(120, 240, 120)	(0, 255, 255)
Фиолетовый (Magenta)	(160, 240, 120)	(0, 0, 255)
Желтый (Yellow)		(200, 240, 120)	(255, 0, 255)
Белый (White)		(0, 0, 240)	(255, 255, 255)
Черный (Black)		(0, 0, 0)	(0, 0, 0)


4.15 - Диалоговое окно Шрифт (Font)

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

Вы создаете и показываете диалоговое окно Шрифт (Font), инициализируя структуру CHOOSEFONT и передавая ее в функцию ChooseFont.

Следующая иллюстрация показывает типичное диалоговое окно Шрифт (Font).

16_1.gif (18963 b)

Если пользователь щелкает мышью по кнопке OK, функция ChooseFont возвращает значение ИСТИНА (TRUE) и устанавливает элементы структуры LOGFONT, указанные элементом lpLogFont структуры CHOOSEFONT. Вы можете использовать структуру LOGFONT с функцией CreateFontIndirect, чтобы создать логический шрифт. Функция ChooseFont также устанавливает другие элементы CHOOSEFONT, чтобы обозначить выбор пользователя.

Если пользователь отменяет (закрывает) диалоговое окно Шрифт (Font), или происходит ошибка, ChooseFont возвращает значение ЛОЖЬ (FALSE) и содержание структуры LOGFONT не определяет. Вы можете определить причину ошибки, используя функцию CommDlgExtendedError, чтобы возвратить расширенное значение ошибки.


4.15.1 - Флажки инициализации диалогового окна Шрифт (Font)

Перед обращением к функции ChooseFont, - элемент Flags структуры CHOOSEFONT должен определить флажки CF_SCREENFONTS, CF_PRINTERFONTS или CF_BOTH, чтобы указать, должно ли диалоговое окно перечислять экранные шрифты, встроенные шрифты принтера или оба. Если вы определяете флажок CF_PRINTERFONTS или CF_BOTH, элемент hDC структуры CHOOSEFONT должен определять дескриптор контекста устройства для принтера.

Вы можете использовать элемент Flags, чтобы включить или отключить некоторые из элементов управления диалогового окна, и можете использовать элемент Flags вместе с другими элементами структуры CHOOSEFONT, чтобы управлять начальными значениями некоторых элементов управления.

Чтобы показать элементы управления, которые позволяют пользователю выбирать зачеркивание, подчеркивание и параметры цвета для шрифта

1. Установите флажок CF_EFFECTS. Вы можете использовать элемент rgbColors структуры CHOOSEFONT, чтобы определить начальный цвет шрифта.

Чтобы определить начальные значения элементов управления Шрифт (Font), Стиль Шрифта (Font Style), Размер (Size), Зачеркивание (Strikeout) и Подчеркивание (Underline) диалогового окна

1. Установите флажок CF_INITTOLOGFONTSTRUCT, чтобы использовать элементы структуры LOGFONT для установки начальных значений.

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

Чтобы инициализировать управляющий элемента Стиль Шрифта (Font Style) в определяемом имени стиля.

1. Установите флажок CF_USESTYLE и используйте элемент lpszStyle, чтобы определить имя стиля.

Чтобы показать клавишу Применить (Apply)

1. Установите флажок CF_APPLY и обеспечьте фильтр - процедурой, чтобы обработать сообщение WM_COMMAND для кнопки Применить (Apply). Фильтр - процедура может послать сообщение WM_CHOOSEFONT_GETLOGFONT диалоговому окну, чтобы извлечь адрес структуры LOGFONT, которая содержит текущие параметры для шрифта.

Чтобы показать клавишу Справка (Help)

1. Установите флажок CF_SHOWHELP. Элемент hwndOwner должен идентифицировать окно, которое принимает зарегистрированное сообщение HELPMSGSTRING, когда пользователь щелкает мышью по кнопке Help.

Чтобы ограничить показ шрифтов диалогового окна

1. Установите любую комбинацию флажков CF_TTONLY, CF_FIXEDPITCHONLY, CF_NOVECTORFONTS, CF_NOVERTFONTS, CF_SCALABLEONLY и CF_WYSIWYG. Вы можете также ограничивать доступные стили, размеры в пунктах и эффекты отображения для некоторых шрифтов диалогового окна, используя значение CF_NOSIMULATIONS.

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

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

2. Установите флажок CF_LIMITSIZE, чтобы ограничить пользователя установкой размера в пунктах в диапазоне, определяемом элементами nSizeMin и nSizeMax.

Ограничить или отключить комбинированный блок Набор символов (Scripts)

1. Установите флажок CF_NOSCRIPTSEL, чтобы отключить комбинированный блок Набор символов или установите флажок CF_SELECTSCRIPT, чтобы ограничить выбор в нем установленных наборов символов.


4.15.2 - Настройка диалогового окна Шрифт (Font)

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

Чтобы обеспечить пользовательским шаблоном диалоговое окно Шрифт (Font)

1. Создайте индивидуальный шаблон, изменив заданный по умолчанию, который определен в файле FONT.DLG. Идентификаторы элементов управления, используемые по умолчанию в шаблоне блока диалога Шрифт (Font), определены в DLGS.H файле.

2. Используйте структуру CHOOSEFONT, чтобы шаблону, как ниже перечислено, разрешить:

Если ваш пользовательский шаблон - ресурс в прикладной программе или динамически компонуемой библиотеке, установите флажок CF_ENABLETEMPLATE в элементе Flags. Используйте элементы hInstance и lpTemplateName структуры, чтобы идентифицировать имя ресурса и модуль.

-ИЛИ-

Если ваш пользовательский шаблон - уже в памяти, установите флажок CF_ENABLETEMPLATEHANDLE. Используйте элемент hInstance, чтобы идентифицировать объект памяти, который содержит шаблон.

Вы можете предоставить диалоговому окну Шрифт (Font) фильтр (hook) - процедуру CFHookProc. Фильтр (hook) - процедура может обрабатывать сообщения, переданные в диалоговое окно. Она также может передавать сообщения блоку диалога. Если вы используете пользовательский шаблон, чтобы определить дополнительные элементы управления, вы должны предоставить фильтр (hook) - процедуру, чтобы обрабатывать ввод данных для ваших элементов управления.

Чтобы включить фильтр (hook) - процедуру для диалогового окна Шрифт (Font)

1. Установите флажок CF_ENABLEHOOK в элементе Flags структуры CHOOSEFONT.

2. Определите адрес фильтр (hook) - процедуры в элементе lpfnHook.

После обработки сообщения WM_INITDIALOG, процедура диалогового окна передает сообщение WM_INITDIALOG фильтр (hook) - процедуре. Параметр lParam этого сообщения - указатель на структуру CHOOSEFONT, используемую, чтобы инициализировать диалоговое окно.

Фильтр (hook) - процедура может передавать сообщения WM_CHOOSEFONT_GETLOGFONT, WM_CHOOSEFONT_SETLOGFONT и WM_CHOOSEFONT_SETFLAGS блоку диалога, чтобы получать и устанавливать текущие значения и флажки диалогового окна.


4.16 - Диалоговые окна Открыть (Open) и Сохранить как (Save As)

Диалоговое окно Открыть (Open) позволяет пользователю, определить диск, каталог и имя файла или набора файлов, которые надо открыть. Вы создаете и показываете диалоговое окно Открыть (Open), инициализируя структуру OPENFILENAME и передавая структуру в функцию GetOpenFileName.

Диалоговое окно Сохранить как (Save As) позволяет пользователю, определить диск, каталог и имя файла, которые надо сохранить. Вы создаете и показываете диалоговое окно Save As, инициализируя структуру OPENFILENAME и передавая структуру в функцию GetSaveFileName.

Начиная с Windows 95 и Windows NT версии 4.0, имеется новая версия диалоговых окон Открыть (Open) и Сохранить как (Save As), которые обеспечивают функции интерфейса пользователя, являясь сходными с Проводником Windows. Однако, Win32 продолжает поддерживать диалоговые окна Открыть(Open) и Сохранить как (Save As) старого стиля для прикладных программ, которые должны поддерживать интерфейс пользователя, не противоречащий более ранними версиями Windows.

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

Иллюстрация ниже показывает типичное диалоговое окно Открыть (Open) в стиле Проводника.

19_1.gif (12491 b)

Иллюстрация ниже показывает типичное диалоговое окно Сохранить как (Save As) в стиле Проводника.

19_2.gif (7923 b)

Если пользователь определяет имя файла и щелкает мышью по кнопке OK, функция GetOpenFileName или GetSaveFileName возвращает значение ИСТИНА (TRUE). Буфер, указанный элементом lpstrFile структуры OPENFILENAME содержит полный путь и имя файла, определенное пользователем.

Если пользователь отменяет диалоговое окно Открыть (Open) или Сохранить как (Save As), или происходит ошибка, функция возвращает значение ЛОЖЬ (FALSE). Чтобы определять причину ошибки, вызовите функцию CommDlgExtendedError, чтобы извлечь расширенное значение ошибки. Если буфер lpstrFile слишком маленький, чтобы принять полное имя, CommDlgExtendedError возвращает FNERR_BUFFERTOOSMALL и первые 2 байта буфера, указанного элементом lpstrFile, приведенные к целочисленному значению, устанавливающему размер, требуемый, чтобы принять полное имя файла.

Диалоговые окна стиля Проводника доступны только 32-разрядным прикладным программам. 16-разрядные прикладные программы не могут использовать переключение (thunking), чтобы показать диалоговое окно в стиле Проводника.

Windows 95: 32-разрядные прикладные программы, которые используют диалоговые окна старого стиля, делают это, используя "переходник" (thunk). Это означает, что любой указатель, переданный вашей фильтр (hook) - процедуре - не устойчивая копия данных. Например, указатель OPENFILENAME, переданный в сообщении WM_INITDIALOG - не указывает на буфер, который вы первоначально определили. Если вы должны передать частные данные вашей фильтр (hook) - процедуре, отошлите ее в структуру и сохраните указатель на структуру в элементе lCustData структуры OPENFILENAME.


4.17 - Имена файлов и каталоги

Информация в этом разделе применяется для диалоговых окон Открыть (Open) и Сохранить как (Save As) как в стиле Проводника, так и в старом стиле.

Перед вызовом функции GetOpenFileName или GetSaveFileName, элемент lpstrFile структуры OPENFILENAME должен указывать на буфер, который примет имя файла. Элемент nMaxFile должен определять размер, в байтах (для версии ANSI) или символах (для версии Уникода), буфера lpstrFile.

Если пользователь задает имя файла и щелкает мышью по кнопке OK, диалоговое окно копирует выбранный диск, каталог и имя файла в буфер lpstrFile. Функция также устанавливает элементы nFileOffset и nFileExtension со смещением, в байтах или символах, с самого начала буфера для имени файла и для расширения имени файла, соответственно.

Чтобы извлечь только имя файла и расширение, установите элемент lpstrFileTitle так, чтобы он указывал на буфер, а в элементе nMaxFileTitle установите размер, в байтах (версия ANSI) или символах (версия Уникода), буфера. Или же, вы можете передать буфер lpstrFile при вызове функции GetFileTitle, чтобы получить отображение имени выбранного файла. Однако обратите внимание, что имя файла, которое GetFileTitle возвращает, включает в себя расширение только в том случае, если это является выбором пользователя для отображающихся имен файлов.

Диалоговое окно использует текущий каталог для процесса вызова в качестве начального каталога от которого отображаются файлы и каталоги. Используйте функции GetCurrentDirectory или SetCurrentDirectory, чтобы получить или изменить ваш текущий каталог. Чтобы определить другой начальный каталог без изменения вашего текущего каталога, используйте элемент lpstrInitialDir, для определения имени каталога. Диалоговое окно автоматически изменит ваш текущий каталог, когда пользователь выберет другой диск или каталог. Чтобы диалоговому окну запретить изменять ваш текущий каталог, установите флажок OFN_NOCHANGEDIR. Этот флажок не мешает пользователю изменять каталоги для поиска файла.

Чтобы определить заданное по умолчанию расширение имени файла, используйте элемент lpstrDefExt. Если пользователь задает имя файла, которое не имеет расширения, диалоговое окно добавляет свое заданное по умолчанию расширение. Если вы определяете заданное по умолчанию расширение, а пользователь определяет имя файла с другим расширением, диалоговое окно устанавливает флажок OFN_EXTENSIONDIFFERENT.

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

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

  • Диалоговое окно в стиле Проводника - Строки каталога и имени файла отделяются значением ПУСТО (NULL), с дополнительным символом NULL после последнего имени файла. Этот формат дает возможность диалоговым окнам в стиле Проводника возвращать длинные имена файла, которые включают пробелы.
  • Диалоговое окно старого стиля - Строки каталога и имени файла отделяются пробелами. Для имен файла с пробелами, функция использует короткие имена файлов.


4.18 - Фильтры

Информация в этой статье применяется к диалоговым окнам Открыть (Open) и Сохранить как (Save As) как старого стиля, так и в стиле Проводника.

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

Чтобы определить фильтры, установите элемент lpstrFilter структуры OPENFILENAME, чтобы указать на буфер, который содержит массив пар строк фильтра. Последняя строка в массиве должна сопровождаться дополнительным символом нуля.

Строка образца может быть комбинацией допустимых символов имени файла и звездочки (*). Звездочка - подстановочный знак, который представляет любую комбинацию допустимых символов в имени файла. Диалоговое окно показывает только те файлы, которые соответствуют образцу. Чтобы определить множество образцов для того же самого описания, вы должны использовать точку с запятой (;), чтобы отделять образцы. Обратите внимание, что пробелы в строке образца могут привести к непредвиденным результатам.

Следующий фрагмент кода определяет два фильтра. Фильтр с описанием "Источник" имеет два образца. Если пользователь выбирает этот фильтр, диалоговое окно показывает только файлы, которые имеют .C и .CXX расширения.

OPENFILENAME ofn;       // структура общего диалогового окна
ofn.lpstrFilter = "Source\0*.C;*.CXX\0All\0*.*\0"
ofn.nFilterIndex = 1;

Элемент nFilterIndex структуры OPENFILENAME определяет индекс, который указывает, какие фильтры первоначально использует диалоговое окно. Первый фильтр в буфере имеет индекс 1, второй 2, и так далее. Если пользователь изменяет фильтр при использовании диалогового окна, элемент nFilterIndex при возврате устанавливается в индекс выбранного фильтра.

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

Для диалоговых окон в стиле Проводника, заданное по умолчанию расширение может измениться, если пользователь выбирает другой фильтр. Если пользователь выбирает фильтр, у которого первый шаблон имеет форму *.xxx (то есть расширение не включает групповой символ), диалоговое окно использует xxx как заданное по умолчанию расширение. Это происходит, только в том случае, если вы определили заданное по умолчанию расширение в элементе lpstrDefExt структуры OPENFILENAME. Например, если пользователь выбирает фильтр " Source\0*.C; *.CXX\0 ", заданное по умолчанию расширение изменяется на "C". Однако, если бы вы определили фильтр как "Source\0*.C*\0", заданное по умолчанию расширение не изменилось бы, потому что расширение включает подстановочный знак.


4.19 - Проверка правильности Файла и Каталога

За исключением того что отмечено, информация в этой статье разделе применяется для диалогового окна Открыть(Open) и Сохранить как (Save As) как в стиле Проводника, так и в старом стиле.

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

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

Когда используется диалоговое окно Сохранить как (Save As), вы можете предписать диалоговому окну запросить у пользователя разрешение записать поверх существующего файла, установив флажок OFN_OVERWRITEPROMPT.

По умолчанию, диалоговое окно создает проверочный файл нулевой длины, чтобы определить, может ли новый файл быть создан в выбранном каталоге. Чтобы предотвращать создание этого проверочного файла, установите флажок OFN_NOTESTFILECREATE.

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

Если пользователь выбирает отмечаемый блок "только для чтения", диалоговое окно при возврате устанавливает флажок OFN_READONLY. Чтобы скрыть отмечаемый блок Открыть Как Только для Чтения (Open As Read Only), установите флажок OFN_HIDEREADONLY. Чтобы оградить диалоговое окно от возвращающихся имен существующих файлов, которые имеют признак "только для чтения", установите флажок OFN_NOREADONLYRETURN.

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


4.20 - Пользовательская настройка диалогового окна Открыть (Open) и Сохранить как (Save As)

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

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

Следующая таблица суммирует различия между этими двумя стилями.

Настройка 			Описание
Стиль Проводника
Подключаемая процедура		Фильтр - процедура принимает уведомительные сообщения, посланные из
                общего диалогового окна и сообщения для любых дополнительных средств управления,
                которые Вы определили, устанавливая шаблон дочернего блока диалога. Фильтр -
                процедура не принимает сообщения для стандартных элементов управления диалогового
                окна заданных по умолчанию.
Стиль Проводника
Пользовательский шаблон		Система использует пользовательский шаблон, чтобы создать дочернее диалоговое
                окно. Шаблон может определять дополнительные элементы управления, и может определить
                расположение группы стандартных элементов управления. Пользовательский шаблон не
                заменяет шаблон заданный по умолчанию.
Старый стиль
Подключаемая процедура		Фильтр - процедура принимает все сообщения, пересылаемые в диалоговое окно,
                включая сообщения для стандартных элементов управления и любых пользовательских
                средств управления. А еще фильтр - процедура  принимает зарегистрированные сообщения,
                посланные из стандартного диалогового окна.
Старый стиль
Пользовательский шаблон		Пользовательский шаблон заменяет заданный по умолчанию шаблон. Создается
                пользовательский шаблон изменением заданного шаблона по умолчанию, определяемого в
                файле FILEOPEN.DLG.

Заданный по умолчанию заголовок диалогового окна и в стиле Проводника и в старом стиле является или "Открыть (Open)", или "Сохранить Как. (Save As)" Чтобы изменить заголовок, определите новый заголовок в элементе lpstrTitle структуры OPENFILENAME.


4.21 - Фильтр - процедуры для диалоговых окон в стиле Проводника

Вы можете настроить Диалоговое окно Открыть (Open) или Сохранить как (Save As) в стиле Проводника, при помощи предоставления фильтр - процедуры, пользовательского шаблона или вместе того и другого. Если Вы даете фильтр - процедуру для блока диалога в стиле Проводника, система создает диалоговое окно, которое является дочерним для заданного по умолчанию блока диалога. Фильтр - процедура действует как процедура диалогового окна для дочернего блока диалога. Это дочернее диалоговое окно базируется на пользовательском шаблоне или, если ни один не предоставлен, на шаблоне, заданном по умолчанию. Для получения дополнительной информации, см. статью Пользовательские шаблоны в стиле Проводника. Чтобы включить фильтр - процедуру для диалогового окна Открыть (Open) или Сохранить как (Save As) в стиле Проводника, используйте структуру OPENFILENAME, когда Вы создаете диалоговое окно. Установите флажки OFN_ENABLEHOOK и OFN_EXPLORER в элементе Flags, и определите адрес фильтр - процедуры OFNHookProc в элементе lpfnHook. Если Вы предоставляете фильтр - процедуру и не установили флажок OFN_EXPLORER, Вы должны использовать фильтр - процедуру OFNHookProcOldStyle и получите интерфейс пользователя в старом стиле. Для получения дополнительной информации, см. статью Настраивающиеся диалоговые окна в старом стиле.

Фильтр - процедура в стиле Проводника принимает разнообразные сообщения до тех пор, пока диалоговое окно открыто. Эти сообщения включают в себя:

  1. Сообщение WM_INITDIALOG и другие стандартные сообщения блока диалога типа WM_CTLCOLORDLG, которое является сообщением элемента управления цветом.
  2. Набор уведомительных сообщений WM_NOTIFY, которые указывают на действия, принимаемые пользователем или на другие события диалогового окна.
  3. Сообщения для любых дополнительных средств управления, которые Вы определили, устанавливая шаблон дочернего блока диалога.

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

Если Вы предоставляете фильтр - процедуру для блока диалога в стиле Проводника, заданная по умолчанию процедура диалогового окна создает дочерний блок диалога, когда заданная по умолчанию процедура диалогового окна обрабатывает сообщение WM_INITDIALOG. Фильтр - процедура действует как процедура диалогового окна для дочернего блока диалога. В это время, фильтр - процедура принимает собственное сообщение WM_INITDIALOG с параметром lParam установленным по адресу структуры OPENFILENAME, используемой, чтобы инициализировать блок диалога. После того, как дочернее диалоговое окно заканчивает обрабатывать собственное сообщение WM_INITDIALOG, заданная по умолчанию процедура диалогового окна перемещает стандартные средства управления, если необходимо, чтобы создать место для любых дополнительных средств управления дочернего диалогового окна. Заданная по умолчанию процедура диалогового окна затем посылает уведомительное сообщение CDN_INITDONE фильтр - процедуре.

Фильтр - процедура принимает уведомительные сообщения WM_NOTIFY, указывающие на действия, предпринимаемые пользователем в диалоговом окне. Вы можете использовать некоторые из этих сообщений, чтобы управлять поведением диалогового окна. Например, фильтр - процедура принимает сообщение CDN_FILEOK, когда пользователь выбирает имя файла и щелкает мышью по кнопке OK. В ответ на это сообщение, фильтр - процедура может использовать функцию SetWindowLong, чтобы отклонить выбранное имя и заставить диалоговое окно оставаться открытым.

Параметр lParam для каждого сообщения WM_NOTIFY - указатель на структуру OFNOTIFY, которая определяет действие. Кодовая группа в заголовке структуры OFNOTIFY содержит один из следующих кодов сообщения.

  • CDN_FILEOK - Пользователь щелкнул по кнопке OK; диалоговое окно собирается закрыться.
  • CDN_FOLDERCHANGE - Пользователь открыл новую папку или каталог.
  • CDN_HELP - Пользователь щелкнул по кнопке Справка.
  • CDN_INITDONE - Система закончила инициализировать диалоговое окно, а диалоговое окно закончило обрабатывать сообщение WM_INITDIALOG. А также, система закончила упорядочивать элементы управления в стандартном блоке диалога, чтобы создать место для элементов управления дочернего диалогового окна (если оно есть).
  • CDN_SELCHANGE - Пользователь выбрал новый файл или папку из списка файлов.
  • CDN_SHAREVIOLATION - Стандартное диалоговое окно столкнулось с нарушением правил совместного доступа к файлу, который собирается быть возвращенным.
  • CDN_TYPECHANGE - Пользователь выбрал новый тип файла из списка типов фалов.

Эти сообщения WM_NOTIFY заменяют зарегистрированные сообщения FILEOKSTRING, LBSELCHSTRING, SHAREVISTRING и HELPMSGSTRING, используемые предыдущими версиями Диалоговых окон Открыть (Open) и Сохранить как (Save As). Однако, фильтр - процедура также принимает замененное сообщение после сообщения WM_NOTIFY, если обработка WM_NOTIFY не использует SetWindowLong, чтобы установить значение DWL_MSGRESULT в отличное от нуля.

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

  • CDM_GETFILEPATH - Извлекает путь и имя файла выбранного файла.
  • CDM_GETFOLDERIDLIST - Извлекает список идентификаторов элемента, соответствующего текущей папке, которую диалоговое окно открыло. Для получения информации о списках идентификаторов элемента, см. статью Идентификаторы элемента и списки идентификаторов.
  • CDM_GETFOLDERPATH - Извлекает путь текущей папки или каталога в диалоговом окне.
  • CDM_GETSPEC - Извлекает имя (не, включая путь) текущего файла, выбранного в диалоговом окне.
  • CDM_HIDECONTROL - Скрывает заданный элемент управления.
  • CDM_SETCONTROLTEXT - Устанавливает текст в заданном элементе управления.
  • CDM_SETDEFEXT - Устанавливает в диалоговом окне заданное по умолчанию расширение имени файла.


4.22 - Пользовательские шаблоны в стиле Проводника

Чтобы определить дополнительные элементы управления для Диалогового окна Открыть (Open) или Сохранить как (Save As) в стиле Проводника, используйте структуру OPENFILENAME, чтобы задать шаблон для дочернего диалогового окна, которое содержит дополнительные элементы управления. Если ваш шаблон дочернего блока диалога - ресурс в прикладной программе или динамически компонуемой библиотеке, установите флажок OFN_ENABLETEMPLATE в элементе Flags и используйте элементы структуры hInstance и lpTemplateName, чтобы идентифицировать имя ресурса и модуль. Если шаблон уже в памяти, установите флажок OFN_ENABLETEMPLATEHANDLE и используйте элемент hInstance, чтобы идентифицировать объект памяти, который содержит шаблон. При обеспечении шаблона дочернего блока диалога для диалогового окна в стиле Проводника, Вы должны также установить флажок OFN_EXPLORER; иначе, система предположит, что Вы даете шаблон замены для диалогового окна старого стиля. Обычно, если Вы даете дополнительные средства управления, Вы должны также давать фильтр - процедуру в стиле Проводника для обработки сообщений новых элементов управления.

Вы можете создать свой шаблон дочернего диалогового окна также, как вы делаете любой другой шаблон, за исключением того, что вы можете определить стили WS_CHILD и WS_CLIPSIBLINGS и должны определить стили DS_3DLOOK и DS_CONTROL. Система требует стиля WS_CHILD, потому что ваш шаблон определяет дочерний блок диалога Открыть (Open) или Сохранить как (Save As) по умолчанию. Стиль WS_CLIPSIBLINGS гарантирует, что дочернее диалоговое окно не перерисовывает никакое из элементов управления в заданном по умолчанию диалоговом окне. Стиль DS_3DLOOK проверяет, что внешний вид элементов управления в дочернем диалоговом окне непротиворечиво элементам управления в заданном по умолчанию диалоговом окне. Стиль DS_CONTROL подтверждает, что пользователь может использовать клавишу TAB и другие клавиши передвижения, чтобы передвигаться между всеми элементами управления, созданными по умолчанию или пользовательскими, в пользовательском диалоговом окне.

Чтобы создать место для новых средств управления, система увеличивает заданное по умолчанию диалоговое окно в ширину и в высоту до габаритов пользовательского диалогового окна. По умолчанию, все элементы управления пользовательского диалогового окна устанавливаются ниже элементов управления в заданном по умолчанию диалоговом окне. Однако, Вы можете отменить эту заданную по умолчанию позицию при помощи включения статического текстового элемента управления в вашем шаблоне пользовательского диалогового окна и определить значение этого идентификатора элемента управления как stc32. (Это значение определено в заголовочном файле DLG.H.) В этом случае, система использует элемент управления как точку отсчета для определения, где установить новые элементы управления. Все новые средства управления stc32 устанавливаются выше и слева от элементов управления в том же самом количестве, выше и слева от средств управления в заданном по умолчанию диалоговом окне. Новые средства управления ниже и справа от элемента управления stc32 устанавливаются ниже и справа от заданных по умолчанию средств управления. Вообще, каждый новый элемент управления устанавливается так, чтобы оно имело ту же самую позицию относительно заданных по умолчанию средств управления такую же, какую он имел бы как элемент управления stc32. Чтобы создать место для этих новых средств управления, система добавляет пространство слева, справа, в нижней и верхней части заданного по умолчанию диалогового окна, сколько необходимо.

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

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


4.23 - Идентификаторы элементов управления в стиле Проводника

Win32 SDK обеспечивает шаблоном заданного по умолчанию диалогового окна для диалоговых окон старого стиля, но он не включает в себя шаблон заданного по умолчанию диалогового окна в силе Проводника. Это потому, что диалоговые окна в стиле Проводника позволяют вам добавлять ваши собственные средства управления, но не поддерживают изменение шаблона для стандартных средств управления. Однако, в некоторых случаях, вам возможно необходимо знать идентификаторы элементов управления, используемых в заданных по умолчанию шаблонах. Например, сообщения CDM_HIDECONTROL и CDM_SETCONTROLTEXT требуют идентификатора элемента управления.

Следующая таблица показывает идентификаторы стандартных элементов управления диалоговых окон Открыть (Open) и Сохранить как (Save As) в стиле Проводника. Идентификаторы - это константы, определенные в файлах DLGS.H и WINUSER.H.

  • cmb2 - Поле с раскрывающимся списком, которое показывает текущий диск или папку и позволяет пользователю выбрать диск или папку, которые надо открыть
  • stc4 - Метка для комбинированного блока cmb2
  • lst1 - Окно списка, которое показывает содержание текущего диска или папки
  • stc1 - Метка для окна списка lst1
  • edt1 - Редактируемое поле, которое показывает имя текущего файла, или в который пользователь может вводить с клавиатуры имя файла, для его открытия
  • stc3 - Метка для редактируемого поля edt1
  • cmb1 - Поле с раскрывающимся списком, которое показывает список фильтров типов файлов
  • stc2 - Метка для поля с раскрывающимся списком cmb1
  • chx1 - Отмечаемый блок только для чтения
  • IDOK - Кнопка управления OK (командная кнопка)
  • IDCANCEL - Кнопка управления Cancel (командная кнопка)
  • pshHelp - Кнопка управления Help (командная кнопка)


4.24 - Настройка диалоговых окон старого стиля

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

Чтобы включить фильтр - процедуру для диалогового окна Открыть (Open) или Сохранить как (Save As) старого стиля, используйте структуру OPENFILENAME, когда вы создаете диалоговое окно. В элементе Flags установите флажок OFN_ENABLEHOOK, а в элементе lpfnHook установите адрес фильтр - процедуры OFNHookProcOldStyle. Процедура диалогового окна посылает фильтр - процедуре сообщение WM_INITDIALOG с параметром lParam, который устанавливает адрес структуры OPENFILENAME, используемой, чтобы инициализировать диалоговое окно.

Вы можете использовать структуру OPENFILENAME, чтобы определить пользовательский шаблон для диалогового окна Открыть (Open) или Сохранить как (Save As), используя вместо заданного по умолчанию шаблона. Если ваш пользовательский шаблон - ресурс в прикладной программе или динамически компонуемой библиотеке, в элементе Flags установите флажок OFN_ENABLETEMPLATE и используйте элементы структуры hInstance и lpTemplateName, чтобы идентифицировать имя ресурса и модуль. Если ваш пользовательский шаблон - уже в памяти, установите флажок OFN_ENABLETEMPLATEHANDLE и используйте элемент hInstance, чтобы идентифицировать объект памяти, который содержит шаблон. Создайте пользовательский шаблон, изменяя заданный по умолчанию шаблон, определяемый в файле FILEOPEN.DLG. Идентификаторы элементов управления, используемые по умолчанию в шаблоне блока диалога Найти (Find) и Заменить (Replace), определены в файле DLGS.H.

По умолчанию, функции GetOpenFileName и GetSaveFileName показывают диалоговые окна в стиле Проводника. Если вы желаете показать диалоговое окно старого стиля, то должны предоставить фильтр - процедуру OFNHookProcOldStyle и гарантировать, чтобы флажок OFN_EXPLORER не был установлен в элементе Flags структуры OPENFILENAME.

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


4.25 - Диалоговое окно Печать… (Print)

Диалоговое окно Печать (Print) позволяет пользователю выбирать параметры для отдельного задания по выводу на печать. Например, пользователь может определить принтеру для использования, размер страниц для печати и тираж.

Вы создаете и показываете диалоговое окно Печатать (Print), инициализируя структуру PRINTDLG и передавая структуру в функцию PrintDlg.

Следующая иллюстрация показывает типичное диалоговое окно Печатать (Print).

28_1.gif (19733 b)

Если пользователь щелкает мышью по кнопке OK, функция PrintDlg возвращает значение ИСТИНА (TRUE) и использует структуру PRINTDLG, чтобы возвратить информацию о выборе пользователя. Например, элементы hDevMode и hDevNames обычно возвращают глобальные дескрипторы памяти для структур DEVMODE И DEVNAMES. Вы можете использовать информацию в этих структурах, чтобы создать контекст устройства или информационный контекст для выбранного принтера.

Если пользователь отменяет диалоговое окно Печатать (Print) или происходит ошибка, PrintDlg возвращает значение ЛОЖЬ (FALSE). Вы можете определить причину ошибки, используя функцию CommDlgExtendedError, чтобы извлечь расширенное значение ошибки.

Диалоговое окно Печатать (Print) включает в себя группу радио-кнопок Диапазона Печати, которые указывают, желает ли пользователь печатать все страницы, определенное количество страниц, или только выбранный текст. Перед вызовом функции PrintDlg, Вы можете установить один из флажков PD_ALLPAGES, PD_SELECTION или PD_PAGENUMS, чтобы указать, которая кнопка первоначально выбрана. Когда PrintDlg возвращает значение ИСТИНА (TRUE), функция устанавливает один из этих флажков, чтобы указать выбор пользователя. Если установлен флажок PD_PAGENUMS, то элементы nFromPage и nToPage структуры PRINTDLG содержат начальные и конечные страницы, определенные пользователем. Чтобы отключить радио-кнопку Страницы (Pages) и связанные с ней "С: (From:)" и "По: (To:)" редактируемые поля, установите флажок PD_NOPAGENUMS. Чтобы отключать радио-кнопку Выделенный фрагмент (Selection), установите флажок PD_NOSELECTION.

Диалоговое окно включает в себя редактируемое поле, в котором пользователь может вводить с клавиатуры число копий для печати. Если элемент hDevMode структуры PRINTDLG не нулевой (не пустой), элемент dmCopies структуры DEVMODE определяет исходное значение для этого редактируемое поля. Если hDevMode имеет значение ПУСТО (NULL), элемент nCopies структуры PRINTDLG определяет начальное значение. Когда PrintDlg возвращает значение, nCopies обычно указывают количество копий, определяемых пользователем. Однако, если Вы устанавливаете флажок PD_USEDEVMODECOPIESANDCOLLATE, когда создаете диалоговое окно, nCopies всегда устанавливается в 1 при возврате, а элемент dmCopies стурктуры DEVMODE указывает количество копий для печати.

Отмечаемый блок Разобрать по копиям (Collate) указывает, желает ли пользователь сделать сортировку страниц по копиям, если печатается множество копий. Флажок PD_COLLATE устанавливается, если отмечаемый блок Разобрать по копиям (Collate) отмечен. Если ваша прикладная программа не поддерживает многочисленные копии или имитацию сортировки, установите флажок PD_USEDEVMODECOPIESANDCOLLATE в элементе Flags структуры PRINTDLG. Это отключит отмечаемый блок Разобрать по копиям (Collate) и редактируемое поле "Число копий: (Number of Copies)", если драйвер принтера не поддерживает многочисленные копии и сортировку.

Отмечаемый блок Печать в файл (Print To File) указывает, что пользователь желает послать вывод информации в файл, а не на принтер. Вы можете установить этот флажок PD_PRINTTOFILE, так чтобы изначально в отмечаемом блоке была проставлена "галочка". Чтобы скрыть отмечаемый блок, установите флажок PD_HIDEPRINTTOFILE. Чтобы отключить его, установите флажок PD_DISABLEPRINTTOFILE. Если пользователь выбирает параметр Print To File, функция PrintDlg устанавливает флажок PD_PRINTTOFILE и возвращает значение "ФАЙЛ: (FILE)" со смещением указывающим на элемент wOutputOffset структуры DEVNAMES. Когда вы вызываете функцию StartDoc, чтобы начать печать, определите эту строку "ФАЙЛ: (FILE)" в элементе lpszOutput структуры DOCINFO. Определение этой строки заставляет подсистему печати сделать запрос у пользователя об имени файла, куда выводить информацию.

По умолчанию, диалоговое окно Печать (Print) первоначально показывает информацию о текущем заданном по умолчанию принтере. Вы можете предписать ему, чтобы показать информацию для другого установленного принтера, инициализируя структуру DEVMODE или DEVNAMES и присваивая глобальный дескриптор памяти для структуры в элементе hDevMode или hDevNames. Имя устройства, которое Вы определяете в элементе dmDeviceName структуры DEVMODE или в элементе wDriverOffset структуры DEVNAMES, должно идентифицировать устройство принтера, которое также внесено в список в разделе [Devices] файла WIN.INI. Если устройство не внесено в список, PrintDlg возвращает ошибку.

Вы можете предписать функции PrintDlg, чтобы создать контекст устройства или информационный контекст для принтера, устанавливая флажок PD_RETURNDC или PD_RETURNIC в элементе Flags структуры PRINTDLG. Функция возвращает дескриптор контекста устройства или информационного контекста в элементе hDC. Если Вы используете флажок PD_RETURNDC, Вы можете использовать контекст устройства, чтобы сделать вывод информации на принтер.

Чтобы извлечь информацию о заданном по умолчанию принтере без показа её в диалоговом окне Печать (Print), установите флажок PD_RETURNDEFAULT. В этом случае, функция PrintDlg возвращает немедленно после установки в элементах hDevMode и hDevNames дескрипторов для структур, содержащих информацию.

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


4.26 - Настройки диалогового окна Печать (Print)

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

Чтобы дать пользовательский шаблон для диалогового окна Печать (Print)

1. Создайте пользовательский шаблон, изменяя заданный по умолчанию шаблон, определенный в файле PRNSETUP.DLG. Идентификаторы элементов управления, используемых в заданном по умолчанию шаблоне блока диалога Печать (Print) определены в файле DLGS.H.

2. Используйте структуру PRINTDLG, чтобы разрешить шаблону действия как ниже указано. Если ваш пользовательский шаблон - ресурс в прикладной программе или динамически компонуемой библиотеке, установите флажок PD_ENABLEPRINTTEMPLATE в элементе Flags. Используйте элементы hInstance и lpPrintTemplateName структуры, чтобы идентифицировать модуль и имя ресурса.

ИЛИ

1. Если ваш пользовательский шаблон - уже в памяти, установите флажок PD_ENABLEPRINTTEMPLATEHANDLE. Используйте элемент hPrintTemplate, чтобы идентифицировать объект памяти, который содержит шаблон.

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

Чтобы включить фильтр - процедуру для диалогового окна Печать (Print)

1. Установите флажок PD_ENABLEPRINTHOOK в элементе Flags структуры PRINTDLG.

2. Определите адрес фильтр - процедуры в элементе lpfnPrintHook.

После обработки сообщения WM_INITDIALOG, процедура диалогового окна посылает сообщение WM_INITDIALOG фильтр - процедуре. Параметр lParam этого сообщения - указатель на структуру PRINTDLG, используемую, чтобы инициализировать диалоговое окно.


4.27 - Диалоговое окно Установки для Печати (Print Setup)

Вы можете создать и показать диалоговое окно Установки для Печати (Print Setup), устанавливая флажок PD_PRINTSETUP при вызове функции PrintDlg. Однако, диалоговое окно Установки для печати (Print Setup) заменяется диалоговым окном Установки Страницы (Page Setup) и не должно использоваться в новых прикладных программах.

Ниже следующие флажки применяются только для диалогового окна Установки для Печати (Print Setup):

PD_ENABLESETUPHOOK
PD_ENABLESETUPTEMPLATE
PD_ENABLESETUPTEMPLATEHANDLE


4.28 - Диалоговое окно Параметры Страницы (Page Setup)

Диалоговое окно Параметры Страницы (Page Setup) позволяет пользователю устанавливать следующие отличительные признаки напечатанной страницы:

  1. Тип бумаги (конверт, формат 8,5х14 дюймов(legal), формат 10х14 дюймов (letter) и т. д.)
  2. Источник бумаги (ручная подача, непрерывная подача, устройство подачи бумаги по листам, и т. д.)
  3. Ориентация страницы (портретная или альбомная)
  4. Ширина полей страницы.

Атрибуты, представленные в диалоговом окне, изменяются в зависимости от возможностей принтера.

Вы создаете и показываете диалоговое окно Параметры Страницы (Page Setup), инициализируя структуру PAGESETUPDLG и передавая параметры структуры в функцию .

Если пользователь щелкает мышью по кнопке OK, PageSetupDlg возвращает значение ИСТИНА (TRUE) после установки различных элементов в структуре PAGESETUPDLG, чтобы определить выбор пользователя. Элементы ptPaperSize и rtMargin содержат значения, определяемые пользователем. Элементы hDevMode и hDevNames содержат глобальные дескрипторы памяти для структур DEVMODE и DEVNAMES. Эти структуры содержат дополнительную информацию о странице, также как и информацию о принтере. Вы можете использовать эту информацию, чтобы подготовить вывод данных, которые будут пересланы в выбранный принтер.

Следующая иллюстрация показывает вариант диалогового окна Параметры страницы (Page Setup).

31_1.gif (14028 b)

Если пользователь отменяет диалоговое окно Параметры страницы (Page Setup), или происходит ошибка, PageSetupDlg возвращает значение ЛОЖЬ (FALSE). Чтобы определить причину ошибки, вызовите функцию CommDlgExtendedError, чтобы возвратить расширенное значение ошибки.


4.29 - Инициализация диалогового окна Параметры страницы (Page Setup)

По умолчанию, диалоговое окно Параметры страницы (Page Setup) показывает информацию о текущем заданном по умолчанию принтере. Чтобы предписать диалоговому окну показать информацию об особенностях принтера, установите элементы структуры DEVMODE или DEVNAMES и присвойте глобальные дескрипторы памяти этих структур соответствующим элементам в PAGESETUPDLG. Если Вы определяете имя принтера, который в настоящее время не установлен, диалоговое окно показывает сообщение об ошибке. Чтобы запретить диалоговому окну отображать сообщения об ошибках, используйте значение PSD_NOWARNING. Чтобы извлечь информацию о заданном по умолчанию принтере без показа её в Диалоговом окне Параметры страницы (Page Setup), используйте значение PSD_RETURNDEFAULT.

Если заданная по умолчанию система мер - дюймы, диалоговое окно использует тысячные части дюймов как заданную по умолчанию единицу измерения. Если заданная по умолчанию система мер метрическая, диалоговое окно использует сотые миллиметра как заданные по умолчанию единицы измерения. Чтобы отменить заданную по умолчанию единицу измерения, установите флажок PSD_INHUNDREDTHSOFMILLIMETERS или PSD_INTHOUSANDTHSOFINCHES в элементе Flags структуры PAGESETUPDLG.

Начальные значения для полей, по умолчанию, один дюйм,. Если Вы устанавливаете флажок PSD_MARGINS, диалоговое окно показывает первоначальное значение поля страницы, определенное в элементе rtMargin. По умолчанию минимальное значение для полей, которое пользователь может установить - минимальные поля, допускаемые принтером. Если Вы устанавливаете флажок PSD_MINMARGINS, диалоговое окно обеспечивает минимальные поля, определенные в элементе rtMinMargin.

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

  • PSD_DISABLEMARGINS - Отключает редактируемые поля, в которые пользователь вводит с клавиатуры величину поля
  • PSD_DISABLEORIENTATION - Отключает радио-кнопки Книжная (Portrait) и Альбомная (Landscape) ориентация
  • PSD_DISABLEPAPER - Отключает элементы управления для выбора размера и источника бумаги
  • PSD_DISABLEPRINTER - Отключает командную кнопку Принтер


4.30 - Настройка диалогового окна Параметры страницы (Page Setup)

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

Чтобы предоставить пользовательский шаблон для диалогового окна Параметры страницы (Page Setup).

1. Создайте пользовательский шаблон, изменяя заданный по умолчанию шаблон, определенный в файле PRNSETUP.DLG. Идентификаторы элемента управления, используемые по умолчанию в шаблоне блока диалога Параметры страницы (Page Setup) определены в файле DLGS.H.

2. Используйте структуру PAGESETUPDLG, чтобы разрешить шаблону как ниже указано:

Если ваш пользовательский шаблон - ресурс в прикладной программе или динамически компонуемой библиотеке, установите флажок PSD_ENABLEPAGESETUPTEMPLATE в элементе Flags. Используйте элементы hInstance и lpPageSetupTemplateName структуры, чтобы идентифицировать имя ресурса и модуль.

ИЛИ

Если ваш индивидуальный шаблон уже в памяти, установите флажок PSD_ENABLEPAGESETUPTEMPLATEHANDLE. Используйте элемент hPageSetupTemplate, чтобы идентифицировать объект памяти, который содержит шаблон.

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

Чтобы включить фильтр - процедуру PageSetupHook

1. Установите флажок PSD_ENABLEPAGESETUPHOOK в элементе Flags структуры PAGESETUPDLG.

2. Определите адрес фильтр - процедуры в элементе lpfnPageSetupHook.

После обработки своего сообщения WM_INITDIALOG процедура диалогового окна посылает сообщение WM_INITDIALOG фильтр - процедуре PageSetupHook. Параметр lParam этого сообщения - указатель на структуру PAGESETUPDLG, используемую, чтобы инициализировать диалоговое окно.


4.31 - Настройка макета страницы

Диалоговое окно Параметры страницы (Page Setup) включает в себя изображение макета страницы, который показывается, как выбор пользователя воздействуют на вид распечатки выводимых данных. Изображение состоит из прямоугольника, который представляет собою выбранный тип бумаги или конверта, с прямоугольником пунктира, представляющим текущие поля, а неполные символы (греческий текст) показывают, как будет смотреться текст на напечатанной странице.

Когда Вы вызываете функцию PageSetupDlg, Вы можете предоставить фильтр - процедуру PagePaintHook, чтобы настроить вид макета страницы.

Чтобы разрешать действия фильтр - процедуре PagePaintHook.

1. Установите флажок PSD_ENABLEPAGEPAINTHOOK в элементе Flags структуры PAGESETUPDLG.

2. Установите адрес фильтр - процедуры в элементе lpfnPagePaintHook.

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

  • WM_PSD_PAGESETUPDLG - Диалоговое окно собирается сделать прорисовку макета страницы. Фильтр - процедура может использовать это сообщение, чтобы подготовиться к рисованию содержания макета страницы.
  • WM_PSD_FULLPAGERECT - Диалоговое окно собирается сделать прорисовку макета страницы. Это сообщение определяет границы прямоугольника макета страницы.
  • WM_PSD_MINMARGINRECT - Диалоговое окно собирается сделать прорисовку макета страницы. Это сообщение определяет прямоугольник поля страницы.
  • WM_PSD_MARGINRECT - Диалоговое окно собирается сделать прорисовку прямоугольника полей страницы.
  • WM_PSD_GREEKTEXTRECT - Диалоговое окно собирается сделать вывод греческого текста внутри прямоугольника полей страницы.
  • WM_PSD_ENVSTAMPRECT - Диалоговое окно собирается делать прорисовку в прямоугольнике макета страницы в виде конверта с маркой. Это сообщение посылается только для конвертов.
  • WM_PSD_YAFULLPAGERECT - Диалоговое окно собирается делать прорисовку в области адреса возврата в макете страницы в виде конверта. Это сообщение посылается для конвертов и других размеров бумаги.

Если фильтр - процедура возвращает значение ИСТИНА (TRUE) для любого из первых трех сообщений в порядке следования прорисовки (WM_PSD_PAGESETUPDLG, WM_PSD_FULLPAGERECT или WM_PSD_MINMARGINRECT) диалоговое окно больше не посылает сообщения и не прорисовывает макет страницы до тех пор, пока в следующий раз система не потребуется перерисовать макет страницы. Если фильтр - процедура возвращает ЛОЖЬ (FALSE) для всех этих трех сообщений, диалоговое окно посылает остающиеся сообщения в порядке следования прорисовки.

Если фильтр - процедура возвращает значение ИСТИНА (TRUE) для любого из остающихся сообщений в порядке следования прорисовки, диалоговое окно не выводит соответствующую часть макета страницы. Если фильтр - процедура возвращает значение ЛОЖЬ (FALSE) для любого из этих сообщений, диалоговое окно выводит эту часть макета страницы.

Чтобы не дать диалоговому окну рисовать содержание макетов страниц, вы можете установить флажок PSD_DISABLEPAGEPAINTING. Этот флажок не воздействует на вашу фильтр - процедуру PagePaintHook, которая все еще принимает все WM_PSD_* сообщения и может выводить содержание макета страницы.


4.32 - Диалоговые окна Найти (Find) и Заменить (Replace)

Диалоговое окно Найти (Find) позволяет пользователю определить последовательность символов для поиска, а также параметры для использования, когда делается поиск текста в документе. Диалоговое окно Заменить (Replace) позволяет пользователю определить последовательность символов для поиска и замены этой последовательностью, а также параметры для управления этой операцией.

Вы создаете и отображаете диалоговое окно Найти (Find),инициализируя структуру FINDREPLACE и предавая структуру в функцию FindText. Вы создаете и отображаете диалоговое окно Заменить (Replace),инициализируя структуру FINDREPLACE и предавая структуру в функцию ReplaceText.

Рисунок ниже показывает обычное диалоговое окно Найти (Find).

35_1.gif (7310 b)

Рисунок ниже показывает обычное диалоговое окно Заменить (Replace).

35_2.gif (8745 b)

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

Если функция FindText или ReplaceText успешно создают диалоговое окно, они возвращают значение дескриптора диалогового окна. Вы можете использовать этот дескриптор для перемещения и установки связи с диалоговым окном. Если функция не может создать диалоговое окно, она возвращает значение ПУСТО (NULL). Вы можете определить причину ошибки путем вызова функции CommDlgExtendedError, чтобы отыскать расширенное значение ошибки.


4.33 - Зарегистрированное сообщение FINDMSGSTRING

Перед созданием диалогового окна Найти (Find) или Заменить (Replace). Вы должны вызвать функцию RegisterWindowMessage, чтобы получить идентификатор зарегистрированного сообщения FINDMSGSTRING. Вы можете затем использовать этот идентификатор, чтобы определять и обрабатывать сообщения, посылаемые из диалогового окна. Когда пользователь щелкает мышью по кнопке диалогового окна Искать дальше… (Find Next), Заменить (Replace) или Заменить все (Replace All), процедура диалогового окна передает сообщение FINDMSGSTRING в оконную процедуру окна владельца. Когда вы создаете диалоговое окно, элемент hwndOwner структуры FINDREPLACE идентифицирует окно владельца.

Параметр lParam сообщения FINDMSGSTRING указывает на структуру FINDREPLACE, которую вы определили, когда создавали диалоговое окно. Перед передачей сообщения, диалоговое окно устанавливает элементы этой структуры с самыми последними введенными пользователем данными, включая последовательность символов для поиска, замены этой последовательности (если она имеется) и параметрами для операции поиска-замены.

В сообщении FINDMSGSTRING элемент Flags структуры FINDREPLACE включает в себя один из ниже перечисленных флажков, чтобы указать на событие, которое вызвало сообщение:

  • FR_DIALOGTERM - Диалоговое окно закрывается. После того как окно владелец обработает это сообщение, дескриптор диалогового окна далее не будет корректным.
  • FR_FINDNEXT - Пользователь щелкнул мышью по кнопке Искать дальше (Find Next) в диалоговом окне Найти (Find) или Заменить (Replace). Элемент lpstrFindWhat определяет последовательность символов для поиска.
  • FR_REPLACE - Пользователь щелкнул мышью по кнопке Заменить (Replace) в диалоговом окне Заменить (Replace). Элемент lpstrFindWhat устанавливает последовательность символов, которую надо заменить, а элемент lpstrReplaceWith устанавливает последовательность символов, на которую надо заменить.
  • FR_REPLACEALL - Пользователь щелкнул мышью по кнопке Заменить все (Replace All) в диалоговом окне Заменить (Replace). Элемент lpstrFindWhat устанавливает последовательность символов, которую надо заменить, а элемент lpstrReplaceWith устанавливает последовательность символов, на которую надо заменить.

Для сообщения Искать дальше (Find Next) или Заменить все (Replace All) элемент Flags может включать любую комбинацию ниже перечисленных флажков, которые указывают параметры поиска:

  • FR_DOWN - Если установлен, то из радио-кнопок направления выбрана кнопка До конца (Down), которая указывает, что пользователь желает искать от текущего положения каретки в тексте до конца документа. Если флажок FR_DOWN не установлен, выбрана кнопка Вверх (Up), что означает, что пользователь желает осуществлять поиск к началу документа.
  • FR_MATCHCASE - Если флажок установлен, в отмечаемом блоке С учетом регистра (Match Case) стоит галочка, показывая, что пользователь желает, чтобы поиск был чувствителен к регистру. Если FR_MATCHCASE не установлен, в отмечаемом блоке галочки нет, так что поиск должен быть не чувствительным к регистру.
  • FR_WHOLEWORD - Если флажок установлен, в отмечаемом блоке Соответствовать слову только целиком (Match Whole Word Only) стоит галочка, показывая, что пользователь желает осуществить поиск только для целого слова, которое соответствует поисковой последовательности символов. Если FR_WHOLEWORD не установлен, в отмечаемом блоке галочка не стоит, тогда вы должны также осуществлять поиск фрагмента слова, который соответствует поисковой последовательности символов.


4.34 - Настройка диалогового окна Найти (Find) или Заменить (Replace)

Чтобы настроить диалоговое окно Найти (Find) или Заменить (Replace), вы можете использовать любой из ниже перечисленных методов:

  1. Определить значения в структуре FINDREPLACE, когда создается диалоговое окно
  2. Снабдить индивидуальным шаблоном
  3. Предоставить фильтр - процедуру (ловушку)

Когда вы создаете диалоговое окно Найти (Find) или Заменить (Replace), вы можете установить флажки в элементе Flags структуры FINDREPLACE, чтобы скрыть или запретить работу любого из параметров поиска элементов управления. Например, вы можете установить флажок FR_NOMATCHCASE, чтобы запретить работу отмечаемого блока С учетом регистра (Match Case) или установить флажок FR_HIDEMATCHCASE, чтобы скрыть его.

Вы можете снабдить диалоговое окно Найти (Find) или Заменить (Replace) пользовательским шаблоном, к примеру, если вы захотите включить дополнительные элементы управления, которые присущи только вашей прикладной программе. Функции FindText и ReplaceText используют ваш пользовательский шаблон вместо шаблона по умолчанию.

Чтобы снабдить пользовательским шаблоном диалоговое окно Найти (Find) или Заменить (Replace)

1. Создайте индивидуальный шаблон, модифицируя шаблон по умолчанию, определенный в файле FINDTEXT.DLG. Идентификаторы элементов управления, используемые по умолчанию в шаблоне диалога Найти (Find) или Заменить (Replace), определены в файле DLGS.H

2. Чтобы разрешить работу шаблона, используйте структуру FINDREPLACE, как указано ниже:

Если ваш пользовательский шаблон - ресурс в прикладной программе или динамически компонуемой библиотеки, установите флажок FR_ENABLETEMPLATE в элементе Flags. Используйте элементы hInstance и lpTemplateName структуры, чтобы идентифицировать модуль и название ресурса.

ИЛИ

Если ваш пользовательский шаблон уже в памяти, установите флажок FR_ENABLETEMPLATEHANDLE. Используйте элемент hInstance, чтобы идентифицировать объект памяти, который хранит в себе шаблон.

Вы можете предоставить диалоговому окну Найти (Find) или Заменить (Replace) фильтр - процедуру FRHookProc. Фильтр -процедура может обрабатывать сообщения, посылаемые в диалоговое окно. Если вы используете пользовательский шаблон, чтобы определить дополнительные элементы управления, вы должны предоставить фильтр - процедуру для обработки в водимых данных для ваших элементов управления.

Чтобы включить в работу фильтр - процедуру для диалогового окна Найти (Find) или Заменить (Replace)

1. Установите флажок FR_ENABLEHOOK в элементе Flags структуры FINDREPLACE.

2. Определите адрес фильтр - процедуры в элементе lpfnHook.

После обработки своего сообщения WM_INITDIALOG, процедура диалогового окна передаёт сообщение WM_INITDIALOG в фильтр - процедуру. Параметр lParam этого сообщения указывает на структуру FINDREPLACE, которая используется для инициализации диалогового окна.

Если фильтр - процедура в ответ на сообщение WM_INITDIALOG возвращает значение ЛОЖЬ (FALSE), диалоговое окно не будет показано до тех пор, пока его не покажет фильтр - процедура. Чтобы сделать это, сначала выполняют любые другие операции прорисовки, а затем вызывают функции ShowWindow и UpdateWindow. Код ниже дает пример:

// Мы возвратили ЛОЖЬ (FALSE) в ответ на WM_INITDIALOG.
// Мы выполнили любые другие операции прорисовки.
// Теперь мы показываем диалоговое окно.

ShowWindow(hDlg, SW_SHOWNORMAL);
UpdateWindow(hDlg);


4.35 - Использование общих диалоговых окон

Выбор цвета
Выбор шрифта
Открытие файла
Отображение Диалогового окна Печатать (Print)
Установка параметров страницы для печати
Поиск текста


4.35.1 - Выбор цвета

Эта статья описывает типовой код, который отображает на экране диалоговое окно Цвет (Color) тогда, когда пользователь собирается выбрать какой-нибудь цвет. Этот типовой код сначала инициализирует структуру CHOOSECOLOR, а затем вызывает функцию ChooseColor, чтобы изобразить диалоговое окно. Если функция возвращает значение ИСТИНА (TRUE), то это служит признаком того, что пользователь выбрал цвет, а типовой код использует выбранный цвет для создания новой сплошной кисти.

Этот пример использует структуру CHOOSECOLOR для инициализации диалогового окна как ниже указано:

  1. Инициализирует элемент lpCustColors с указателем на статический массив COLORREF. Цвета в массиве первоначально черные, но статический массив защищает пользовательские цвета, созданные пользователем, посредством использования последующего вызова ChooseColor.
  2. Устанавливает флажок CC_RGBINIT и инициализирует элемент rgbResult, чтобы определить цвет, который первоначально был выбран, когда диалоговое окно открывалось. Если он не определен, изначально выбирается черный цвет.
  3. Пример, использует статическую переменную rgbCurrent, чтобы сохранить значение выбора между обращениями к ChooseColor.
  4. Устанавливает флажок CC_FULLOPEN, так что диалоговое окно всегда отображает пользовательские дополнительные цвета.
CHOOSECOLOR cc;		// структура стандартного диалогового окна
static COLORREF acrCustClr[16];	// массив пользовательских цветов
HWND hwnd;			// окно владелец
HBRUSH hbrush;		// дескриптор кисти
static DWORD rgbCurrent;		// выбор начального цвета

// Инициализация CHOOSECOLOR
ZeroMemory(&cc, sizeof(CHOOSECOLOR));
cc.lStructSize = sizeof(CHOOSECOLOR);
cc.hwndOwner = hwnd;
cc.lpCustColors = (LPDWORD) acrCustClr;
cc.rgbResult = rgbCurrent;

cc.Flags = CC_FULLOPEN | CC_RGBINIT;

if (ChooseColor(&cc)==TRUE)
{
    hbrush = CreateSolidBrush(cc.rgbResult);
    rgbCurrent = cc.rgbResult;
}


4.35.2 - Выбор шрифта

Эта статья описывает типовой код, который отображает диалоговое окно Шрифт (Font), так что пользователь может выбрать атрибуты шрифта. Типовой код сначала инициализирует структуру CHOOSEFONT, а затем вызывает функцию ChooseFont, которая отображает диалоговое окно.

Этот пример устанавливает флажок CF_SCREENFONTS, чтобы определить какое диалоговое окно будет показывать только экранные шрифты. Он устанавливает флажок CF_EFFECTS, чтобы отобразить элементы управления, которые позволяют пользователю выбрать параметры зачёркивания, подчёркивания и цвета шрифта.

Если ChooseFont, возвращает значение ИСТИНА (TRUE) то это указывает на то, что пользователь щёлкнул мышью по кнопке OK, что структура LOGFONT, указанная элементом lpLogFont структуры CHOOSEFONT содержит информацию, которая описывает шрифт и отличительные признаки шрифта, выбранные пользователем. Элемент rgbColors содержит выбранный цвет текста. Типовой код использует эту информацию, чтобы установить шрифт и цвет текста для контекста устройства связанного с окном владельца.

HWND hwnd;                			// окно владельца
HDC hdc;                  			// показываем контекст устройства окна владельца
CHOOSEFONT cf;            			// структура стандартного диалогового окна
static LOGFONT lf;        			// структура логического шрифта
static DWORD rgbCurrent;			// текущий цвет текста
HFONT hfont, hfontPrev;
DWORD rgbPrev;

// Инициализация CHOOSEFONT
ZeroMemory(&cf, sizeof(CHOOSEFONT));
cf.lStructSize = sizeof (CHOOSEFONT);
cf.hwndOwner = hwnd;
cf.lpLogFont = &lf;
cf.rgbColors = rgbCurrent;

cf.Flags = CF_SCREENFONTS | CF_EFFECTS;

if (ChooseFont(&cf)==TRUE)
{
    hfont = CreateFontIndirect(cf.lpLogFont);
    hfontPrev = SelectObject(hdc, hfont);
    rgbCurrent= cf.rgbColors;
    rgbPrev = SetTextColor(hdc, rgbCurrent);
    .
    .
    .
}


4.35.3 - Открытие файла

Эта статья описывает типовой код, показывающий диалоговое окно Открыть (Open), в котором пользователь мог бы определить диск, каталог и имя открываемого файла. Типовой код сначала инициализирует структуру OPENFILENAME, а затем вызывает функцию GetOpenFileName, чтобы показать диалоговое окно.

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

Этот пример устанавливает флажки OFN_PATHMUSTEXIST и OFN_FILEMUSTEXIST в элементе Flags. Эти флажки принуждают диалоговое окно проверять, перед возвратом, какой путь и имя файла, установленные пользователем, фактически существуют.

Функция GetOpenFileName возвращает значение ИСТИНА (TRUE), если пользователь щелкает мышью по кнопке ОК и устанавливает путь и имя существующего файла. В этом случае, буфер указывает на элемент lpstrFile, который содержит путь и имя файла. Типовой код использует эту информацию при вызове функции CreateFile для открытия файла.

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

OPENFILENAME ofn;			// структура стандартного диалогового окна
char szFile[260];			// буфер для имени файла
HWND hwnd;              		// окно владельца
HANDLE hf;              		// дескриптор файла

// Инициализация OPENFILENAME
ZeroMemory(&ofn, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hwnd;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = "All\0*.*\0Text\0*.TXT\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

// Покажем диалоговое окно Открыть (Open).

if (GetOpenFileName(&ofn)==TRUE)
    hf = CreateFile(ofn.lpstrFile, GENERIC_READ,
        0, (LPSECURITY_ATTRIBUTES) NULL,
        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
        (HANDLE) NULL);


4.35.4 - Отображение диалогового окна Печать (Print)

Эта статья описывает типовой код, который показывает диалоговое окно Печать (Print), так что пользователь может выбирать параметры для печати документа. Типовой код сначала инициализирует структуру PRINTDLG, а затем вызывает функцию PrintDlg, чтобы показать диалоговое окно.

Этот пример устанавливает флажок PD_RETURNDC в элементе Flags структуры PRINTDLG. Это заставляет функцию PrintDlg возвратить в элементе hDC дескриптор контекста устройства для выбранного принтера. Вы можете использовать дескриптор, чтобы выполнить вывод данных на принтер.

При вводе данных, типовой код устанавливает элементы hDevMode и hDevNames в значение ПУСТО (NULL). Если функция возвращает значение ИСТИНА (TRUE), эти элементы возвращают дескрипторы структурам DEVMODE и DEVNAMES, содержащим вводимые данные пользователем и информацию о принтере. Вы можете использовать эту информацию, чтобы подготовить вывод данных, которые будут пересланы в выбранный принтер.

PRINTDLG pd;
HWND hwnd;

// Инициализация PRINTDLG.
ZeroMemory(&pd, sizeof(PRINTDLG));
pd.lStructSize = sizeof(PRINTDLG);
pd.hwndOwner   = hwnd;
pd.hDevMode    = NULL;      	// Не забудьте освободить или сохранить hDevMode.
pd.hDevNames   = NULL;    	// Не забудьте освободить или сохранить hDevNames.
pd.Flags       = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC;
pd.nCopies     = 1;
pd.nFromPage   = 0xFFFF;
pd.nToPage     = 0xFFFF;
pd.nMinPage    = 1;
pd.nMaxPage    = 0xFFFF;

if (PrintDlg(&pd)==TRUE)
{
    // GDI обращается к выполнению вывода данных.
    // После выполнения удаляем DC.
    DeleteDC(pd.hDC);
}


4.35.5 - Установка параметров страницы для печати

Эта статья описывает типовой код, который показывает диалоговое окно Параметры страницы (Page Setup), так что пользователь может выбирать атрибуты страницы для печати, такие как тип бумаги, источник бумаги, ориентация страницы и поля страницы. Типовой код сначала инициализирует структуру PAGESETUPDLG, а затем вызывает функцию PageSetupDlg, чтобы показать диалоговое окно.

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

При вводе данных, типовой код устанавливает элементы hDevMode и hDevNames в значение ПУСТО (NULL). Если функция возвращает значение ИСТИНА (TRUE), то функция использует эти элементы, чтобы возвратить дескрипторы структурам DEVMODE И DEVNAMES, содержащим вводимые данные от пользователя и информацию о принтере. Вы можете использовать эту информацию, чтобы приготовить вывод данных, которые будут пересланы в выбранный принтер.

В пример также включена фильтр - процедура PagePaintHook, чтобы настраивать рисунок состава макета страницы.

PAGESETUPDLG psd;    		// структура стандартного диалогового окна
HWND hwnd;           		// окно владельца

// Инициализация PAGESETUPDLG
ZeroMemory(&psd, sizeof(PAGESETUPDLG));
psd.lStructSize = sizeof(PAGESETUPDLG);
psd.hwndOwner   = hwnd;
psd.hDevMode    = NULL; 	// Не забудьте освободить или сохранить hDevMode.
psd.hDevNames   = NULL; 	// Не забудьте освободить или сохранить hDevNames.
psd.Flags       = PSD_INTHOUSANDTHSOFINCHES | PSD_MARGINS |  PSD_ENABLEPAGEPAINTHOOK;
psd.rtMargin.top = 1000;
psd.rtMargin.left = 1250;
psd.rtMargin.right = 1250;
psd.rtMargin.bottom = 1000;
psd.lpfnPagePaintHook = PaintHook;

if (PageSetupDlg(&psd)==TRUE)
{
    // Здесь проверим значения размера бумаги и полей страницы
}

Следующий пример показывает типовую фильтр - процедуру PagePaintHook, которая рисует прямоугольник поля страницы в области макета страницы:

BOOL CALLBACK PaintHook(HWND hwndDlg, UINT uMsg, WPARAM wParam,
LPARAM lParam)

{
    LPRECT lprc;
    COLORREF crMargRect;
    HDC hdc, hdcOld;

    switch (uMsg)
    {
        // Нарисуем поля прямоугольника.
        case WM_PSD_MARGINRECT:
            hdc = (HDC) wParam;
            lprc = (LPRECT) lParam;
            // Получим системный цвет выделения.
            crMargRect = GetSysColor(COLOR_HIGHLIGHT);
            // Создаем штрих пунктирное перо для системного выделения цветом
            // и выберем его в DC макета страницы.

            hdcOld = SelectObject(hdc, CreatePen(PS_DASHDOT, .5, crMargRect));
            // Рисуем поля прямоугольника.
            Rectangle(hdc, lprc->left, lprc->top, lprc->right, lprc->bottom);
            // Возвращаем предыдущее перо DC.
            SelectObject(hdc, hdcOld);
            return TRUE;
        default:
            return FALSE;
    }
    return TRUE;
}


4.35.6 - Поиск текста

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

Код для отображения и управления диалоговым окном Заменить (Replace) сходен с вышеупомянутым диалогом, за исключением того, что он использует функцию ReplaceText, чтобы показать диалоговое окно. Диалоговое окно Заменить (Replace) также посылает сообщения в ответ на щелчок пользователя по кнопке Заменить (Replace) и Заменить все (Replace All).

Чтобы использовать диалоговое окно Найти (Find) или Заменить (Replace), вы должны выполнить три отдельные задачи:

  1. Получить идентификатор зарегистрированного сообщения FINDMSGSTRING.
  2. Показать диалоговое окно.
  3. Обработать сообщения FINDMSGSTRING, когда диалоговое окно открыто

Когда вы инициализируете вашу прикладную программу, вызовите функцию RegisterWindowMessage, чтобы получить идентификатор сообщения для зарегистрированного сообщения FINDMSGSTRING.

UINT uFindReplaceMsg;  		// идентификатор сообщения для FINDMSGSTRING
uFindReplaceMsg = RegisterWindowMessage(FINDMSGSTRING);

Чтобы показать диалоговое окно Найти (Find), сначала инициализируйте структуру FINDREPLACE, а затем вызовите функцию FindText. Обратите внимание, что структура FINDREPLACE и буфер для строки для поиска должны быть глобальной или статической переменной, так что она не выходила за пределы области действия до того, как диалоговое окно закроется. Вы должны установить элемент hwndOwner, чтобы определить окно, которое примет зарегистрированные сообщения. После того, как вы создадите диалоговое окно, вы можете перемещать или управлять им, используя возвращенный дескриптор.

FINDREPLACE fr;      		// структура стандартного диалогового окна
HWND hwnd;            		// окно владелец
CHAR szFindWhat[80];  		// буфер, принимающий строку
HWND hdlg = NULL;     		// дескриптор диалогового окна Найти (Find)

// инициализация FINDREPLACE
ZeroMemory(&fr, sizeof(FINDREPLACE));
fr.lStructSize = sizeof(FINDREPLACE);
fr.hwndOwner = hwnd;
fr.lpstrFindWhat = szFindWhat;
fr.wFindWhatLen = 80;
fr.Flags = 0;
hdlg = FindText(&fr);

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

Чтобы контролировать сообщения, посланные из диалогового окна, ваша оконная процедура должна проверять зарегистрированное сообщение FINDMSGSTRING и обрабатывать значения, переданные в структуру FINDREPLACE как в примере ниже:

LPFINDREPLACE lpfr;

if (message == uFindReplaceMsg){
    // Получим из lParam указатель на структуру FINDREPLACE.

    lpfr = (LPFINDREPLACE)lParam;

    // Если флажок установлен FR_DIALOGTERM, значит дескриптор,
    // идентифицирующий диалоговое окно, неверный.

    if (lpfr->Flags & FR_DIALOGTERM)
    {
        hdlg = NULL;
        return 0;
    }

    // Если флажок установлен FR_FINDNEXT, то вызывается определяемая программой
    // подпрограмма поиска, чтобы найти затребованную строку.

    if (lpfr->Flags & FR_FINDNEXT)
        SearchFile(lpfr->lpstrFindWhat,
            (BOOL) (lpfr->Flags & FR_DOWN),
            (BOOL) (lpfr->Flags & FR_MATCHCASE));
    return 0;
}


4.36 - Справочник по стандартному диалоговому окну

Следующие функции, структуры и сообщения связаны с общими диалоговыми окнами.


4.36.1 - Функции стандартного диалогового окна

Следующие функции используются со стандартными диалоговыми окнами.
ChooseColor
ChooseFont
CommDlgExtendedError
FindText
GetFileTitle
GetOpenFileName
GetSaveFileName
PageSetupDlg
PrintDlg
ReplaceText

Следующие определяемые программой фильтр - процедуры используются со стандартными диалоговыми окнами.
CCHookProc
CFHookProc
FRHookProc
OFNHookProc
OFNHookProcOldStyle
PagePaintHook
PageSetupHook
PrintHookProc
SetupHookProc


4.36.1.1 - Функция ChooseColor

(ВыборЦвета)

Функция ChooseColor создает стандартное диалоговое окно Цвет(Color), которое дает возможность пользователю выбрать цвет.

Синтаксис

BOOL ChooseColor
(
    LPCHOOSECOLOR lpcc 	// указывает на структуру с данными инициализации
);

Параметры
lpcc
Указатель на структуру CHOOSECOLOR, которая содержит информацию, используемую, чтобы инициализировать диалоговое окно. Когда функция ChooseColor возвращает значение, эта структура содержит информацию о цвете, выбранном пользователем.

Возвращаемые значения
Если пользователь щелкает мышью по кнопке OK диалогового окна, возвращаемое значение не нуль. Элемент rgbResult структуры CHOOSECOLOR содержит значения RGB цвета, выбранного пользователем.
Если пользователь отменяет или закрывает Диалоговое окно Цвет (Color), или происходит ошибка, возвращаемое значение нулевое. Чтобы получить дополнительные данные об ошибке, вызовите функцию CommDlgExtendedError, которая может возвратить одно из следующих значений:

CDERR_FINDRESFAILURE	CDERR_MEMLOCKFAILURE
CDERR_INITIALIZATION	CDERR_NOHINSTANCE
CDERR_LOCKRESFAILURE	CDERR_NOHOOK
CDERR_LOADRESFAILURE	CDERR_NOTEMPLATE
CDERR_LOADSTRFAILURE	CDERR_STRUCTSIZE
CDERR_MEMALLOCFAILURE

Замечания
Диалоговое окно Цвет (Color) не поддерживает палитры. Выбор цветов, предлагаемый диалоговым окном, ограничен цветами системы и размытыми версиями этих цветов.
Вы можете предоставить фильтр - процедуру CCHookProc для диалогового окна Цвет (Color). Фильтр - процедура может обрабатывать сообщения, посылаемые в диалоговое окно. Чтобы подключить фильтр - процедуру, установите флажок CC_ENABLEHOOK в элементе Flags структуры CHOOSECOLOR и установите адрес ее в элементе lpfnHook.

Смотри также
CCHookProc, CHOOSECOLOR, CommDlgExtendedError

Размещение и совместимость ChooseColor.

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		comdlg32.lib
Заголовочный файл			commdlg.h
Уникод				WinNT
Замечания по платформе		Не имеется


4.36.1.2 - Функция ChooseFont

(ВыборШрифта)

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

Синтаксис

BOOL ChooseFont
(
    LPCHOOSEFONT lpcf 	// указывает на структуру с данными инициализации
);

Параметры
lpcf
Указатель на структуру CHOOSEFONT, которая содержит информацию, используемую, чтобы инициализировать диалоговое окно. Когда ChooseFont возвращает значение, эта структура содержит информацию о выборе шрифта пользователем.

Возвращаемые значения
Если пользователь щелкнул по кнопке диалогового окна ОК, возвращается значение не нуль. Элементы структуры CHOOSEFONT показывают выбор пользователя.
Если пользователь прерывает работу или закрывает диалоговое окно Шрифт (Font) или происходит ошибка, возвращается значение нуль. Чтобы получить более подробную информацию об ошибке, вызовите функцию CommDlgExtendedError, которая может возвратить одно из ниже перечисленных значений:

CDERR_FINDRESFAILURE	CDERR_NOHINSTANCE
CDERR_INITIALIZATION	CDERR_NOHOOK
CDERR_LOCKRESFAILURE	CDERR_NOTEMPLATE
CDERR_LOADRESFAILURE	CDERR_STRUCTSIZE
CDERR_LOADSTRFAILURE	CFERR_MAXLESSTHANMIN
CDERR_MEMALLOCFAILURE	CFERR_NOFONTS
CDERR_MEMLOCKFAILURE

Замечания
Вы можете предоставить фильтр - процедуру CFHookProc для диалогового окна Шрифт (Font). Фильтр - процедура может обрабатывать сообщения, передаваемые в диалоговое окно. Чтобы разрешить работу фильтр - процедуры, установите флажок CF_ENABLEHOOK в элементе Flags структуры CHOOSEFONT и определите адрес фильтр - процедуры в элементе lpfnHook.
Фильтр - процедура может передать в диалоговое окно сообщения WM_CHOOSEFONT_GETLOGFONT, WM_CHOOSEFONT_SETFLAGS и WM_CHOOSEFONT_SETLOGFONT, чтобы получить и установить текущие значения и флаги диалогового окна.

Смотри также
CFHookProc, CHOOSEFONT, CommDlgExtendedError, LOGFONT, WM_CHOOSEFONT_GETLOGFONT, WM_CHOOSEFONT_SETFLAGS, WM_CHOOSEFONT_SETLOGFONT

Размещение и совместимость ChooseFont

Windows NT	Да
Win95	Да
Win32s	Да
Импортируемая библиотека		comdlg32.lib
Заголовочный файл			commdlg.h
Уникод				WinNT
Замечания по платформе		Не имеется


4.36.1.3 - Функция CommDlgExtendedError

(ОшибкиСтандартногоРасширенногоДиалоговогоОкна)

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

ChooseColor	GetOpenFileName
ChooseFont	GetSaveFileName
FindText	PrintDlg
ReplaceText	PageSetupDlg

Синтаксис

DWORD CommDlgExtendedError(VOID)

Параметры
У этой функции нет параметров.

Возвращаемые значения
Если самый последний вызов функции стандартного диалогового окна завершился успешно, возвращаемое значение неопределенное.
Если функция стандартного диалогового окна возвратила значение ЛОЖЬ (FALSE), потому что пользователь закрыл или отменил работу диалогового окна, возвращаемое значение нулевое. Иначе, возвращаемое значение - код ошибки отличный от нуля. Для получения дополнительной информации, см. следующий раздел Замечания.

Замечания
Функция CommDlgExtendedError может возвращать общие коды ошибок для любой из функций стандартного диалогового окна. Кроме того, имеются коды ошибок, которые возвращаются только для специфического стандартного диалогового окна. Коды ошибки, возвращенные CommDlgExtendedError, определены в файле CDERR.H.
Следующие общие коды ошибок могут быть возвращены для любой из стандартных функций диалогового окна:

  • CDERR_DIALOGFAILURE - Диалоговое окно не возможно создать. Вызов функций стандартного диалогового окна в функции DialogBox потерпел неудачу. Например, эта ошибка происходит, если стандартное диалоговое окно вызывает определение недопустимого дескриптора окна.
  • CDERR_FINDRESFAILURE - Функция стандартного диалогового окна не сумела найти определяемый ресурс.
  • CDERR_INITIALIZATION - Функция стандартного диалогового окна потерпела неудачу в ходе инициализации. Эта ошибка часто происходит тогда, когда не доступен необходимый объем памяти.
  • CDERR_LOADRESFAILURE - Функция стандартного диалогового окна потерпела неудачу при загрузке заданного ресурса.
  • CDERR_LOADSTRFAILURE - Функция стандартного диалогового окна потерпела неудачу при загрузке заданной строки.
  • CDERR_LOCKRESFAILURE - Функция стандартного диалогового окна потерпела неудачу при включении заданного ресурса.
  • CDERR_MEMALLOCFAILURE - Функция стандартного диалогового окна не смогла распределить память для внутренних структур.
  • CDERR_MEMLOCKFAILURE - Функция стандартного диалогового окна не смогла закрепить память, связанную с дескриптором.
  • CDERR_NOHINSTANCE - Флажок ENABLETEMPLATE был установлен в элементе Flags структуры инициализации для соответствующего стандартного диалогового окна, но вы не сумели предоставить соответствующий дескриптор экземпляра.
  • CDERR_NOHOOK - Флажок ENABLEHOOK был установлен в элементе Flags структуры инициализации для соответствующего стандартного диалогового окна, но вы не сумели предоставить указатель на соответствующую фильтр - процедуру.
  • CDERR_NOTEMPLATE - Флажок ENABLETEMPLATE был установлен в элементе Flags структуры инициализации для соответствующего стандартного диалогового окна, но вы не сумели предоставить соответствующий шаблон.
  • CDERR_REGISTERMSGFAIL - Функция RegisterWindowMessage возвратила код ошибки, когда она была вызвана функцией стандартного диалогового окна.
  • CDERR_STRUCTSIZE - Элемент lStructSize структуры инициализации для соответствующего стандартного диалогового окна недопустим.

Ниже перечисленные коды ошибок могут быть возвращены для функции PrintDlg:

  • PDERR_CREATEICFAILURE - Функция PrintDlg потерпела неудачу, когда попыталась создать информационный контекст.
  • PDERR_DEFAULTDIFFERENT - Вы вызвали функцию PrintDlg с флажком DN_DEFAULTPRN, определенным в элементе wDefault структуры DEVNAMES, но принтер, описанный другими элементами структуры, не соответствует текущему заданному по умолчанию принтеру. (Эта ошибка происходит тогда, когда вы сохраняете структуру DEVNAMES, а пользователь заменяет заданный по умолчанию принтер, используя Панель управления (Windows)). Чтобы использовать принтер, описанный структурой DEVNAMES, сбросьте бит флажка DN_DEFAULTPRN и вызовите PrintDlg снова. Чтобы использовать заданный по умолчанию принтер, замените структуру DEVNAMES (и структуру DEVMODE, если она существует) значением ПУСТО (NULL) и вызовите PrintDlg снова.
  • PDERR_DNDMMISMATCH - Данные в структурах DEVMODE и DEVNAMES описывают два различных принтера.
  • PDERR_GETDEVMODEFAIL - Драйвер принтера при инициализации структуры DEVMODE потерпел неудачу. (Этот код ошибки применяется только тогда, когда драйверы принтера описаны в Windows версии 3.0 и выше).
  • PDERR_INITFAILURE - Функция PrintDlg потерпела неудачу в ходе инициализации, и больше нет специфического расширенного кода ошибки, который описывает сбой. Это событие генерирует код ошибки для функции заданный по умолчанию.
  • PDERR_LOADDRVFAILURE - Функция PrintDlg не сумела загрузить драйвер устройства для заданного принтера.
  • PDERR_NODEFAULTPRN - Принтера по умолчанию не существует.
  • PDERR_NODEVICES - Драйверы принтера не были найдены.
  • PDERR_PARSEFAILURE - Функция PrintDlg не сумела разобрать строчки в разделе [devices] файла WIN.INI.
  • PDERR_PRINTERNOTFOUND - Раздел [devices] файла WIN.INI не содержит записи для требуемого принтера.
  • PDERR_RETDEFFAILURE - Флажок PD_RETURNDEFAULT был определен в элементе Flags структуры PRINTDLG, однако элемент hDevMode, или hDevNames не был установлен в значение ПУСТО (NULL).
  • PDERR_SETUPFAILURE - Функция PrintDlg не сумела загрузить требуемые ресурсы.

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

  • CFERR_MAXLESSTHANMIN - Размер, заданный в элементе nSizeMax структуры CHOOSEFONT меньше, чем размер установленный в элементе nSizeMin.
  • CFERR_NOFONTS - Шрифты не существуют.

Ниже перечислены коды ошибок, которые могут быть возвращены функциями GetOpenFileName и GetSaveFileName:

  • FNERR_BUFFERTOOSMALL - Буфер, указанный элементом lpstrFile структуры OPENFILENAME слишком маленький для имени файла, заданного пользователем. Первые два байта буфера lpstrFile содержат целочисленное значение, определяющее размер, в байтах (версия ANSI) или символах (версия Уникода), необходимое, чтобы принять полностью имя файла.
  • FNERR_INVALIDFILENAME - Недопустимое имя файла.
  • FNERR_SUBCLASSFAILURE - Попытка поделить на подклассы окно списка потерпела неудачу, потому что было не доступно необходимое количество памяти.

Ниже перечислены коды ошибок, которые могут быть возвращены функциями FindText и ReplaceText:

  • FRERR_BUFFERLENGTHZERO - Элемент структуры FINDREPLACE указывает на недопустимый буфер.

Смотри также
ChooseColor, CHOOSECOLOR, ChooseFont, CHOOSEFONT, DEVMODE, DEVNAMES, DialogBox, FINDREPLACE, FindText, GetOpenFileName, GetSaveFileName, OPENFILENAME, PageSetupDlg, PAGESETUPDLG, PrintDlg, PRINTDLG, RegisterWindowMessage, ReplaceText.

Размещение и совместимость CommDlgExtendedError

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		comdlg32.lib
Заголовочный файл			commdlg.h
Уникод				Нет
Замечания по платформе		Не имеется


4.36.1.4 - Функция FindText

(НайтиТекст)

Функция FindText создает определенное системой не модальное диалоговое окно, которое позволяет пользователю, определять строку для поиска и используемые параметры, когда происходит поиск текста в документе.

Синтаксис

HWND FindText
(
    LPFINDREPLACE lpfr 	// указывает на структуру с данными инициализации
);

Параметры
lpfr
Указатель на структуру FINDREPLACE, которая содержит информацию, используемую для инициализации диалогового окна. Диалоговое окно использует эту структуру для передачи информации о вводе данных пользователем в вашу прикладную программу. Более подробную информацию можно увидеть в разделе Замечания, расположенном ниже.

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - дескриптор окна блока диалога. Вы можете использовать дескриптор окна для установки связи или закрытия диалогового окна.
Если функция потерпела неудачу, возвращаемое значение ПУСТО (NULL). Чтобы получить расширенную информацию об ошибке, вызовите функцию CommDlgExtendedError. CommDlgExtendedError может возвратить один из следующих кодов ошибки:

CDERR_FINDRESFAILURE	CDERR_MEMLOCKFAILURE
CDERR_INITIALIZATION	CDERR_NOHINSTANCE
CDERR_LOCKRESFAILURE	CDERR_NOHOOK
CDERR_LOADRESFAILURE	CDERR_NOTEMPLATE
CDERR_LOADSTRFAILURE	CDERR_STRUCTSIZE
CDERR_MEMALLOCFAILURE	FRERR_BUFFERLENGTHZERO

Замечания
Функция FindText не выполняет операцию поиска. Вместо этого, диалоговое окно посылает зарегистрированные сообщения FINDMSGSTRING оконной процедуре окна владельца диалогового окна. Когда вы создаете диалоговое окно, элемент hwndOwner структуры FINDREPLACE идентифицирует окно владельца.
Перед вызовом FindText, вы должны вызвать функцию RegisterWindowMessage, чтобы получить идентификатор для сообщения FINDMSGSTRING. Процедура диалогового окна использует этот идентификатор, чтобы послать сообщения, когда пользователь щелкает мышью по кнопке Искать дальше (Find Next), или когда диалоговое окно закрывается. Параметр lParam сообщения FINDMSGSTRING содержит указатель на структуру FINDREPLACE. Элемент Flags этой структуры указывает событие, которое вызвало сообщение. Другие элементы структуры указывают ввод данных пользователем.
Если вы создаете диалоговое окно Найти (Find), вы должны также использовать функцию IsDialogMessage в основном цикле обработки сообщений вашей прикладной программы, чтобы гарантировать, что диалоговое окно правильно обрабатывает вводимые данные с клавиатуры, типа клавиш TAB И ESC. IsDialogMessage возвращает значение, которое указывает, обработало ли диалоговое окно Найти (Find) сообщение.
Вы можете предоставить фильтр - процедуру FRHookProc для диалогового окна Найти (Find). Фильтр - процедура может обрабатывать сообщения, посылаемые в диалоговое окно. Чтобы разрешить действие фильтр - процедуры, установите флажок FR_ENABLEHOOK в элементе Flags структуры FINDREPLACE и установите адрес этой процедуры в элементе lpfnHook.

Смотри также CommDlgExtendedError, FINDMSGSTRING, FINDREPLACE, FRHookProc, IsDialogMessage, RegisterWindowMessage, ReplaceText.

Размещение и совместимость FindText

Windows 			NT	Да
Win95				Да
Win32s				Да
Импортируемая библиотека		comdlg32.lib
Заголовочный файл			commdlg.h
Уникод				WinNT
Замечания по платформе		Не имеется


4.36.1.5 - Функция GetFileTitle

(ПолучитьНазваниеФайла)

Функция GetFileTitle возвращает имя файла, идентифицированного при помощи параметра lpszFile.

Синтаксис

short GetFileTitle
(
    LPCTSTR lpszFile,	// указатель на полный путь и имя файла для файла
    LPTSTR lpszTitle,	// указатель на буфер, который принимает имя файла
    WORD cbBuf 		// длина буфера
);

Параметры
lpszFile
Указатель на имя и расположение файла.
lpszTitle
Указатель на буфер, в который функция скопирует имя файла.
cbBuf
Определяет длину буфера, указанного параметром lpszTitle, в символах/

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - ноль.
Если имя файла недопустимое, возвращаемое значение - отрицательное число.
Если буфер, на который указывает параметр lpszTitle слишком маленький, возвращаемое значение - положительное целое число, которое определяет требуемый размер буфера в байтах (для версии ANSI) или в символах (для версии Уникода). Требуемый размер буфера включает в себя символ нуль-терминатора.

Замечания
Функция GetFileTitle возвращает значение ошибки, если буфер, указанный параметром lpszFile, содержит любой из ниже перечисленных элементов:

  1. Пустую строку
  2. Строку, содержащую подстановочный знак (*), открывающую скобку ([) или закрывающую скобку (])
  3. Строку, которая заканчивается двоеточием (:/) или обратным слэшем (\)
  4. Строку, длина которой превышает длину буфера
  5. Недопустимый символ (например, пробел или непечатаемый символ)

Чтобы получать для имени файла буфер необходимого размера, вызовите функцию с установленными параметрами lpszTitle в значение ПУСТО (NULL) и cbBuf - в нуль. Функция возвратит требуемый размер.
GetFileTitle возвращает строку, которую система использовала бы, чтобы показать имя файла пользователю. Показываемое имя включает в себя расширение только в том случае, если, это является выбором пользователя для отображающихся имен файлов. Это означает, что возвращенная строка не может точно идентифицировать файл, если он используется при обращении к функциям файловой системы.
Если буфер lpszTitle слишком маленький, GetFileTitle возвращает размер, требуемый, чтобы удержать отображаемое имя. Нет никакой гарантии согласованости между требуемым размером и символами, первоначально определяемыми в буфере lpszFile. При перенесении прикладных программ в Windows 95 и Windows NT, разработчики должны будут модифицировать любой код, который предполагает такое поведение в предыдущих версиях операционной системы. Наиболее общий случай - код, который преднамеренно вызывает GetFileTitle с установленным lpszTitle в значение ПУСТО (NULL) и cbBuf, установленный в нуль, а затем использует возвращаемое значение как индекс в строке lpszFile. Эта методика больше не поддерживается. Вы можете обычно достичь сходных результатов (и лучшей производительности) с библиотечными функциями этапа выполнения программы таких, как strrchr, wcsrchr, и _mbsrchr.

Смотри также
GetOpenFileName, GetSaveFileName

Размещение и совместимость GetFileTitle

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		comdlg32.lib
Заголовочный файл			commdlg.h
Уникод				WinNT
Замечания по платформе		Не имеется


4.36.1.6 - Функция GetOpenFileName

(ПолучитьИмяОткрытогоФайла)

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

Синтаксис

BOOL GetOpenFileName
(
    LPOPENFILENAME lpofn 	// адрес структуры с данными инициализации
);

Параметры
lpofn
Указатель на структуру OPENFILENAME, которая содержит информацию, используемую для инициализации диалогового окна. Когда GetOpenFileName возвращает значение, эта структура содержит информацию о файле, выбранном пользователем.

Возвращаемые значения
Если пользователь определяет имя файла и щелкает по кнопке ОК, возвращаемое значение не нуль. Буфер, указанный элементом lpstrFile структуры OPENFILENAME содержит полный путь и имя файла, которые определил пользователь.
Если пользователь прервал работу или закрыл диалоговое окно Открыть (Open) или произошла ошибка, возвращаемое значение - ноль. Чтобы получить расширенную информацию об ошибке, вызовите функцию CommDlgExtendedError, которая может возвратить одно из ниже перечисленных значений:

CDERR_FINDRESFAILURE	CDERR_NOHINSTANCE
CDERR_INITIALIZATION	CDERR_NOHOOK
CDERR_LOCKRESFAILURE	CDERR_NOTEMPLATE
CDERR_LOADRESFAILURE	CDERR_STRUCTSIZE
CDERR_LOADSTRFAILURE	FNERR_BUFFERTOOSMALL
CDERR_MEMALLOCFAILURE	FNERR_INVALIDFILENAME
CDERR_MEMLOCKFAILURE	FNERR_SUBCLASSFAILURE

Замечания
По умолчанию Windows 95 и Windows NT версии 4.0 показывают новую версию диалогового окна Открыть, которое обеспечивает пользовательский интерфейс со свойствами, которые похожи на Проводник Windows. Вы можете предоставить диалоговому окну Открыть в стиле Проводника фильтр - процедуру OFNHookProc. Чтобы разрешить работу фильтр - процедуре, установите флажки OFN_EXPLORER и OFN_ENABLEHOOK в элементе Flags структуры OPENFILENAME и определите ее адрес в элементе lpfnHook.
Windows 95 и Windows NT 4.0 продолжают поддерживать диалоговое окно Открыть для приложений, которые хотят поддерживать пользовательский интерфейс совместимый с пользовательским интерфейсом Windows 3.1 или Windows NT 3.51. Чтобы показать диалоговое окно Открыть старого стиля, разрешите работу фильтр - процедуре OFNHookProcOldStyle и гарантируйте, что флажок OFN_EXPLORER не установлен.

Смотри также
CommDlgExtendedError, GetSaveFileName, OFNHookProc, OFNHookProcOldStyle, OPENFILENAME

Размещение и совместимость GetOpenFileName

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		comdlg32.lib
Заголовочный файл			commdlg.h
Уникод				WinNT
Замечания по платформе		Не имеется


4.36.1.7 - Функция GetSaveFileName

(ПолучитьСохраненноеИмяФайла)

Функция GetSaveFileName создает стандартное диалоговое окно Сохранить (Save), которое позволяет пользователю определить диск, каталог и имя файла, которое нужно сохранить.

Синтаксис

BOOL GetSaveFileName
(
    LPOPENFILENAME lpofn 	// адрес структуры данными инициализации
);

Параметры
lpofn
Указатель на структуру OPENFILENAME, которая содержит информацию, используемую, чтобы инициализировать диалоговое окно. Когда GetSaveFileName возвращает значение, эта структура содержит информацию о выбранном пользователем файле.

Возвращаемые значения
Если пользователь определяет имя файла и щелкает мышью по кнопке OK, возвращаемое значение не нуль. Буфер, указанный в элементе lpstrFile структуры OPENFILENAME содержит полный путь и имя файла, определенного пользователем.
Если пользователь прерывает работу или закрывает диалоговое окно Сохранить (Save) или происходит ошибка, возвращаемое значение - нуль. Чтобы получить дополнительную информацию об ошибке, вызовите функцию CommDlgExtendedError, которая может возвратить одно из ниже перечисленных значений:

CDERR_FINDRESFAILURE	CDERR_NOHINSTANCE
CDERR_INITIALIZATION	CDERR_NOHOOK
CDERR_LOCKRESFAILURE	CDERR_NOTEMPLATE
CDERR_LOADRESFAILURE	CDERR_STRUCTSIZE
CDERR_LOADSTRFAILURE	FNERR_BUFFERTOOSMALL
CDERR_MEMALLOCFAILURE	FNERR_INVALIDFILENAME
CDERR_MEMLOCKFAILURE	FNERR_SUBCLASSFAILURE

Замечания
По умолчанию, Windows 95 и Windows NT версии 4.0 показывают новую версию диалогового окна Сохранить (Save), чтобы обеспечить пользовательский интерфейс со свойствами, которые похожи на Проводник Windows. Вы можете обеспечить диалоговое окно Сохранить (Save) в стиле Проводника фильтр - процедурой OFNHookProc. Чтобы разрешить работу фильтр - процедуры, установите флажки OFN_EXPLORER и OFN_ENABLEHOOK в элементе Flags структуры OPENFILENAME и установить ее адрес в элементе lpfnHook.
Windows 95 и Windows NT 4.0 продолжает поддерживать диалоговое окно Сохранить (Save) старого стиля для прикладных программ, которые хотят поддерживать пользовательский интерфейс совместимый с пользовательским интерфейсом Windows 3.1 или Windows NT 3.51. Чтобы показать диалоговое окно Сохранить (Save) в старом стиле, разрешите работу фильтр - процедуре OFNHookProcOldStyle и гарантируйте, что флажок OFN_EXPLORER не установлен.

Смотри также
CommDlgExtendedError, GetOpenFilename, OFNHookProc, OFNHookProcOldStyle, OPENFILENAME

Размещение и совместимость GetSaveFileName

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		comdlg32.lib
Заголовочный файл			commdlg.h
Уникод				WinNT
Замечания по платформе		Не имеется


4.36.1.8 - Функция PageSetupDlg

(ДиалоговоеОкноПараметрыСтраницы)

Функция PageSetupDlg создает диалоговое окно Параметры страницы (Page Setup), которое разрешает действия пользователю, чтобы установить атрибуты страницы для печати. Эти атрибуты включают в себя размер бумаги и источник, ориентацию страницы (портретную или альбомную) и ширину полей страницы.

Синтаксис

BOOL PageSetupDlg
(
    LPPAGESETUPDLG lppsd	// указатель на структуру
);

Параметры
lppsd
Указатель на структуру PAGESETUPDLG, которая содержит информацию, используемую для инициализации диалогового окна. Когда функция возвращает значение, структура принимает информацию о выборе пользователя.

Возвращаемые значения
Если пользователь щелкает мышью по кнопке OK, возвращаемое значение не нуль. Элементы структуры PAGESETUPDLG, указанные параметром lppsd, определяют выбор пользователя.
Если пользователь прерывает работу или закрывает диалоговое окно Параметры страницы (Page Setup) или происходит ошибка, возвращаемое значение нулевое. Чтобы получать дополнительные данные об ошибках, используйте функцию CommDlgExtendedError

Смотри также
CommDlgExtendedError, PagePaintHook, PAGESETUPDLG, PageSetupHook

Размещение и совместимость PageSetupDlg

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		comdlg32.lib
Заголовочный файл			commdlg.h
Уникод				WinNT
Замечания по платформе		Не имеется


4.36.1.9 - Функция PrintDlg

(ДиалоговоеОкноПечать)

Функция PrintDlg показывает диалоговое окно Печать (Print) или диалоговое окно Установки для печати (Print Setup). Диалоговое окно Печать (Print) дает возможность пользователю установить свойства отдельного задания по выводу на печать.
Диалоговое окно Установки для печати (Print Setup) не должно использоваться в новых прикладных программах. Оно заменяется стандартным диалоговым окном Параметры Страницы (Page Setup), создаваемое функцией PageSetupDlg.

Синтаксис

BOOL PrintDlg
(
    LPPRINTDLG lppd 	// адрес структуры с данными инициализации
);

Параметры
lppd
Указатель на структуру PRINTDLG, которая содержит информацию, используемую, чтобы инициализировать диалоговое окно. Когда PrintDlg возвращает значение, эта структура содержит информацию о выборе пользователя.

Возвращаемые значения
Если пользователь щелкает мышью по кнопке OK, возвращаемое значение не нуль. Элементы структуры PRINTDLG, указанные параметром lppd показывают выбор пользователя.
Если пользователь прерывает работу или закрывает диалоговое окно Печать (Print) или Установки для печати (Print Setup) или происходит ошибка, возвращаемое значение нулевое. Чтобы получать дополнительные данные об ошибках, используйте функцию CommDlgExtendedError, которая может возвратить одно из ниже перечисленных значений:

CDERR_FINDRESFAILURE	PDERR_CREATEICFAILURE
CDERR_INITIALIZATION	PDERR_DEFAULTDIFFERENT
CDERR_LOADRESFAILURE	PDERR_DNDMMISMATCH
CDERR_LOADSTRFAILURE	PDERR_GETDEVMODEFAIL
CDERR_LOCKRESFAILURE	PDERR_INITFAILURE
CDERR_MEMALLOCFAILURE	PDERR_LOADDRVFAILURE
CDERR_MEMLOCKFAILURE	PDERR_NODEFAULTPRN
CDERR_NOHINSTANCE	PDERR_NODEVICES
CDERR_NOHOOK		PDERR_PARSEFAILURE
CDERR_NOTEMPLATE	PDERR_PRINTERNOTFOUND
CDERR_STRUCTSIZE	PDERR_RETDEFFAILURE

Замечания
Если фильтр - процедура (указанная элементом lpfnPrintHook или lpfnSetupHook структуры PRINTDLG) обрабатывает сообщение WM_CTLCOLORDLG, она должна возвратить дескриптор для кисти, которая должна использоваться, чтобы окрасить фон элемента управления.

Смотри также
CommDlgExtendedError, CreateDC, DOCINFO, PRINTDLG, PrintHookProc, SetupHookProc, StartDoc, WM_CTLCOLORDLG

Размещение и совместимость PrintDlg

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		comdlg32.lib
Заголовочный файл			commdlg.h
Уникод				WinNT
Замечания по платформе		Не имеется


4.36.1.10 - Функция ReplaceText

(ЗаменитьТекст)

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

Синтаксис

HWND ReplaceText
(
    LPFINDREPLACE lpfr 	// указатель на структуру с данными инициализации
);

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

Возвращаемые значения
Если функция завершается успешно, возвращаемое значение - дескриптор окна блока диалога. Вы можете использовать дескриптор окна, чтобы установить связь диалоговым окном или закрыть его.
Если функция потерпит неудачу, возвращаемое значение - ПУСТО (NULL). Чтобы получить расширенные данные об ошибках, вызовите функцию CommDlgExtendedError, которая может возвратить один из ниже перечисленных кодов ошибки:

CDERR_FINDRESFAILURE	CDERR_MEMLOCKFAILURE
CDERR_INITIALIZATION	CDERR_NOHINSTANCE
CDERR_LOADRESFAILURE	CDERR_NOHOOK
CDERR_LOADSTRFAILURE	CDERR_NOTEMPLATE
CDERR_LOCKRESFAILURE	CDERR_STRUCTSIZE
CDERR_MEMALLOCFAILURE	FRERR_BUFFERLENGTHZERO

Замечания
Функция ReplaceText не выполняет операцию замены текста. Вместо этого, диалоговое окно посылает зарегистрированные сообщения FINDMSGSTRING оконной процедуре окна владельца диалогового окна. Когда вы создаете диалоговое окно, элемент hwndOwner структуры FINDREPLACE идентифицирует окно владельца.
Перед вызовом ReplaceText, вы должны вызвать функцию RegisterWindowMessage, чтобы получить идентификатор для сообщения FINDMSGSTRING. Процедура диалогового окна использует этот идентификатор, чтобы посылать сообщения, когда пользователь щелкает по кнопкам Искать Дальше (Find Next), Заменить (Replace), или Заменить Все (Replace All), или когда диалоговое окно закрывается. Параметр lParam сообщения FINDMSGSTRING содержит указатель на структуру FINDREPLACE. Элемент Flags этой структуры указывает событие, которое вызвало сообщение. Другие элементы структуры указывают введенные данные пользователем.
Если вы создаете диалоговое окно Заменить (Replace), вы должны также использовать функцию IsDialogMessage в основном цикле обработки сообщений вашей прикладной программы, чтобы гарантировать, что диалоговое окно правильно обрабатывает ввод данных с клавиатуры, таких как клавиши TAB и ESC. Функция IsDialogMessage возвращает значение, которое указывает, обработало ли диалоговое окно Заменить (Replace) сообщение.
Вы можете предоставить для диалогового окна Заменить (Replace) фильтр - процедуру FRHOOKPROC. Фильтр - процедура может обрабатывать сообщения, посылаемые в диалоговое окно. Чтобы разрешать действие фильтр - процедуры, установите флажок FR_ENABLEHOOK в элементе Flags структуры FINDREPLACE и установите ее адрес в элементе lpfnHook.

Смотри также
CommDlgExtendedError, FINDREPLACE, FRHookProc, IsDialogMessage, RegisterWindowMessage, WM_CTLCOLORDLG

Размещение и совместимость ReplaceText

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		comdlg32.lib
Заголовочный файл			commdlg.h
Уникод				WinNT
Замечания по платформе		Не имеется


4.36.2 1 - Фильтр - процедура CCHookProc

Фильтр - процедура CCHookProc - определяемая программой или определенная библиотекой процедура повторного вызова, которая используется стандартным диалоговым окном Цвет (Color). Фильтр - процедура принимает сообщения или сообщения, предназначенные для заданной по умолчанию процедуры диалогового окна.

Синтаксис

UINT APIENTRY CCHookProc
(
    HWND hdlg,			// дескриптор окна блока диалога
    UINT uiMsg,			// код сообщения
    WPARAM wParam,			// параметр сообщения
    LPARAM lParam 			// параметр сообщения
);

Параметры
hdlg
Дескриптор окна блока диалога Цвет (Color), для которого предназначено сообщение. uiMsg
Идентифицирует получаемое сообщение.
wParam
Определяет дополнительную информацию о сообщении. Точное значение зависит от значения параметра uiMsg.
lParam
Определяет дополнительную информацию о сообщении. Точное значение зависит от значения параметра uiMsg.
Если параметр uiMsg указывает на сообщение WM_INITDIALOG, lParam - указатель на структуру CHOOSECOLOR, содержащую значения, установленные, когда было создано диалоговое окно.

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

Замечания
Когда вы используете функцию ChooseColor, чтобы создать диалоговое окно Цвет (Color), вы можете предоставить фильтр - процедуру CCHookProc, чтобы обрабатывать сообщения или предупреждения, предназначенные для процедуры диалогового окна. Чтобы разрешать действие фильтр - процедуры, используйте структуру CHOOSECOLOR, которую вы передали в функцию создающую диалоговое окно. Определите адрес фильтр - процедуры в элементе lpfnHook, и установите флажок CC_ENABLEHOOK в элементе Flags.
Заданная по умолчанию процедура диалогового окна обрабатывает сообщение WM_INITDIALOG перед передачей его в фильтр - процедуру. Все другие сообщения сначала принимает фильтр - процедура. Затем, возвращаемое значение фильтр - процедуры определяет, обрабатывает ли заданная по умолчанию процедура диалогового окна сообщение или игнорирует его.
Если фильтр - процедура обрабатывает сообщение WM_CTLCOLORDLG, она должна возвратить допустимый дескриптор кисти для закрашивания фона диалогового окна. Вообще, если фильтр - процедура обрабатывает какое-либо сообщение WM_CTLCOLOR*, она должна возвратить допустимый дескриптор кисти для закрашивания фона определяемого элемента управления.
Не вызывайте функцию EndDialog из фильтр - процедуры. Вместо этого, фильтр - процедура может вызывать функцию PostMessage, чтобы послать сообщение WM_COMMAND со значением IDABORT в процедуру диалогового окна. Регистрация IDABORT закрывает диалоговое окно и вынуждает функцию блока диалога возвратить значение ЛОЖЬ (FALSE). Если Вам нужно знать, почему фильтр - процедура закрыла диалоговое окно, вы должны предоставить свой собственный механизм связи между фильтр - процедурой и вашей прикладной программой.
Вы можете делить на подклассы стандартные элементы управления общего диалогового окна. Однако, и процедура стандартного диалогового окна может тоже делить на подклассы элементы управления. По этой причине, вы должны делить на подклассы элементы управления тогда, когда ваша фильтр - процедура обрабатывает сообщение WM_INITDIALOG. Это гарантирует, что ваша процедура подкласса получит определенные элементом управления сообщения раньше процедуры подкласса, установленной процедурой диалогового окна.
CCHookProc - метка - заместитель для определяемого программой или определенного библиотекой имени функции. Тип LPCCHOOKPROC - указатель на фильтр - процедуру CCHookProc.

Смотри также
ChooseColor, CHOOSECOLOR, EndDialog, PostMessage, WM_INITDIALOG, WM_CTLCOLORDLG

Размещение и совместимость CCHookProc

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		Определяемая пользователем
Заголовочный файл			commdlg.h
Уникод				Нет
Замечания по платформе		LPCCHOOKPROC


4.36.2.2 Фильтр - процедура CFHookProc

Фильтр - процедура CFHookProc - определяемая программой или определенная библиотекой процедура повторного вызова, которая используется стандартным диалоговым окном Шрифт (Font). Фильтр - процедура принимает сообщения или сообщения, предназначенные для заданной по умолчанию процедуры диалогового окна.

Синтаксис

UINT APIENTRY CFHookProc
(
    HWND hdlg,			// дескриптор окна блока диалога
    UINT uiMsg,			// код сообщения
    WPARAM wParam,		// параметр сообщения
    LPARAM lParam 		// параметр сообщения
);

Параметры
hdlg
Дескриптор окна блока диалога Шрифт (Font), для которого предназначено сообщение.
uiMsg
Идентифицирует полученное сообщение.
wParam
Определяет дополнительную информацию о сообщении. Точное значение зависит от значения параметра uiMsg.
lParam
Определяет дополнительную информацию о сообщении. Точное значение зависит от значения параметра uiMsg.
Если параметр uiMsg обозначает сообщение WM_INITDIALOG, lParam - указатель на структуру CHOOSEFONT, содержащую значения, которые были определены, когда было создано стандартное диалоговое окно.

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

Замечания
Когда вы используете функцию ChooseFont, чтобы создать Диалоговое окно Шрифт (Font), вы можете предоставить фильтр - процедуру CFHookProc, чтобы обработать сообщения или предупреждения, предназначенные для процедуры диалогового окна. Чтобы разрешить действие фильтр - процедуры, используйте структуру CHOOSEFONT, которую вы передали в функцию создания диалоговое окна. Установите адрес фильтр - процедуры в элементе lpfnHook, и установите флажок CF_ENABLEHOOK в элементе Flags.
Заданная по умолчанию процедура диалогового окна обрабатывает сообщение WM_INITDIALOG перед передачей его в фильтр - процедуру. Все другие сообщения, сначала принимает фильтр - процедура. Затем, возвращаемое значение фильтр - процедурой определяет, обрабатывает ли заданная по умолчанию процедура диалогового окна сообщение или игнорирует его.
Если фильтр - процедура обрабатывает сообщение WM_CTLCOLORDLG, она должна возвратить допустимый дескриптор кисти для закрашивания фона диалогового окна. Вообще, если фильтр - процедура обрабатывает какое-либо сообщение WM_CTLCOLOR*, она должна возвратить допустимый дескриптор кисти для закрашивания фона определяемого элемента управления.
Не вызывайте функцию EndDialog из фильтр - процедуры. Вместо этого, она может вызывать функцию PostMessage, чтобы послать сообщение WM_COMMAND со значением IDABORT в процедуру диалогового окна. Посылка IDABORT закрывает диалоговое окно и вынуждает функцию блока диалога возвратить значение ЛОЖЬ (FALSE). Если Вам нужно знать, почему фильтр - процедура закрыла диалоговое окно, вы должны предоставить свой собственный механизм связи между фильтр - процедурой и вашей прикладной программой.
Вы можете делить на подклассы стандартные элементы управления общего диалогового окна. Однако, и процедура стандартного диалогового окна может тоже делить на подклассы элементы управления. По этой причине, вы должны делить на подклассы элементы управления тогда, когда ваша фильтр - процедура обрабатывает сообщение WM_INITDIALOG. Это гарантирует, что ваша процедура подкласса получит определенные элементом управления сообщения раньше процедуры подкласса, установленной процедурой диалогового окна.
CFHookProc - метка - заместитель для определяемого программой или определенного библиотекой имени функции. Тип LPCFHOOKPROC - указатель на фильтр - процедуру CFHookProc.

Смотри также
ChooseFont, CHOOSEFONT, EndDialog, PostMessage, WM_INITDIALOG, WM_CTLCOLORDLG

Размещение и совместимость CFHookProc

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		Определяемая пользователем
Заголовочный файл			commdlg.h
Уникод				Нет
Замечания по платформе		LPCFHOOKPROC


4.36.2.3 - Фильтр - процедура FRHookProc

Фильтр - процедура FRHookProc - определяемая программой или определенная библиотекой процедура повторного вызова, которая используется стандартными диалоговыми окнами Найти (Find) и Заменить (Replace). Фильтр - процедура принимает сообщения или предупреждения, предназначенные для заданной по умолчанию процедуры диалогового окна.

Синтаксис

UINT APIENTRY FRHookProc
(
    HWND hdlg,			// дескриптор окна блока диалога
    UINT uiMsg,			// код сообщения
    WPARAM wParam,			// параметр сообщения
    LPARAM lParam 			// параметр сообщения
);

Параметры
hdlg
Дескриптор окна стандартного блока диалога Найти (Find) или Заменить (Replace), для которых предназначены сообщения.
uiMsg
Идентифицирует полученное сообщение.
wParam
Определяет дополнительную информацию о сообщении. Точное значение зависит от значения параметра uiMsg.
lParam
Определяет дополнительную информацию о сообщении. Точное значение зависит от значения параметра uiMsg.
Если параметр uiMsg показывает сообщение WM_INITDIALOG, lParam - указатель на структуру FINDREPLACE, содержащую значения, которые были определены, когда было создано стандартное диалоговое окно.

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

Замечания
Когда вы используете функции FindText или ReplaceText, чтобы создать стандартное диалоговое окно Найти (Find) или Заменить (Replace), вы можете предоставить фильтр - процедуру FRHookProc, чтобы обработать сообщения или предупреждения, предназначенные для процедуры диалогового окна. Чтобы разрешить действие фильтр - процедуры, используйте структуру FINDREPLACE, которую вы передали в функцию создания диалоговое окна. Установите адрес фильтр - процедуры в элементе lpfnHook, и установите флажок FR_ENABLEHOOK в элементе Flags.
Заданная по умолчанию процедура диалогового окна обрабатывает сообщение WM_INITDIALOG перед передачей его в фильтр - процедуру. Хотя все другие сообщения, сначала принимает фильтр - процедура. Затем, возвращаемое значение фильтр - процедурой определяет, обрабатывает ли заданная по умолчанию процедура диалогового окна сообщение или игнорирует его.
Если фильтр - процедура обрабатывает сообщение WM_CTLCOLORDLG, она должна возвратить допустимый дескриптор кисти для закрашивания фона диалогового окна. Вообще, если фильтр - процедура обрабатывает какое-либо сообщение WM_CTLCOLOR*, она должна возвратить допустимый дескриптор кисти для закрашивания фона определяемого элемента управления.
Не вызывайте функцию EndDialog из фильтр - процедуры. Вместо этого, фильтр - процедура может вызывать функцию PostMessage, чтобы послать сообщение WM_COMMAND со значением IDABORT в процедуру диалогового окна. Регистрация IDABORT закрывает диалоговое окно и вынуждает функцию блока диалога возвратить значение ЛОЖЬ (FALSE). Если Вам нужно знать, почему фильтр - процедура закрыла диалоговое окно, вы должны предоставить свой собственный механизм связи между фильтр - процедурой и вашей прикладной программой.
Вы можете делить на подклассы стандартные элементы управления стандартного диалогового окна. Однако, и процедура стандартного диалогового окна может тоже делить на подклассы элементы управления. По этой причине, вы должны делить на подклассы элементы управления тогда, когда ваша фильтр - процедура обрабатывает сообщение WM_INITDIALOG. Это гарантирует, что ваша процедура подкласса получит определенные элементом управления сообщения раньше процедуры подкласса, установленной процедурой диалогового окна.
FRHookProc - метка - заместитель для определяемого программой или определенного библиотекой имени функции. Тип LPFRHOOKPROC - указатель на фильтр - процедуру FRHookProc.

Смотри также
EndDialog, FINDREPLACE, FindText, PostMessage, ReplaceText, WM_INITDIALOG, WM_CTLCOLORDLG

Размещение и совместимость FRHookProc

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		Определяемая пользователем
Заголовочный файл			commdlg.h
Уникод				Нет
Замечания по платформе		LPFRHOOKPROC


4.36.2.4 - Фильтр - процедура OFNHookProc

Фильтр - процедура OFNHookProc это - определенная прикладной программой или библиотекой повторно вызываемая процедура, которую используют стандартные диалоговые окна Открыть (Open) или Сохранить как (Save As) в стиле Проводника. Фильтр - процедура принимает предупреждающие сообщения, передаваемые из стандартного диалогового окна. Фильтр - процедура принимает также сообщения для любых дополнительных элементов управления, которые определены вашими установками шаблона дочернего диалогового окна.
Если вы не установили флажок OFN_EXPLORER, когда создавали стандартное диалоговое окно Отрыть или Сохранить как, а вы хотите иметь фильтр - процедуру, то должны использовать такую процедуру старого стиля как OFNHookProcOldStyle. В этом случае, диалоговое окно должно иметь пользовательский интерфейс старого стиля.

Синтаксис.

UINT APIENTRY OFNHookProc
(
    HWND hdlg,			// дескриптор дочернего окна диалога
    UINT uiMsg,			// код сообщения
    WPARAM wParam,			// параметр сообщения
    LPARAM lParam 			// параметр сообщения
);

Параметры
hdlg
Дескриптор дочернего диалогового окна блока диалога Открыть или Сохранить как. Используйте функцию GetParent, чтобы получить дескриптор окна блока диалога Открыть или Сохранить.
uiMsg
Идентифицирует полученное сообщение.
wParam
Определяет дополнительную информацию о сообщении. Точное значение зависит от значения параметра uiMsg.
lParam
Определяет дополнительную информацию о сообщении. Точное значение зависит от значения параметра uiMsg.
Если параметр uiMsg показывает сообщение WM_INITDIALOG, lParam указывает на структуру OPENFILENAME, содержащую значения определенные тогда, когда было создано диалоговое окно.

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

Замечания
Когда вы используете функции GetOpenFileName или GetSaveFileName, чтобы создать стандартное диалоговое окно Открыть (Open) или Сохранять Как (Save As) в стиле Проводника, вы можете предоставить фильтр - процедуру OFNHookProc. Чтобы разрешить ее действие, используйте структуру OPENFILENAME, которую вы передали в функцию создания диалогового окна. Установите указатель на фильтр - процедуру в элементе lpfnHook и установите флажок OFN_ENABLEHOOK в элементе Flags.
Если вы предоставляете фильтр - процедуру для стандартного диалогового окна в стиле Проводника, система создает блок диалога, который является потомком заданного по умолчанию диалогового окна. Фильтр - процедура действует как процедура диалогового окна для дочернего диалогового окна. Это дочернее диалоговое окно основано на шаблоне, который вы установили в структуре OPENFILENAME, или это - заданное по умолчанию дочернее диалоговое окно, если никакой шаблон не определен. Дочернее диалоговое окно создается, когда заданная по умолчанию процедура диалогового окна обрабатывает сообщение WM_INITDIALOG. После того, как дочернее диалоговое окно обрабатывает свое собственное сообщение WM_INITDIALOG, заданная по умолчанию процедура диалогового окна перемещает стандартные элементы управления, в случае необходимости, чтобы создать место для любых дополнительных элементов управления дочернего диалогового окна. Затем система передает уведомительное сообщение CDN_INITDONE фильтр - процедуре.
Фильтр - процедура не принимает сообщения, предназначенные для стандартных элементов управления заданного по умолчанию диалогового окна. Вы можете эти стандартные элементы управления поделить на подклассы, но это сомнительное действие, потому что оно может сделать вашу прикладную программу несовместимой с будущими версиями стандартного диалогового окна. Тем не менее, стандартные диалоговые окна в стиле Проводника, предоставляют набор сообщений, которые фильтр - процедура может использовать, чтобы контролировать и управлять диалоговым окном. Они включают набор уведомительных сообщений WM_NOTIFY, передаваемых из диалогового окна, также как и сообщения, которые вы можете пересылать, чтобы отыскать информацию из диалогового окна. Полный список этих сообщений, см. в статье "Фильтр - процедуры для стиля Проводника."
Если фильтр - процедура обрабатывает сообщение WM_CTLCOLORDLG, она должна возвратить допустимый дескриптор кисти для закрашивания фона диалогового окна. В большинстве случаев, если она обрабатывает какое-либо сообщение WM_CTLCOLOR*, то должна возвратить допустимый дескриптор кисти для закрашивания фона определяемого элемента управления.
Не вызывайте функцию EndDialog из фильтр - процедуры. Вместо этого, она может вызывать функцию PostMessage, чтобы в процедуру диалогового окна послать сообщение WM_COMMAND со значением IDABORT. Объявление IDABORT закрывает диалоговое окно и вынуждает функцию блока диалога возвратить значение ЛОЖЬ (FALSE). Если вам нужно узнать, почему фильтр - процедура закрыла диалоговое окно, вы должны предоставить свой собственный механизм связи между фильтр - процедурой и вашей прикладной программой.
OFNHookProc - метка - заместитель для определяемого программой или определенного библиотекой имени функции. Тип LPOFNHOOKPROC - указатель или на фильтр - процедуру OFNHOOKPROC или OFNHookProcOldStyle.

Смотри также
GetOpenFileName, GetSaveFileName, OFNHookProcOldStyle, OPENFILENAME

Размещение и совместимость OFNHookProc

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		Определяется пользователем
Заголовочный файл			-
Уникод				Нет
Замечания по платформе		LPOFNHOOKPROC


4.36.2.5 - Фильтр - процедура OFNHookProcOldStyle

Фильтр - процедура OFNHookProcOldStyle - это определяемая программой или определяемая библиотекой процедура обратного вызова, которая используется стандартными диалоговыми окнами Открыть (Open) и Сохранить как (Save As). Фильтр - процедура принимает сообщения или предупреждения, предназначенные для процедуры блока диалога.
Если вы, при создании стандартного диалогового окна Открыть (Open) или Сохранить как (Save As), установили флажок OFN_EXPLORER и вам потребовалась фильтр - процедура, вы должны использовать фильтр - процедуру OFNHookProc в стиле Проводника.

Синтаксис

UINT APIENTRY OFNHookProcOldStyle
(
    HWND hdlg,		// дескриптор окна блока диалога
    UINT uiMsg,		// идентификатор сообщения
    WPARAM wParam,		// параметр сообщения
    LPARAM lParam 		// параметр сообщения
);

Параметры
hdlg
Дескриптор окна блока диалога Открыть (Open) или Сохранить как (Save As) для которого предназначено сообщение.
uiMsg
Идентифицирует принимаемое сообщение.
wParam
Определяет дополнительную информацию о сообщении. Точное значение зависит значения параметра uiMsg.
lParam
Определяет дополнительную информацию о сообщении. Точное значение зависит значения параметра uiMsg.
Если параметр uiMsg показывает сообщение WM_INITDIALOG, lParam - указатель на структуру OPENFILENAME, содержащую значения установленные тогда, когда было создано диалоговое окно.

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

Замечания
Когда вы используете функции GetOpenFileName или GetSaveFileName, чтобы создать диалоговое окно Открыть (Open) или Сохранить как (Save As) в старом стиле, вы можете предоставить фильтр - процедуру OFNHookProcOldStyle. Чтобы разрешить работу фильтр - процедуре, используй те структуру OPENFILENAME, которой вы передали обязанности по созданию блока диалога. Установите указатель на ее в элементе lpfnHook, а в элементе Flags установите флажок OFN_ENABLEHOOK.
По умолчанию процедура диалогового окна обрабатывает сообщение WM_INITDIALOG пред передачей его в фильтр - процедуру. Для всех других сообщений, фильтр - процедура первая принимает сообщение. Затем, возвращаемое значение ее определяет, обрабатывает ли заданная по умолчанию процедура диалогового окна сообщение или игнорирует его.
Если фильтр - процедура обрабатывает сообщение WM_CTLCOLORDLG, она должна возвратить дескриптор допустимой кисти для закрашивания фона диалогового окна. В общем случае, если фильтр - процедура обрабатывает какое-либо сообщение WM_CTLCOLOR*, она должна возвратить дескриптор допустимой кисти для закрашивания фона определяемого элемента управления.
Не вызывайте функцию EndDialog из фильтр - процедуры. Вместо этого она может вызвать функцию PostMessage, чтобы послать сообщение со значением IDABORT в процедуру диалогового окна. Извещение IDABORT закрывает диалоговое окно и заставляет функцию диалогового окна возвратить значение ЛОЖЬ (FALSE). Если вам нужно узнать почему фильтр - процедура закрыла блок диалога, вы должны предоставить свой собственный механизм связи между фильтр - процедурой и вашей прикладной программой.
Вы можете поделить на классы стандартные элементы управления обшего диалогового окна. Однако и процедура стандартного диалогового окна может также поделить на классы элементы управления. По этой причине, вы должны делить на классы элементы управления тогда, когда ваша фильтр - процедура обрабатывает сообщение WM_INITDIALOG. Это гарантирует то, что ваша процедура подкласса принимает определенные элементом управления сообщения перед процедурой подкласса, установленной процедурой диалогового окна.
OFNHookProcOldStyle - метка - заместитель для определяемого программой или определенного библиотекой имени функции. Тип LPOFNHOOKPROC - указатель на фильтр - процедуру или OFNHookProcOldStyle или OFNHookProc.

Смотри также
GetOpenFileName, GetSaveFileName, OFNHookProc, OPENFILENAME, WM_INITDIALOG

Размещение и совместимость OFNHookProcOldStyle

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		Определяется пользователем
Заголовочный файл			-
Unicode				Нет
Замечания по платформе		LPOFNHOOKPROC


4.36.2.6 - Фильтр - процедура PagePaintHook

Фильтр - процедура PagePaintHook - определяемая программой или определенная библиотекой процедура повторного вызова, которая используется диалоговым окном Параметры страницы (Page Setup). Фильтр - процедура принимает сообщения, которые позволяют вам настраивать рисунок макета страницы в диалоговом окне Параметры страницы (Page Setup).

Синтаксис

UINT APIENTRY PagePaintHook
(
    HWND hdlg,			// дескриптор окна блока диалога
    UINT uiMsg,			// идентификатор сообщения
    WPARAM wParam,			// параметр сообщения
    LPARAM lParam 			// параметр сообщения
);

Параметры
hdlg
Дескриптор окна блока диалога Параметры страницы (Page Setup).
uiMsg
Идентифицирует принимаемое сообщение.
wParam
Определяет дополнительную информацию о сообщении. Точное значение зависит от значения параметра uiMsg.
lParam
Определяет дополнительную информацию о сообщении. Точное значение зависит от значения параметра uiMsg.

Возвращаемые значения
Если фильтр - процедура возвращает значение ИСТИНА (TRUE) для любого из первых трех сообщений (WM_PSD_PAGESETUPDLG, WM_PSD_FULLPAGERECT или WM_PSD_MINMARGINRECT) в порядке следования прорисовки, то диалоговое окно не передает больше сообщений и не рисует в макете страницы до тех пор, пока в следующий раз системе не потребуется перерисовать макет страницы. Если фильтр - процедура возвращает значение ЛОЖЬ (FALSE) для всех трех сообщений, диалоговое окно передает остающиеся сообщения в порядке следования прорисовки.
Если фильтр - процедура возвращает значение ИСТИНА (TRUE) для любого из остающихся сообщений в порядке следования прорисовки, диалоговое окно не рисует соответствующую часть макета страницы. Если фильтр - процедура возвращает ЛОЖЬ (FALSE) для любого из этих сообщений, диалоговое окно рисует эту часть макета страницы.

Замечания
Диалоговое окно Параметры страницы (Page Setup) включает в себя изображение макета страницы, который показывает, как выбор пользователя воздействует на вид печати выводимых данных. Изображение состоит из прямоугольника, который представляет собой выбранный тип листа бумаги или конверта, с пунктирным прямоугольником, представляющим собой текущие поля и неполные (греческий текст) символы, чтобы показать, как смотрится текст на напечатанной странице. Когда вы используете функцию PageSetupDlg, чтобы создать диалоговое окно Параметры страницы (Page Setup), вы можете предоставить фильтр - процедуру PagePaintHook, чтобы настроить вид макета страницы.
Чтобы разрешить действие фильтр - процедуры, используйте структуру PAGESETUPDLG, которую вы передали в функцию создавшую диалоговое окно. Установите указатель на фильтр - процедуру в элементе lpfnPagePaintHook, а в элементе Flags установите флажок PSD_ENABLEPAGEPAINTHOOK.
Всякий раз, когда диалоговое окно собирается делать прорисовку содержания макета страницы, фильтр - процедура принимает следующие сообщения по порядку, в котором они перечислены:

  • WM_PSD_PAGESETUPDLG - Диалоговое окно собирается делать прорисовку макета страницы. Фильтр - процедура может использовать это сообщение, чтобы приготовиться рисовать содержание макета страницы.
  • WM_PSD_FULLPAGERECT - Диалоговое окно собирается делать прорисовку макета страницы. Это сообщение определяет ограничительный прямоугольник макета страницы.
  • WM_PSD_MINMARGINRECT - Диалоговое окно собирается делать прорисовку макета страницы. Это сообщение определяет прямоугольник поля.
  • WM_PSD_MARGINRECT - Диалоговое окно собирается делать прорисовку прямоугольника поля.
  • WM_PSD_GREEKTEXTRECT - Диалоговое окно собирается делать прорисовку греческого текста внутри прямоугольника ограниченного полями.
  • WM_PSD_ENVSTAMPRECT - Диалоговое окно собирается делать прорисовку в прямоугольнике страницы макета конверта с маркой. Это сообщение посылается только для конвертов.
  • WM_PSD_YAFULLPAGERECT - Диалоговое окно собирается делать прорисовку по адресу возврата части макета страницы конверта. Это сообщение посылается для конвертов и бумаги других размеров.

PagePaintHook - метка - заместитель для определяемого программой или определенного библиотекой имени функции. Тип LPPAGEPAINTHOOK - указатель на фильтр - процедуру PagePaintHook.

Смотри также
PageSetupDlg, PAGESETUPDLG

Размещение и совместимость PagePaintHook

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		Определяется пользователем
Заголовочный файл			commdlg.h
Уникод				Нет
Замечания по платформе		LPOFNHOOKPROC


4.36.2.7 - Фильтр - процедура PageSetupHook

Фильтр - процедура PageSetupHook является определенная программой или определяемая библиотекой процедура, которая используется стандартным диалоговым окном Параметры страницы (Page Setup). Фильтр - процедура принимает сообщения или предупреждения, предназначенные для процедуры блока диалога по умолчанию.

Синтаксис.

UINT APIENTRY PageSetupHook
(
    HWND hdlg,			// дескриптор окна блока диалога
    UINT uiMsg,			// идентификатор сообщения
    WPARAM wParam,			// параметр сообщения
    LPARAM lParam 			// параметр сообщения
);

Параметры
hdlg
Дескриптор окна блока диалога Параметры страницы, для которого предназначено сообщение.
uiMsg
Идентифицирует принимаемое сообщение.
wParam
Определяет дополнительную информацию о сообщении. Точное значение зависит от значения параметра uiMsg.
lParam
Определяет дополнительную информацию о сообщении. Точное значение зависит от значения параметра uiMsg.
Если параметр uiMsg показывает сообщение WM_INITDIALOG, lParam - указатель на структуру PAGESETUPDLG, содержащую значения, которые определены, когда было создано стандартное диалоговое окно.

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

Замечания
Когда вы используете функцию PageSetupDlg, чтобы создать стандартное диалоговое окно Параметры страницы, вы можете предоставить фильтр - процедуру PageSetupHook, чтобы обрабатывать сообщения или предупреждения, предназначенные для процедуры диалогового окна. Чтобы разрешить действие фильтр - процедуры, используйте структуру PAGESETUPDLG, которую вы передали в функцию создающую диалоговое окно. Установите указатель на фильтр - процедуру в элементе lpfnPageSetupHook, а в элементе Flags установите флажок PSD_ENABLEPAGESETUPHOOK.
Заданная по умолчанию процедура диалогового окна обрабатывает сообщение WM_INITDIALOG перед передачей его фильтр - процедуре. Хотя все другие сообщения, фильтр - процедура принимает первая. Затем, возвращаемое значение фильтр - процедуры определяет, обрабатывает ли заданная по умолчанию процедура диалогового окна сообщение или игнорирует его.
Если фильтр - процедура обрабатывает сообщение WM_CTLCOLORDLG, она должна возвратить допустимый дескриптор кисти для закрашивания фона диалогового окна. В большинстве случаев, если фильтр - процедура обрабатывает какое-либо сообщение WM_CTLCOLOR*, она должна возвратить допустимый дескриптор кисти для закрашивания фона определяемого элемента управления.
Не вызывайте функцию EndDialog из фильтр - процедуры. Вместо этого, она может вызывать функцию PostMessage, чтобы послать процедуре диалогового окна сообщение WM_COMMAND со значением IDABORT. Отправка сообщения IDABORT закрывает диалоговое окно и вынуждает функцию блока диалога возвратить значение ЛОЖЬ (FALSE). Если вам нужно узнать, почему фильтр - процедура закрыла диалоговое окно, вы должны предоставить свой собственный механизм связи между фильтр - процедурой и вашей прикладной программой.
Вы можете поделить на подклассы стандартные элементы управления общего диалогового окна. Однако, и процедура стандартного диалогового окна также может делить на подклассы элементы управления. По этой причине, вы должны делить на подклассы элементы управления тогда, когда ваша фильтр - процедура обрабатывает сообщение WM_INITDIALOG. Это гарантирует то, что ваша процедура подкласса принимает определенные элементом управления сообщения перед процедурой подкласса, установленной процедурой диалогового окна.
PageSetupHook - метка - заместитель для определяемого программой или определенного библиотекой имени функции. Тип LPPAGESETUPHOOK - указатель на фильтр - процедуру PageSetupHook.

Смотри также
EndDialog, PageSetupDlg, PAGESETUPDLG, PostMessage, WM_INITDIALOG, WM_CTLCOLORDLG

Размещение и совместимость PageSetupHook

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		Определяется пользователем
Заголовочный файл			commdlg.h
Уникод				Нет
Замечания по платформе		LPPAGESETUPHOOK


4.36.2.8 - Фильтр процедура PrintHookProc

Фильтр - процедура PrintHookProc - определяемая программой или определенная библиотекой процедура повторного вызова, которая используется стандартным диалоговым окном Печать (Print). Фильтр - процедура принимает сообщения или предупреждения, предназначенные для заданной по умолчанию процедуры диалогового окна.

Синтаксис

UINT APIENTRY PrintHookProc
(
    HWND hdlg,			// дескриптор окна блока диалога
    UINT uiMsg,			// идентификатор сообщения
    WPARAM wParam,			// параметр сообщения
    LPARAM lParam 			// параметр сообщения
);

Параметры
hdlg
Дескриптор окна стандартного блока диалога Печать (Print), для которого предназначено сообщение.
uiMsg
Идентификация предаваемого сообщения.
wParam
Определяет дополнительную информацию о сообщении. Точное значение зависит от значения параметра uiMsg.
lParam
Определяет дополнительную информацию о сообщении. Точное значение зависит от значения параметра uiMsg.
Если параметр uiMsg показывает сообщение WM_INITDIALOG, lParam - указатель на структуру PRINTDLG, содержащую значения определенные тогда, когда было создано стандартное диалоговое окно.

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

Замечания
Когда вы используете функцию PrintDlg, чтобы создать стандартное диалоговое окно Печать (Print), то можете для обработки сообщений или предупреждений, предназначенных для процедуры диалогового окна, предоставить фильтр - процедуру PrintHookProc. Чтобы разрешить действие этой фильтр - процедуры, используйте структуру PRINTDLG, которую вы передали в функцию создавшую диалоговое окно. Установите в элементе lpfnPrintHook адрес фильтр процедуры, а в элементе Flags установите флажок PD_ENABLEPRINTHOOK.
Процедура блока диалога по умолчанию обрабатывает сообщение WM_INITDIALOG перед передачей его в фильтр - процедуру. Хотя все другие сообщения фильтр - процедура принимает первая. Затем, возвращаемое значение фильтр - процедуры определяет, обрабатывает ли заданная по умолчанию процедура диалоговое окна сообщение или игнорирует его.
Если фильтр - процедура обрабатывает сообщение WM_CTLCOLORDLG, она должна возвратить допустимый дескриптор кисти для закрашивания фона диалогового окна. В большинстве случаев, если фильтр - процедура обрабатывает какое-либо сообщение WM_CTLCOLOR*, она должна возвратить допустимый дескриптор кисти для закрашивания фона определяемого элемента управления.
Не вызывайте функцию EndDialog из фильтр - процедуры. Вместо этого, она может вызывать функцию PostMessage, чтобы послать процедуре диалогового окна сообщение WM_COMMAND со значением IDABORT. Отправка сообщения IDABORT закрывает диалоговое окно и вынуждает функцию блока диалога возвратить значение ЛОЖЬ (FALSE). Если вам нужно узнать, почему фильтр - процедура закрыла диалоговое окно, вы должны предоставить свой собственный механизм связи между фильтр - процедурой и вашей прикладной программой.
Вы можете поделить на подклассы стандартные элементы управления стандартного диалогового окна. Однако и процедура стандартного диалогового окна также может делить на подклассы элементы управления. По этой причине, вы должны делить на подклассы элементы управления тогда, когда ваша фильтр - процедура обрабатывает сообщение WM_INITDIALOG. Это гарантирует то, что ваша процедура подкласса принимает определенные элементом управления сообщения перед процедурой подкласса, установленной процедурой диалогового окна.
PrintHookProc - метка - заместитель для определяемого программой или определенного библиотекой имени функции. Тип LPPRINTHOOKPROC - указатель на фильтр - процедуру PrintHookProc.

Смотри также
EndDialog, PostMessage, PrintDlg, PRINTDLG, WM_INITDIALOG, WM_CTLCOLORDLG

Размещение и совместимость PrintHookProc

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		Определяется пользователем
Заголовочный файл			commdlg.h
Уникод				Нет
Замечания по платформе		LPPRINTHOOKPROC


4.36.2.9 - Фильтр - процедура SetupHookProc

Фильтр - процедура SetupHookProc - определяемая программой или определяемая библиотекой процедура обратного вызова, которая используется стандартным диалоговым окном Установки для печати (Print Setup). Фильтр - процедура передает сообщения или предупреждения, предназначенные для процедуры диалогового окна по умолчанию.

Синтаксис

UINT APIENTRY SetupHookProc
(

    HWND hdlg,			// дескриптор окна блока диалога
    UINT uiMsg,			// идентификатор сообщения
    WPARAM wParam,			// параметр сообщения
    LPARAM lParam 			// параметр сообщения
);

Параметры
hdlg
Дескриптор окна стандартного блока диалога Установки для печати (Print Setup), для которого предназначено сообщение.
uiMsg
Идентифицирует принимаемое сообщение.
wParam
Определяет дополнительную информацию о сообщении. Точное значение зависит от значения параметра uiMsg.
lParam
Определяет дополнительную информацию о сообщении. Точное значение зависит от значения параметра uiMsg.

Возвращаемые значения
Если фильтр - процедура возвращает значение ноль, это значит по умолчанию процедура диалогового окна обрабатывает сообщение.
Если фильтр - процедура возвращает не нулевое значение, по умолчанию процедура диалогового окна игнорирует сообщение.

Замечания
Диалоговое окно Установки для печати (Print Setup) было заменено блоком диалога Параметры страницы(Page Setup), которое должно использоваться новыми прикладными программами, написанными для Windows NT или Windows 95. Однако, для совместимости с более ранними версиями Windows, функция PrintDlg продолжает поддерживать отображение на экране диалогового окна Установки для печати (Print Setup). Вы можете предоставить фильтр - процедуру SetupHookProc для диалогового окна Установки для печати (Print Setup), чтобы обрабатывать сообщения или предупреждения, предназначенные для процедуры диалогового окна.
Чтобы разрешить работу фильтр - процедуры, используйте структуру PRINTDLG, которую вы передали в функцию создавшую диалог. Установите адрес фильтр - процедуры в элементе lpfnSetupHook, а в элементе Flags установите флажок PD_ENABLESETUPHOOK
Заданная по умолчанию процедура диалогового окна обрабатывает сообщение WM_INITDIALOG перед передачей его в фильтр - процедуру. Хотя все другие сообщения сначала принимает фильтр - процедура. Затем, возвращаемое значение фильтр - процедуры определяет, обрабатывает ли заданная по умолчанию процедура диалогового окна сообщение или игнорирует его.
Если фильтр - процедура обрабатывает сообщение WM_CTLCOLORDLG, она должна возвратить правильный дескриптор кисти для закрашивания фона диалогового окна. В большинстве случаев, если фильтр - процедура обрабатывает любое сообщение WM_CTLCOLOR*, она должна возвратить правильный дескриптор кисти для закрашивания фона определяемого элемента управления.
Не вызывайте функцию EndDialog из фильтр - процедуры. Вместо этого, она может вызывать функцию PostMessage, чтобы послать сообщение WM_COMMAND со значением IDABORT в процедуру диалогового окна. Отправка сообщения IDABORT закрывает диалоговое окно и вынуждает функцию блока диалога возвратить значение ЛОЖЬ (FALSE). Если вам нужно узнать, почему фильтр - процедура закрыла диалоговое окно, вы должны предоставить ваш собственный механизм связи между фильтр - процедурой и вашей прикладной программой.
Вы можете поделить на подклассы стандартные элементы управления общего диалогового окна. Тем не менее, процедура стандартного диалогового окна может также делить на подклассы элементы управления. По этой причине, вы должны делить на подклассы элементы управления, когда ваша фильтр - процедура обрабатывает сообщение WM_INITDIALOG. Это гарантирует то, что ваша процедура подкласса принимает определенные элементом управления сообщения перед процедурой подкласса, установленной процедурой диалогового окна.
SetupHookProc - метка - заместитель для определяемого программой или определенного библиотекой имени функции. Тип LPSETUPHOOKPROC - указатель на фильтр - процедуру SetupHookProc.

Смотри также
EndDialog, PrintDlg, PRINTDLG, PostMessage, WM_INITDIALOG, WM_CTLCOLORDLG

Размещение и совместимость SetupHookProc

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		Определяемая пользователем
Заголовочный файл			commdlg.h
Уникод				Нет
Замечания по платформе		LPSETUPHOOKPROC


4.36.3 - Структуры стандартного диалогового окна

Стандартные диалоговые окна используют ниже перечисленные структуры.


4.36.3.1 - Структура CHOOSECOLOR

Структура CHOOSECOLOR содержит информацию, которую использует функция ChooseColor, чтобы инициализировать стандартное диалоговое окно Цвет (Color). После того, как пользователь закрывает диалоговое окно, система возвращает информацию о выборе пользователя в этой структуре.

Синтаксис

typedef struct
{
    DWORD lStructSize;
    HWND hwndOwner;
    HWND hInstance;
    COLORREF rgbResult;
    COLORREF* lpCustColors;
    DWORD Flags;
    LPARAM lCustData;
    LPCCHOOKPROC lpfnHook;
    LPCTSTR lpTemplateName;
} CHOOSECOLOR;

Элементы
lStructSize
Определяет длину структуры, в байтах.
hwndOwner
Идентифицирует окно, которое владеет диалоговым окном. Этот элемент может быть любой правильный дескриптор окна или это может быть значение ПУСТО (NULL), если блок диалога не имеет владельца.
hInstance
Если флажок CC_ENABLETEMPLATEHANDLE установлен в элементе Flags, элемент hInstance - дескриптор объекта памяти, содержащего шаблон диалогового окна. Если флажок CC_ENABLETEMPLATE установлен, hInstance идентифицирует модуль, который содержит шаблон диалогового окна, именованный при помощи элемента lpTemplateName. Если ни CC_ENABLETEMPLATEHANDLE, ни CC_ENABLETEMPLATE не установлен, этот элемент игнорируется.
rgbResult
Если флажок CC_RGBINIT установлен, элемент rgbResult определяет выбранный первоначально цвет, когда создавалось диалоговое окно. Если среди доступных цветов определяемого значения цвета нет, система выбирает самый близкий доступный чистый тон. Если rgbResult - нуль или CC_RGBINIT не установлен, первоначально выбранный цвет черный. Если пользователь щелкает мышью по кнопке OK, элемент rgbResult устанавливает цвет выбранный пользователем.
lpCustColors
Указатель на массив из 16 значений COLORREF, который содержит для пользовательских палитр цветов значения красного, зеленого, синего (RGB) в диалоговом окне. Если пользователь изменяет эти цвета, система модифицирует массив новыми значениями RGBChooseColor, вы должны распределить статическую память для массива.
Flags
Установка битов флажков, которые вы можете использовать, чтобы инициализировать стандартное диалоговое окно Цвет (Color). Когда блок диалога возвращает значение, он устанавливает эти флажки, чтобы показать ввод данных пользователем. Этот элемент может быть комбинацией следующих флажков:

  • CC_ENABLEHOOK - Разрешает действие фильтр - процедуры, которая определена в элементе lpfnHook этой структуры. Этот флажок используется только для того, чтобы инициализировать диалоговое окно.
  • CC_ENABLETEMPLATE - Указывает, что элементы hInstance и lpTemplateName определяют шаблон диалогового окна, чтобы использовать его вместо заданного по умолчанию шаблона. Этот флажок используется только для того, чтобы инициализировать диалоговое окно.
  • CC_ENABLETEMPLATEHANDLE - Указывает, что элемент hInstance идентифицирует блок данных, который содержит предварительно загружаемый шаблон диалогового окна. Система игнорирует элемент lpTemplateName, если этот флажок установлен. Этот флажок используется только для инициализации диалогового окна.
  • CC_FULLOPEN - Заставляет диалоговое окно показывать дополнительные элементы управления, которые позволяют пользователю создавать пользовательские цвета. Если этот флажок не установлен, пользователь должен щелкнуть мышью по кнопке Определить дополнительный цвет (Define Custom Color), чтобы показать элементы управления дополнительным цветом.
  • CC_PREVENTFULLOPEN - Запрещает работу кнопки Определить дополнительные цвета (Define Custom Colors).
  • CC_RGBINIT - Заставляет диалоговое окно использовать цвет, определяемый в элементе rgbResult как исходный выбранный цвет.
  • CC_SHOWHELP - Заставляет диалоговое окно отображать кнопку Справка (Help). Элемент hwndOwner должен определить окно, которое примет зарегистрированные сообщения HELPMSGSTRING, переданное диалоговым окном, когда пользователь щелкает мышью по кнопке Справка (Help).

lCustData
Устанавливает определяемые программой данные, которые система передает в фильтр - процедуру, идентифицированную элементом lpfnHook. Когда система передает сообщение WM_INITDIALOG фильтр - процедуре, параметр lParam сообщения является указателем на структуру CHOOSECOLOR, определяемую, когда диалоговое окно было создано. Фильтр - процедура может использовать этот указатель, чтобы получить значение lCustData.
lpfnHook
Указатель на фильтр - процедуру CCHookProc, которая может обрабатывать сообщения, предназначенные для диалогового окна. Этот элемент игнорируется, если в элементе Flags не установлен флажок CC_ENABLEHOOK.
lpTemplateName
Указатель на строку с нуль-терминатором в конце, которая именует ресурс шаблона диалогового окна в модуле, идентифицированном элементом hInstance. Этот шаблон заменяет стандартный шаблон диалогового окна. Для перечисления ресурсов диалогового окна, значение lpTemplateName может быть возвращено макрокомандой MAKEINTRESOURCE. Этот элемент игнорируется, если в элементе Flags не установлен флажок CC_ENABLETEMPLATE.

Смотри также
CCHookProc, ChooseColor, MAKEINTRESOURCE, WM_INITDIALOG

Размещение и совместимость CHOOSECOLOR

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Уникод				WinNT
Замечания по платформе		Не имеется


4.36.3.2 - Структура CHOOSEFONT

Структура CHOOSEFONT содержит информацию, которую использует функция ChooseFont, чтобы инициализировать стандартное диалоговое окно Шрифт (Font). После того, как пользователь закрывает диалоговое окно, система возвращает информацию о выборе пользователя в этой структуре.

typedef struct
{
    DWORD lStructSize;
    HWND hwndOwner;
    HDC hDC;
    LPLOGFONT lpLogFont;
    INT iPointSize;
    DWORD Flags;
    DWORD rgbColors;
    LPARAM lCustData;
    LPCFHOOKPROC lpfnHook;
    LPCTSTR lpTemplateName;
    HINSTANCE hInstance;
    LPTSTR lpszStyle;
    WORD nFontType;
    WORD ___MISSING_ALIGNMENT__;
    INT nSizeMin;
    INT nSizeMax;
} CHOOSEFONT;

Элементы
lStructSize
Определяет длину структуры в байтах.
hwndOwner
Идентифицирует окно, которое владеет блоком диалога. Этот элемент может быть любым правильным дескриптором окна или он может быть значением ПУСТО (NULL), если у диалогового окна нет владельца.
hDC
Идентифицирует контекст устройства (или информационный контекст) печати, чьи шрифты должны быть внесены в список диалогового окна. Этот элемент используется только тогда, если в элементе Flags установлен флажок CF_PRINTERFONTS или CF_BOTH; в противном случае, этот элемент игнорируется.
lpLogFont
Указатель на структуру LOGFONT. Если вы в элементе Flags установили флажок CF_INITTOLOGFONTSTRUCT и инициализировали элементы LOGFONT, функция ChooseFont инициализирует диалоговое окно со шрифтом, который является наиболее близким возможным соответствием. Если пользователь щелкает по кнопке ОК, ChooseFont устанавливает элементы структуры LOGFONT, основанные на выборе пользователя.
iPointSize
Устанавливает размер выбранного шрифта, в единицах 1/10 пункта. Функция ChooseFon устанавливает это значение после того, как пользователь закроет диалоговое окно
Flags
Установка битов флажков, которые вы можете использовать, чтобы инициализировать стандартное диалоговое окно Шрифт (Font). Когда диалоговое окно возвращает значение, оно устанавливает эти флажки, чтобы показать вводимые данные пользователем. Этот элемент может быть комбинацией следующих флажков:

  • CF_APPLY - Заставляет диалоговое окно показать на экране кнопку Применить (Apply). Вы должны предоставить фильтр - процедуру, чтобы обрабатывать сообщения WM_COMMAND от кнопки Применить (Apply). Фильтр - процедура может передать сообщение WM_CHOOSEFONT_GETLOGFONT в диалоговое окно, чтобы изъять адрес структуры LOGFONT, которая содержит текущий выбор для шрифта.
  • CF_ANSIONLY - Этот флажок устаревший. Чтобы ограничить выбор шрифта для всех записей, за исключением тех, которые используют набор символов OEM или Symbol, используют флажок CF_SCRIPTSONLY. Чтобы получить сведения о поведении Windows 3.1 в соответствии с CF_ANSIONLY, используйте CF_SELECTSCRIPT, и определите ANSI_CHARSET в элементе lfCharSet структуры LOGFONT, указанной в lpLogFont.
  • CF_BOTH - Заставляет диалоговое окно внести в список доступный принтер и экранные шрифты. Элемент hDC идентифицирует контекст устройства (или информационный контекст) связанный с принтером. Этот флажок - комбинация флажков CF_PRINTERFONTS и CF_SCREENFONTS.
  • CF_TTONLY - Определяет, что функция ChooseFont должна только перечислять и давать возможность выбора шрифтов TrueType.
  • CF_EFFECTS - Заставляет диалоговое окно показать на экране элементы управления, которые позволяют пользователю устанавливать опции зачеркивания, подчеркивания и цвета текста. Если этот флажок установлен, вы можете использовать элемент rgbColors, чтобы определить исходный цвет текста. Вы можете использовать элементы lfStrikeOut и lfUnderline структуры LOGFONT, указанной в lpLogFont, чтобы определить начальные установки переключателей зачеркивания и подчеркивания. ChooseFont может использовать эти элементы, чтобы возвратить выбор пользователя.
  • CF_ENABLEHOOK - Разрешает действие фильтр - процедуры, определяемой в элементе lpfnHook этой структуры.
  • CF_ENABLETEMPLATE - Показывает, что элементы hInstance и lpTemplateName определяют шаблон диалогового окна, чтобы использовать его вместо заданного по умолчанию шаблона.
  • CF_ENABLETEMPLATEHANDLE - Показывает, что элемент hInstance идентифицирует блок данных, который содержит предварительно загруженный шаблон диалогового окна. Система игнорирует элемент lpTemplateName, если этот флажок установлен.
  • CF_FIXEDPITCHONLY - Определяет, что функция ChooseFont должна выбирать только моноширинные шрифты.
  • CF_FORCEFONTEXIST - Определяет, что функция ChooseFont должна показать состояние ошибки, если пользователь стремится выбрать шрифт или стиль, который не существует.
  • CF_INITTOLOGFONTSTRUCT - Определяет, что функция ChooseFont должна использовать структуру LOGFONT, указанную элементом lpLogFont, чтобы инициализировать управляющие элементы диалогового окна.
  • CF_LIMITSIZE - Определяет, что функция ChooseFont должна выбрать только размеры шрифта внутри диапазона, определяемого элементами nSizeMin и nSizeMax.
  • CF_NOOEMFONTS - То же самое, что и флажок CF_NOVECTORFONTS.
  • CF_NOFACESEL - При использовании структуры LOGFONT, чтобы инициализировать управляющие элементы диалогового окна, используйте этот флажок, чтобы выборочно не допустить отображения на экране диалоговым окном первоначального выбора имени шрифта для комбинированного блока. Это полезно, когда нет хотя бы одного наименования шрифта, который применяется в выбранном тексте.
  • CF_NOSCRIPTSEL - Отключает комбинированный блок Набор символов (Script). Когда этот флажок установлен, элемент lfCharSet структуры LOGFONT устанавливается в DEFAULT_CHARSET, когда ChooseFont возвращает значение. Этот флажок используется только для того, чтобы инициализировать диалоговое окно.
  • CF_NOSTYLESEL - При использовании структуры LOGFONT, чтобы инициализировать управляющие элементы диалогового окна, используйте этот флажок, чтобы избирательно не дать диалоговому окну отображать на экране начальный выбор стиля шрифта для комбинированного блока диалога. Это полезно, когда нет хотя бы единственного стиля шрифта, который применяется в выбранном тексте.
  • CF_NOSIZESEL - При использовании структуры LOGFONT, чтобы инициализировать управляющие элементы диалогового окна, используйте этот флажок, чтобы избирательно не дать диалоговому окну отображать на экране начальный выбор размера шрифта для комбинированного блока диалога. Это полезно, когда нет хотя бы единственного размера шрифта, который применяется в выбранном тексте.
  • CF_NOSIMULATIONS - Определяет, что функция ChooseFont не должна позволять графическому интерфейсу устройства (GDI) моделирования шрифта.
  • CF_NOVECTORFONTS - Определяет, что функция ChooseFont не должна позволять выбор векторного шрифта.
  • CF_NOVERTFONTS - Заставляет диалоговое окно Шрифт (Font) вносит в список только горизонтально ориентированные шрифты.
  • CF_PRINTERFONTS - Заставляет диалоговое окно внести в список только шрифты, поддерживаемые принтером, связанным с контекстом устройства (или информационным контекстом) идентифицированным элементом hDC.
  • CF_SCALABLEONLY - Определяет, что функция ChooseFont должна позволить выбор только масштабируемых шрифтов. (Масштабируемые шрифты включают в себя векторные шрифты, масштабируемые шрифты принтера, шрифты TrueType, и шрифты, масштабируемые другими технологиями.)
  • CF_SCREENFONTS - Заставляет диалоговое окно вносить в список только экранные шрифты, поддерживаемые системой.
  • CF_SCRIPTSONLY - Определяет, что функция ChooseFont должна позволить выбор шрифтов для всех не - OEM и Symbol наборов символов, а также набора символов ANSI. Этот флажок заменяет значение CF_ANSIONLY.
  • CF_SELECTSCRIPT - Когда это значение установлено при вводе данных, отображаются только шрифты с набором символов, идентифицированным в элементе lfCharSet структуры LOGFONT. Пользователю не будет позволено изменить набор символов, определяемый в комбинированном блоке диалога Набор символов (Scripts).
  • CF_SHOWHELP - Заставляет диалоговое окно показывать на экране кнопку Справка (Help). Элемент hwndOwner должен определить окно, чтобы принимать зарегистрированные сообщения HELPMSGSTRING, которые диалоговое окно передает, когда пользователь щелкает мышью по кнопке Справка (Help).
  • CF_USESTYLE - Определяет, что элемент lpszStyle указывает на буфер, который содержит данные о стиле, которые функция ChooseFont должна использовать, чтобы инициализировать комбинированный блок диалога Стиль Шрифта (Font Style). Когда пользователь закрывает диалоговое окно, ChooseFont копирует данные о стиле, выбранном пользователем, из этого буфера.
  • CF_WYSIWYG - Определяет, что функция ChooseFont должна позволить выбор только шрифтов, доступных и для принтера и для дисплея. Если этот флажок установлен, флажки CF_BOTH и CF_SCALABLEONLY также должны быть установлены.

rgbColors
Если установлен флажок CF_EFFECTS, rgbColors определяет начальный цвет текста. Когда функция ChooseFont успешно возвращает значение, этот элемент содержит значение RGB цвета текста, который выбрал пользователь.
lCustData
Устанавливает определяемые программой данные, которые система передает в фильтр - процедуру, идентифицированную элементом lpfnHook. Когда система передает сообщение WM_INITDIALOG фильтр - процедуре, параметр сообщения lParam - указатель на структуру CHOOSEFONT, определенную, когда диалоговое окно было создано. Фильтр - процедура может использовать этот указатель, чтобы получить значение lCustData.
lpfnHook
Указатель на фильтр - процедуру CFHookProc, которая может обрабатывать сообщения, предназначенные для диалогового окна. Этот элемент игнорируется, если в элементе Flags не установлен флажок CF_ENABLEHOOK.
LpTemplateName
Указатель на строку с символом нуля в конце, который именует ресурс шаблона диалогового окна в модуле, идентифицированном элементом hInstance. Этот шаблон заменяет стандартный шаблон диалогового окна. Для пронумерованных ресурсов блока диалога, lpTemplateName может быть значением, возвращенным макрокомандой MAKEINTRESOURCE. Этот элемент игнорируется, если в элементе Flags не установлен флажок CF_ENABLETEMPLATE.
hInstance
Если в элементе Flags установлен флажок CF_ENABLETEMPLATEHANDLE, hInstance - дескриптор объекта памяти, содержащего шаблон диалогового окна. Если установлен флажок CF_ENABLETEMPLATE, hInstance идентифицирует модуль, который содержит шаблон диалогового окна, именованный элементом lpTemplateName. Если ни CF_ENABLETEMPLATEHANDLE ни CF_ENABLETEMPLATE не установлен, этот элемент игнорируется.
lpszStyle
Указатель на буфер, который содержит данные стиля. Если установлен флажок CF_USESTYLE, функция ChooseFont использует данные в этом буфере, чтобы инициализировать стиль шрифта комбинированного блока диалога. Когда пользователь закрывает диалоговое окно, ChooseFont в этот буфер копирует строку стиля шрифта в комбинированном блоке диалога.
nFontType
Определяет тип выбранного шрифта, когда ChooseFont возвращает значение. Этот элемент может быть комбинацией следующих значений:

  • BOLD_FONTTYPE - Толщина шрифта - полужирная. Эта информация дублируется в элементе lfWeight структуры LOGFONT и эквивалентна FW_BOLD.
  • ITALIC_FONTTYPE - Устанавливает атрибут шрифта курсив. Эта информация дублируется в элементе lfItalic структуры LOGFONT.
  • PRINTER_FONTTYPE - Этот шрифт является шрифтом принтера.
  • REGULAR_FONTTYPE - Толщина шрифта нормальная. Эта информация дублируется в элементе lfWeight структуры LOGFONT и эквивалентна FW_REGULAR.
  • SCREEN_FONTTYPE - Этот шрифт является шрифтом экрана.
  • SIMULATED_FONTTYPE - Этот шрифт моделируется графическим интерфейсом устройства (GDI).

nSizeMin
Определяет минимальный размер шрифта в пунктах, который пользователь может выбирать. Функция ChooseFont распознает этот элемент только в том случае, если установлен флажок CF_LIMITSIZE.
nSizeMax
Определяет максимальный размер шрифта в пунктах, который пользователь может выбирать. Функция ChooseFont распознает этот элемент только в том случае, если установлен флажок CF_LIMITSIZE.

Смотри также
ChooseFont, LOGFONT, MAKEINTRESOURCE

Размещение и совместимость CHOOSEFONT

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Уникод				WinNT
Замечания по платформе		Не имеется


4.36.3.3 - Структура DEVNAMES

Структура DEVNAMES содержит строки, которые идентифицируют имена драйвера, устройства и порта вывода данных для принтера. Функция PrintDlg использует эти строки, чтобы инициализировать элементы в определенном системой диалоговом окне Печать (Print). Когда пользователь закрывает диалоговое окно, информация о выбранном принтере возвращается в эту структуру.

Синтаксис

typedef struct tagDEVNAMES
{
    WORD wDriverOffset;
    WORD wDeviceOffset;
    WORD wOutputOffset;
    WORD wDefault;
    // строки названий драйвера, устройства и порта следуют за wDefault
} DEVNAMES;

Элементы
wDriverOffset
(Ввод/Вывод) Устанавливает смещение в символах от начала этой структуры до строки с символом нуля в конце, которая содержит имя файла (без расширения) драйвера устройства. При вводе, эта строка используется для определения принтера, чтобы отобразить на экране вначале в диалоговом окне.
wDeviceOffset
(Ввод/Вывод) Устанавливает смещение в символах от начала этой структуры до строки с символом нуля в конце (максимум 32 байта, включая ноль), которая содержит название устройства. Эта строка должна быть идентична элементу dmDeviceName структуры DEVMODE.
wOutputOffset
(Ввод/Вывод) Устанавливает смещение в символах от начала этой структуры до строки с символом нуля в конце, которая содержит имя устройства физического носителя данных для вывода (порт вывода данных).
wDefault
Определяет, идентифицируют ли строки, содержащиеся в структуре DEVNAMES, заданный по умолчанию принтер. Эта строка используется, чтобы проверить, что заданный по умолчанию принтер не изменился после последней операции печати. Если какая-либо из строк не соответствует, на экране отображается предупреждающее сообщение, информирующее пользователя о том, что документ возможно надо будет переформатировать.
При выводе, элемент wDefault изменяется только в том случае, если диалоговое окно Параметры печати (Print Setup) отображалось на экране и пользователь выбрал кнопку OK. Флажок DN_DEFAULTPRN используется в том случае, если был выбран заданный по умолчанию принтер. Если определяемый принтер выбран, флажок не используется. Все другие флажки в этом элементе зарезервированы для внутреннего использования процедурой диалогового окна Печать (Print).

Смотри также
DEVMODE, PrintDlg

Размещение и совместимость DEVNAMES

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	 	-
Заголовочный файл			commdlg.h
Уникод				Нет
Замечания по платформе		Не имеется


4.36.3.4 - Структура FINDREPLACE

Структура FINDREPLACE содержит информацию, которую используют функции FindText и ReplaceText, чтобы инициализировать стандартные диалоговые окна Найти (Find) и Заменить (Replace). Зарегистрированное сообщение FINDMSGSTRING использует эту структуру, чтобы передать вводимые данные пользователем для поиска или замены в окно владельца стандартного блока диалога Найти (Find) или Заменить (Replace).

Синтаксис

typedef struct {
    DWORD lStructSize;
    HWND hwndOwner;
    HINSTANCE hInstance;
    DWORD Flags;
    LPTSTR lpstrFindWhat;
    LPTSTR lpstrReplaceWith;
    WORD wFindWhatLen;
    WORD wReplaceWithLen;
    LPARAM lCustData;
    LPFRHOOKPROC lpfnHook;
    LPCTSTR lpTemplateName;
} FINDREPLACE;

Элементы
lStructSize
Определяет длину структуры в байтах.
hwndOwner
Идентифицирует окно, которое владеет диалоговым окном. Оконная процедура определяемого окна принимает сообщения FINDMSGSTRING от блока диалога. Этот элемент может быть любым допустимым дескриптором окна, но он не должен быть со значением ПУСТО (NULL).
hInstance
Если в элементе Flags установлен флажок FR_ENABLETEMPLATEHANDLE, hInstance - дескриптор объекта памяти, содержащего шаблон диалогового окна. Если установлен флажок FR_ENABLETEMPLATE, hInstance идентифицирует модуль, который содержит шаблон диалогового окна, именованный элементом lpTemplateName. Если установленных флажков нет, этот элемент игнорируется.
Flags
Установка битов флажков, которые вы можете использовать, чтобы инициализировать диалоговое окно. Блок диалога устанавливает эти флажки, когда он передает зарегистрированное сообщение FINDMSGSTRING, чтобы обозначить ввод данных пользователем. Этот элемент может быть комбинацией следующих флажков:

  • FR_DIALOGTERM - Если он установлен в сообщении FINDMSGSTRING, то указывает на то, что диалоговое окно закрывается. Когда вы получаете сообщение с этим установленным флажком, дескриптор окна блока диалога, возвращенный функцией FindText или ReplaceText больше не допустим.
  • FR_DOWN - Если он установлен, выбрана кнопка Вперед (Down) из радио-кнопок направления в диалоговом окне Найти (Find), обозначая тем самым, что вы должны осуществлять поиск от текущего местоположения до конца документа. Если он не установлен, выбрана кнопка Назад (Up), таким образом вы должны искать в направлении к началу документа. Вы можете устанавливать этот флажок, чтобы инициализировать диалоговое окно. Если он установлен в сообщении FINDMSGSTRING, то указывает на выбор пользователя.
  • FR_ENABLEHOOK - Разрешает работу фильтр - процедуры, которая определена в элементе lpfnHook. Этот флажок используется только для инициализации диалогового окна.
  • FR_ENABLETEMPLATE - Указывает, что элементы hInstance и lpTemplateName определяют шаблон диалогового окна, который используется вместо заданного по умолчанию шаблона. Этот флажок используется только для того, чтобы инициализировать диалоговое окно.
  • FR_ENABLETEMPLATEHANDLE - Указывает, что элемент hInstance идентифицирует блок данных, который содержит предварительно загруженный шаблон диалогового окна. Система игнорирует элемент lpTemplateName, если установлен этот флажок.
  • FR_FINDNEXT - Если он установлен в сообщении FINDMSGSTRING, то указывает, что пользователь щелкнул по кнопке Найти далее (Find Next) в диалоговом окне Найти(Find) или Заменить (Replace). Элемент lpstrFindWhat определяет строку для поиска.
  • FR_HIDEUPDOWN - Если он установлен при инициализации диалогового окна Найти (Find), то скрывает радио-кнопки направления поиска.
  • FR_HIDEMATCHCASE - Если он установлен при инициализации диалогового окна Найти (Find) или Заменить (Replace), то скрывает окошко для флажка Учитывать регистр (Match Case).
  • FR_HIDEWHOLEWORD - Если он установлен при инициализации диалогового окна или Найти (Find) или Заменить (Replace), то скрывает окошко для флажка Учитывать только слово целиком (Match Whole Word Only).
  • FR_MATCHCASE - Если он установлен, то окошко для флажка Учитывать регистр (Match Case) имеет маркер "галочку", указывая, что поиск должен быть чувствителен к регистру. Если он не установлен, в окошке для флажка нет "галочки", так что поиск должен осуществляться без учета регистра. Вы можете устанавливать этот флажок, чтобы инициализировать диалоговое окно. Если он установлен в сообщении FINDMSGSTRING, то обозначает выбор пользователя.
  • FR_NOMATCHCASE - Если он установлен при инициализации диалогового окна Найти (Find) или Заменить (Replace), то отключает окошко для флажка Учитывать регистр (Match Case).
  • FR_NOUPDOWN - Если он установлен при инициализации диалогового окна Найти (Find), то отключает радио-кнопки направления поиска.
  • FR_NOWHOLEWORD - Если он установлен при инициализации диалогового окна Найти (Find ) или Заменить (Replace), то отключает окошко для флажка Слово целиком (Whole Word).
  • FR_REPLACE - Если он установлен в сообщении FINDMSGSTRING, то указывает, что пользователь щелкнул по кнопке Заменить (Replace) в диалоговом окне Заменить (Replace). Элемент lpstrFindWhat определяет строку, которая будет заменена, а элемент lpstrReplaceWith определяет строку замены.
  • FR_REPLACEALL - Если он установлен в сообщении FINDMSGSTRING, то указывает, что пользователь щелкнул по кнопке Заменить все (Replace All) в диалоговом окне Заменить (Replace). Элемент lpstrFindWhat определяет строку, которая будет заменена, а элемент lpstrReplaceWith определяет строку замены.
  • FR_SHOWHELP - Заставляет диалоговое окно показать кнопку Справка (Help). Элемент hwndOwner должен определить окно, которое примет зарегистрированные сообщения HELPMSGSTRING, переданные диалоговым окном, когда пользователь щелкает мышью по кнопку Справка (Help).
  • FR_WHOLEWORD - Если он установлен, в окошке для флажка Учитывать только слово целиком (Match Whole Word Only) появляется "галочка", указывая, что вы должны искать только целые слова, которые соответствуют строке для поиска. Если он не установлен, в окошке для флажка нет отметки "галочкой", таким образом, вы должны искать такие же фрагменты слова, которые соответствуют строке для поиска. Вы можете установить этот флажок, чтобы инициализировать диалоговое окно. Если он установлен в сообщении FINDMSGSTRING, то это обозначает выбор пользователя.

lpstrFindWhat
Указатель на буфер, который использует сообщение FINDMSGSTRING для передачи строки для поиска с нуль-терминатором в конце, которую пользователь набрал в редактируемом поле " То, что искать:". Вы должны динамически распределить буфер или использовать глобальный или статический массив, так чтобы он не выходил из области действия до того, как диалоговое окно закроется. Буфер должен быть, по крайней, мере длиной 80 символов. Если буфер содержит строку, когда вы инициализируете диалоговое окно, строка отображается в редактируемом поле " То, что искать:".
Если сообщение FINDMSGSTRING определяет, флажок FR_FINDNEXT, элемент lpstrFindWhat содержит строку, которую надо искать. Флажки FR_DOWN, FR_WHOLEWORD и FR_MATCHCASE указывают направление и тип поиска. Если сообщение FINDMSGSTRING определяет флажки FR_REPLACE или FR_REPLACE, элемент lpstrFindWhat содержит строку, которая будет заменена.
lpstrReplaceWith
Указатель на буфер, который использует сообщение FINDMSGSTRING, чтобы передать строку замены с нуль-терминатором в конце, которую пользователь ввел с клавиатуры в редактируемое поле "Заменить на: (Replace With)". Вы должны динамически распределить буфер или использовать глобальный или статический массив, так чтобы он не выходил из области действия прежде, чем диалоговое окно закроется. Если буфер содержит строку, когда вы инициализируете диалоговое окно, строка отображается в редактируемом поле "Заменить на: (Replace With)".
Если сообщение FINDMSGSTRING определяет флажки FR_REPLACE или FR_REPLACEALL, lpstrReplaceWith содержит строку замены.
Функция FindText игнорирует этот элемент.
wFindWhatLen
Устанавливает длину, в байтах, буфера, указанного элементом lpstrFindWhat.
wReplaceWithLen
Устанавливает длину, в байтах, буфера, указанного элементом lpstrReplaceWith
lCustData
Устанавливает определяемые программой данные, которые система передает в фильтр - процедуру, идентифицированную при помощи элемента lpfnHook. Когда система посылает сообщение WM_INITDIALOG фильтр - процедуре, параметр сообщения lParam - указатель на структуру FINDREPLACE, определенную, когда диалоговое окно было создано. Фильтр - процедура может использовать этот указатель, чтобы получить значение lCustData.
lpfnHook
Указатель на фильтр - процедуру FRHookProc, которая может обрабатывать сообщения, предназначенные для диалогового окна. Этот элемент игнорируется, если в элементе Flags не установлен флажок FR_ENABLEHOOK.
Если фильтр - процедура в ответ на сообщение WM_INITDIALOG возвращает значение ЛОЖЬ (FALSE), она должна показать на экране диалоговое окно, а не то диалоговое окно не будет показано на экране. Чтобы сделать это, сначала выполняют любые другие действия рисования, а затем вызывают функции ShowWindow и UpdateWindow.
lpTemplateName
Указатель на строку с символом нуля в конце, которая именует ресурс шаблона диалогового окна в модуле, идентифицированном элементом hInstance. Этот шаблон заменяет стандартный шаблон диалогового окна. Для пронумерованных ресурсов диалогового окна, это может быть значение, возвращенное макрокомандой MAKEINTRESOURCE. Этот элемент игнорируется, если в элементе Flags не установлен флажок FR_ENABLETEMPLATE.

Смотри также
FindText, FRHookProc, MAKEINTRESOURCE, ReplaceText, ShowWindow, UpdateWindow, WM_INITDIALOG

Размещение и совместимость DEVNAMES

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека	 	-
Заголовочный файл			commdlg.h
Уникод				Нет
Замечания по платформе		Не имеется


4.36.3.5 - Структура OPENFILENAME

Структура OPENFILENAME содержит информацию, которую используют функции GetOpenFileName и GetSaveFileName, чтобы инициализировать стандартное диалоговое окно Открыть (Open) или Сохранить как… (Save As). После того как пользователь закроет диалоговое окно, система возвращает информацию о выборе пользователя в эту структуру.

Синтаксис

typedef struct tagOFN
{
    DWORD lStructSize;
    HWND hwndOwner;
    HINSTANCE hInstance;
    LPCTSTR lpstrFilter;
    LPTSTR lpstrCustomFilter;
    DWORD nMaxCustFilter;
    DWORD nFilterIndex;
    LPTSTR lpstrFile;
    DWORD nMaxFile;
    LPTSTR lpstrFileTitle;
    DWORD nMaxFileTitle;
    LPCTSTR lpstrInitialDir;
    LPCTSTR lpstrTitle;
    DWORD Flags;
    WORD nFileOffset;
    WORD nFileExtension;
    LPCTSTR lpstrDefExt;
    DWORD lCustData;
    LPOFNHOOKPROC lpfnHook;
    LPCTSTR lpTemplateName;
} OPENFILENAME;

Элементы
lStructSize
Определяет длину структуры в байтах.
hwndOwner
Идентифицирует окно, которое владеет диалоговым окном. Этот элемент может быть любым допустимым дескриптором окна или он может иметь значение ПУСТО (NULL), если у диалогового окна нет владельца.
hInstance
Если в элементе Flags установлен флажок OFN_ENABLETEMPLATEHANDLE, hInstance является дескриптором объекта памяти, содержащего шаблон диалогового окна. Если установлен флажок OFN_ENABLETEMPLATE, hInstance идентифицирует модуль, который содержит шаблон диалогового окна, имеющий имя, которое в элементе lpTemplateName. Если ни один флаг не установлен, этот элемент игнорируется.
Если установлен флажок OFN_EXPLORER, система использует заданный шаблон для создания диалогового окна, которое является дочерним блоком диалога по умолчанию в стиле Проводника. Если флажок OFN_EXPLORER не установлен, система использует шаблон для создания диалогового окна в старом стиле, который заменяет блок диалога по умолчанию.
lpstrFilter
Указатель на буфер, содержащий пары строк фильтров с нулевым символом в конце. Последняя строка в буфере должна быть завершена двумя символами ПУСТО (NULL).
Первая строка в каждой паре - информационная строка, которая описывает фильтр (например, "Текстовые файлы" ("Text Files)"), а вторая строка определяет модель фильтра (например, "*.TXT"). Чтобы определить модели сложного фильтра для отдельной информационной строки, используйте точку с запятой, чтобы отделять их (например, "*.TXT; *.DOC; *.BAK"). Строка модели может быть комбинацией допустимых символов имени файла и звездочки (*) в качестве группового символа. Не включайте пробелы в строку модели.
Операционная система не изменяет порядок фильтров. Она показывает их в комбинированном блоке Типы файлов (File Types), по порядку определяемому в элементе lpstrFilter.
Если lpstrFilter имеет значение ПУСТО (NULL), диалоговое окно не показывает каких-либо фильтров.
lpstrCustomFilter
Указатель на статический буфер, который содержит пару строк фильтра с нулевым символом в конце для сохранения модели фильтра, выбранного пользователем. Первая строка - информирующая вас строка, которая описывает индивидуальный фильтр, а вторая строка - модель фильтра, выбранного пользователем. Первый раз, когда ваша прикладная программа создает диалоговое окно, вы определяете первую строку, которая может быть любой непустой строкой. Когда пользователь выбирает файл, диалоговое окно копирует текущую модель фильтра во вторую строку. Сохраняемая модель фильтра может быть одной из моделей, определяемых в буфере lpstrFilter, или это может быть модель фильтра, введенная с клавиатуры пользователем. Система использует строки, чтобы инициализировать определяемый пользователем фильтр файла, в следующий раз, когда создается диалоговое окно. Если элемент nFilterIndex нулевой, диалоговое окно использует пользовательский фильтр.
Если этот элемент имеет значение ПУСТО (NULL), диалоговое окно не сохраняет определяемые пользователем модели фильтра.
Если этот элемент - не ПУСТО (NULL), значение элемента nMaxCustFilter должно определить размер, в байтах (версия ANSI) или символах (версия Уникода), буфера lpstrCustomFilter.
nMaxCustFilter
Определяет размер, в байтах или символах, буфера, идентифицированного элементом lpstrCustomFilter. Этот буфер должен быть, по крайней мере, длиной 40 символов. Если lpstrCustomFilter имет значение ПУСТО (NULL) или указывает на строку со значением ПУСТО (NULL), этот элемент игнорируется.
nFilterIndex
Определяет индекс текущего выбранного фильтра в элементе управления Типы файлов (File Types). Буфер, указанный элементом lpstrFilter содержит пары строк, которые задают фильтры. Первая пара строк имеет индексное значение 1, вторая пара 2, и так далее. Индекс нуля обозначает, что пользовательский фильтр определен при помощи lpstrCustomFilter. Вы можете определить индекс при вводе данных, чтобы обозначить начальное описание фильтра и модель фильтра для диалогового окна. Когда пользователь выбирает файл, элемент nFilterIndex возвращает значение индекса текущего отображаемого фильтра.
Если элемент nFilterIndex нулевой и lpstrCustomFilter имеет значение ПУСТО (NULL), система использует первый фильтр в буфере lpstrFilter. Если все три элемента нулевые или имеют значение ПУСТО (NULL), система не использует какой-либо фильтр и не показывает какие-либо файлы в окне со списком файлов диалогового окна.
lpstrFile
Указатель на буфер, который содержит имя файла, используемое, чтобы инициализировать поле редактирования Имя файла (File Name). Первый символ этого буфера должен быть ПУСТО (NULL), если в ициализации нет необходимости. Когда функция GetOpenFileName или GetSaveFileName успешно возвращает значение, этот буфер содержит определитель диска, путь, имя и расширение выбранного файла.
Если установлен флажок OFN_ALLOWMULTISELECT и пользователь выбирает многочисленные файлы, буфер содержит текущий каталог, сопровождаемый выбранными именами файлов. В диалоговых окнах в стиле Проводника, каталог и строки имен файлов отделяются значением ПУСТО (NULL), с дополнительным символом ПУСТО (NULL) после последнего имени файла. В диалоговых окнах старого стиля, строки отделяются пробелами и функция использует короткие имена для файлов с пробелами. Вы можете использовать функцию FindFirstFile, чтобы преобразовывать длинные и короткие имена файлов.
Если буфер слишком маленький, функция возвращает значение ЛОЖЬ (FALSE), а функция CommDlgExtendedError возвращает значение FNERR_BUFFERTOOSMALL. В данном случае, первые два байта буфера lpstrFile содержат требуемый размер, в байтах или символах.
nMaxFile
Определяет размер буфера, в байтах (версия ANSI) или символах (версия Уникода), указанного элементом lpstrFile. Функции GetOpenFileName и GetSaveFileName возвращают значение ЛОЖЬ (FALSE), если буфер слишком маленький, чтобы содержать информацию о файле. Буфер должен быть по крайней мере длиной 256 символов.
lpstrFileTitle
Указатель на буфер, который принимает имя файла и расширение (без информации о пути) выбранного файла. Этот элемент может быть значением ПУСТО (NULL).
nMaxFileTitle
Определяет размер буфера, в байтах (версия ANSI) или символы (версия Уникода), указанного элементом lpstrFileTitle. Этот элемент игнорируется, если lpstrFileTitle имеет значение ПУСТО (NULL).
lpstrInitialDir
Указатель на строку, которая определяет начальный каталог файлов. Если этот элемент имеет значение ПУСТО (NULL), система использует текущий каталог как исходный каталог.
lpstrTitle
Указатель на строку, которая будет помещена в области заголовка диалогового окна. Если этот элемент имеет значение ПУСТО (NULL), система использует заданный по умолчанию заголовок (то есть "Сохранить как ... (Save As)" или "Открыть (Open)".
Flags
Набор битовых флажков, который вы может использовать, чтобы инициализировать диалоговое окно. Когда блок диалога возвращает значение, он устанавливает эти флажки, чтобы обозначить ввод данных от пользователя. Этот элемент может быть комбинацией следующих флажков:

  • OFN_ALLOWMULTISELECT - Определяет, что окно со списком Имя файла (File Name) позволяет многочисленный выбор. Если вы к тому же устанавите флажок OFN_EXPLORER, диалоговое окно использует пользовательский интерфейс в стиле Проводника; иначе, оно использует пользовательский интерфейс старого стиля. Если пользователь выбирает больше чем один файл, буфер lpstrFile возвращает путь текущему каталогу, сопровождаемый именами выбранных файлов. Элемент nFileOffset является смещением от первого имени файла, а элемент nFileExtension не используется. В диалоговых окнах в стиле Проводника, каталог и строки имени файла отделяются значением ПУСТО (NULL), с дополнительным символом ПУСТО (NULL) после последнего имени файла. Этот формат включает диалоговое окно в стиле Проводника, чтобы возвращать длинные имена файлов, которые включают в себя пробелы. В диалоговых окнах старого стиля каталог и строки имен файлов отделяются пробелами, а функция использует короткие имена для имен файлов с пробелами. Вы можете использовать функцию FindFirstFile, чтобы делать преобразования между длинными и короткими именами файла. Если вы определяете пользовательский шаблон для блока диалога старого стиля, определение окна со списком Имя файла (File Name) должно содержать значение LBS_EXTENDEDSEL.
  • OFN_CREATEPROMPT - Если пользователь определяет файл, который не существует, этот флажок заставляет диалоговое окно запросить пользователя о разрешении создать файл. Если пользователь выбирает создание файла, блок диалога закрывается, а функция возвращает определяемое название; в противном случае, диалоговое окно остается открытым.
  • OFN_ENABLEHOOK - Разрешает работу фильтр - процедуры, определяемой в элементе lpfnHook.
  • OFN_ENABLETEMPLATE - Обозначает то, что элемент lpTemplateName указывает на название ресурса шаблона блока диалога в модуле, идентифицированном элементом hInstance. Если установлен флажок OFN_EXPLORER, система использует определяемый шаблон, чтобы создать диалоговое окно, которое является дочерним для заданного по умолчанию блока диалога в стиле Проводника. Если флажок OFN_EXPLORER не установлен, система использует шаблон, чтобы создать диалоговое окно старого стиля, которое заменяет заданный по умолчанию блок диалога.
  • OFN_ENABLETEMPLATEHANDLE - Указывает на то, что элемент hInstance идентифицирует блок данных, который содержит предварительно загруженный шаблон диалогового окна. Система игнорирует элемент lpTemplateName, если этот флажок установлен. Если установлен флажок OFN_EXPLORER, система использует определяемый шаблон, чтобы создать блок диалога, который является дочерним для заданного по умолчанию диалогового окна в стиле Проводника. Если флажок OFN_EXPLORER не установлен, система использует шаблон, чтобы создать блок диалога старого стиля, которое заменяет заданное по умолчанию диалоговое окно.
  • OFN_EXPLORER - Обозначает, что любые настройки, сделанные в диалоговом окне Открыть (Open) или Сохранить как (Save As) используют новые методы настройки в стиле Проводника. Для получения дополнительной информации, см. статьи обзора Библиотеки стандартного диалогового окна " Фильтр (hook) - процедуры в стиле Проводника " и "Пользовательские шаблоны в стиле Проводника". По умолчанию, диалоговые окна Открыть (Open) и Сохранить как (Save As) используют пользовательский интерфейс в стиле Проводника независимо от того, установлен ли этот флажок. Этот флажок необходим, только в том случае, если вы предоставляете фильтр (hook) - процедуру или пользовательский шаблон или устанавливаете флажок OFN_ALLOWMULTISELECT. Если вы хотите иметь пользовательский интерфейс старого стиля, не включайте флажок OFN_EXPLORER и обеспечте замену шаблоном или фильтр (hook) - процедурой старого стиля. Если вы хотите иметь старый стиль, но не нуждаетесь в пользовательском шаблоне или фильтр (hook) - процедуре, просто предоставьте фильтр (hook) - процедуру, которая всегда возвращает значение ЛОЖЬ (FALSE).
  • OFN_EXTENSIONDIFFERENT - Определяет, что пользователь ввел с клавиатуры расширение имени файла, которое отличается от расширения, заданного при помощи lpstrDefExt. Функция не использует этот флажок, если lpstrDefExt имеет значение ПУСТО (NULL).
  • OFN_FILEMUSTEXIST - Определяет, что пользователь может вводить с клавиатуры только имена файлов существующих в поле ввода Имя файл (File Name). Если этот флажок определен, а пользователь вводит недопустимое название, процедура диалогового окна показывает на экране предупреждение в окне сообщений. Если этот флажок определен, флажок OFN_PATHMUSTEXIST также используется.
  • OFN_HIDEREADONLY - Скрывает отмечаемое "галочкой" окошко Только для чтения (Read Only).
  • OFN_LONGNAMES - В диалоговых окнах старого стиля этот флажок заставляет блок диалога использовать длинные имена файлов. Если этот фложок не определен или, если флажок OFN_ALLOWMULTISELECT также установлен, диалоговое окно старого стиля для названий файлов с пробелами использует короткие имена файлов (формат 8.3). Диалоговое окно в стиле Проводника игнорирует этот флажок и всегда показывает длинные имена файлов.
  • OFN_NOCHANGEDIR - Восстанавливает текущий каталог в первоначальном значении, если пользователь изменил каталог при поиске файлов.
  • OFN_NODEREFERENCELINKS - Предписывает диалоговому окну возвратить путь и имя файла выбранного ярлыка (.LNK файл). Если это значение не дано, блок диалога возвращает путь и имя файла, вызванного ярлыком.
  • OFN_NOLONGNAMES - В диалоговых окнах старого стиля этот флаг заставляет блок диалога использовать короткие имена файлов (формат 8.3). Диалоговые окна в стиле Проводника игнорируют этот флажок и всегда показывают длинные имена файлов.
  • OFN_NONETWORKBUTTON - Скрывает и отключает кнопку Сеть (Network).
  • OFN_NOREADONLYRETURN - Определяет, что возвращенное значение файла в окошке Только для чтения (Read Only) не имеет отметки "галочкой" и не в защищено от записи в каталоге.
  • OFN_NOTESTFILECREATE - Определяет, что перед закрытием диалогового окна файл не создается. Этот флажок должен быть определен, если прикладная программа сохраняет файл на неизменяющейся при выполнении соместно используемой сетевой станции. Когда прикладная программа определяет этот флажок, библиотека не проверяет защиту записи, переполнение диска, открытие доступа к диску или сетевую защиту. Прикладные программы используя этот флажок должны с большой осторжностью исполнять системный файл, потому что файл не может быть вновь открыт, как только он закроется.
  • OFN_NOVALIDATE - Определяет, что стандартные диалоговые окна позволяют запрещенные символы в возвращенном имени файла. Обычно, вызывающая прикладная программа использует фильтр (hook) - процедуру, которая проверяет имя файла при помощи использования сообщения FILEOKSTRING. Если текстовое поле в окне редактирования пустое или ничего не содержит, кроме пробелов, списки файлов и каталоги модифицируются. Если текстовое поле в окне редактирования текста содержит что - нибудь еще, элементы nFileOffset и nFileExtension устанавливаются в значения, созданные при анализе текста. Ни заданное по умолчанию расширение, ни имеемый текст, котрый скопирован в буфер, указанный элементом lpstrFileTitle, к тексту не добавляются. Если это значение определенное при помощи элемента nFileOffset - меньше чем нуль, имя файла ошибочное. Иначе, имя файла правильное и элементы nFileExtension и nFileOffset могут быть использованы, как будто флажок OFN_NOVALIDATE не был установлен.
  • OFN_OVERWRITEPROMPT - Заставляет диалоговое окно Сохранить как (Save As) создать окно сообщений, если выбранный файл уже существует. Пользователь должен подтвердить, переписывать ли заново файл.
  • OFN_PATHMUSTEXIST - Определяет, что пользователь может вводить с клавиатуры только правильные пути и имена файла. Если этот флажок использован, а пользователь вводит с клавиатуры ошибочный путь и имя файла в поле ввода Имя файла (File Name), функция диалогового окна показывает на экране в окне сообщений предупреждение.
  • OFN_READONLY - Заставляет окошко отметки Только для чтения (Read Only) изначально быть отмеченным "галочкой" при создании диалогового окна. Этот флажок указывает состояние окошка отметки Только для чтения (Read Only), когда блок диалога закрыт.
  • OFN_SHAREAWARE - Определяет, что, если вызов функции OpenFile не выполняет задачу из-за сетевой ошибки совместного доступа, ошибка игнорируется, а диалоговое окно возвращает выбранное имя файла. Если этот флажок не установлен, блок диалога сообщает вашей фильтр (hook) - процедуре, когда происходит сетевая ошибка совместного доступа имя файла, определенное пользователем. Если вы устанавливаете флажок OFN_EXPLORER, диалоговое окно передает сообщение CDN_SHAREVIOLATION фильтр (hook) - процедуре. Если вы не устанавливаете OFN_EXPLORER, блок диалога передает зарегистрированное сообщение SHAREVISTRING фильтр (hook) - процедуре.
  • OFN_SHOWHELP - Заставляет диалоговое окно показать на экране кнопку Справка (Help). Элемент hwndOwner должен определить окно, принимающее зарегистрированные сообщения HELPMSGSTRING, которые блок диалога передает, когда пользователь щелкает мышью по кнопке Справка (Help). Диалоговое окно в стиле Проводника передает вашей фильтр (hook) - процедуре уведомительное сообщение CDN_HELP, когда пользователь щелкает мышью по кнопке Справка (Help).

nFileOffset
Определяет отсчитываемое от нуля смещение от начала пути до имени файла в строке, указанной элементом lpstrFile. Например, если lpstrFile указывает на следующуюя строку, "c:\dir1\dir2\file.ext", этот элемент содержит значение 13, чтобы обозначить смещение строки "file.ext".
nFileExtension
Определяет отсчитываемое от нуля смещение от начала пути до расширения имени файла в строке, указанной элементом lpstrFile. Например, если lpstrFile указывает на следующую строку, "c:\dir1\dir2\file.ext", этот элемент содержит значение 18. Если пользователь не вводил с клавиатуры расширение и lpstrDefExt имеет значение ПУСТО (NULL), этот элемент определяет смещение, которое завершается символом нуля. Если пользователь ввел с клавиатуры "." в качестве последнего символа в имени файла, этот элемент определяется как нуль.
lpstrDefExt
Указывает на буфер, который содержит заданное по умолчанию расширение. Функции GetOpenFileName и GetSaveFileName это расширение добавляют в конец к имени файла, если пользователь не выполнил ввода с клавиатуры расширения. Эта строка может быть любой длины, но добавляются только первые три символа. Строка не должна содержать точку (.). Если этот элемент имеет значение ПУСТО (NULL), а пользователь не выполняет с клавиатуры ввода расширения, в конец никакого расширения не добавляется.
lCustData
Определяет заданные программой данные, которые система посылает фильтр (hook) - процедуре, идентифицированной элементом lpfnHook. Когда система передает сообщение WM_INITDIALOG фильтр (hook) - процедуре, параметр сообщения lParam - указатель на структуру OPENFILENAME, определенную, когда было создано диалоговое окно. Фильтр (hook) - процедура может использовать этот указатель, чтобы получить значение элемента lCustData.
lpfnHook
Указатель на фильтр (hook) - процедуру. Этот элемент игноририруется, если элемент Flags не включает в себя флажок OFN_ENABLEHOOK.
Если флажок OFN_EXPLORER не установлен в элементе Flags, lpfnHookhook) - процедуру OFNHookProcOldStyle, которая принимает сообщения, предназначенные для диалогового окна. Фильтр (hook) - процедура возвращает значение ЛОЖЬ (FALSE), чтобы переслать сообщение заданной по умолчанию процедуре диалогового окна, или значение ИСТИНА (TRUE), чтобы cбросить сообщение.
Если флажок OFN_EXPLORER установлен, lpfnHook - указатель на фильтр (hook) - процедуру OFNHookProc. Фильтр (hook) - процедура получает уведомительные сообщения, переданные из диалогового окна. Фильтр (hook) - процедура к тому же получает сообщения для любых дополнительных элементов управления, которые вы определили, устанавливая шаблон дочернего блока диалога. Фильтр (hook) - процедура не получает сообщения, предназначенные для заданных по умолчанию стандартных элементов управления диалогового окна.
lpTemplateName
Указатель на строку с символом нуля в конце, которя именует ресурс шаблона блока диалога в модуле, идентифицированном элементом hInstance. Для пронумерованных ресурсов диалогового окна, это может быть значение, возвращенное макрокомандой MAKEINTRESOURCE. Этот элемент игнорируется, если в элементе Flags не установлен флажок OFN_ENABLETEMPLATE.
Если флажок OFN_EXPLORER установлен, система использует заданный шаблон, чтобы создать диалоговое окно, которое является дочерним для заданного по умолчанию диалогового окна в стиле Проводника. Если флажок OFN_EXPLORER не установлен, система использует шаблон, чтобы создать блок диалога старого стиля, которое заменяет заданное по умолчанию диалоговое окно.

Смотри также
GetOpenFileName, GetSaveFileName

Размещение и совместимость OPENFILENAME

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				WinNT
Замечания по платформе		Не имеется


4.36.3.6 - Структура PAGESETUPDLG

Структура PAGESETUPDLG содержит информацию для функции PageSetupDlg, которая используется, чтобы инициализировать стандартное диалоговое окно Параметры страницы (Page Setup). После того, как пользователь закрывает блок диалога, система возвращает в эту структуру информацию об определяемых пользователем параметрах страницы.

Синтаксис

typedef struct tagPSD
{
    DWORD lStructSize;
    HWND hwndOwner;
    HGLOBAL hDevMode;
    HGLOBAL hDevNames;
    DWORD Flags;
    POINT ptPaperSize;
    RECT rtMinMargin;
    RECT rtMargin;
    HINSTANCE hInstance;
    LPARAM lCustData;
    LPPAGESETUPHOOK lpfnPageSetupHook;
    LPPAGEPAINTHOOK lpfnPagePaintHook;
    LPCTSTR lpPageSetupTemplateName;
    HGLOBAL hPageSetupTemplate;
} PAGESETUPDLG, * LPPAGESETUPDLG;

Элементы
lStructSize
Определяет размер этой структуры, в байтах.
hwndOwner
Идентифицирует окно, которое владеет блоком диалога. Этот элемент может быть любым допустимым дескриптором окна, или он может иметь значение ПУСТО (NULL), если у диалогового окна нет владельца.
hDevMode
Дескриптор объекта глобальной памяти, который содержит структуру DEVMODE. При вводе данных, если дескриптор дан, чтобы инициализировать элементы управления в диалоговом окне используются значения в соответствующей структуре DEVMODE. При выводе данных, блок диалога устанавливает в hDevMode глобальный дескриптор памяти для структуры DEVMODE, которая содержит значения, определяющие выбор пользователя. Если выбор пользователя не доступен, диалоговое окно устанавливает hDevMode в значение ПУСТО (NULL).
hDevNames
Дескриптор объекта глобальной памяти, который содержит структуру DEVNAMES. Эта структура содержит три строки, которые определяют имя драйвера, название принтера и название порта вывода данных. При вводе данных, если дескриптор дан, строки в соответствующей структуре DEVNAMES используются, чтобы инициализировать элементы управления в диалоговом окне. При выводе данных, блок диалога устанавливает в hDevNames глобальный дескриптор памяти для структуры DEVNAMES, которая содержит строки, определяющие выбор пользователя. Если выбор пользователя не доступен, диалоговое окно устанавливает hDevNames в значение ПУСТО (NULL).
Flags
Набор битовых флажков, который вы можете использовать, чтобы инициализировать стандартное диалоговое окно Параметры страницы (Page Setup). Когда блок диалога возвращает значение, он устанавливает эти флажки, чтобы обозначить ввод данных пользователем. Этот элемент может быть комбинацией следующих флажков:

  • PSD_DEFAULTMINMARGINS - Устанавливаются минимальные значения, которые пользователь может определять для полей страницы, чтобы они были минимальными полями страницы, допустимыми для принтера. Эти значения определяются по умолчанию. Этот флажок игноририруется, если определены также флажки PSD_MARGINS и PSD_MINMARGINS.
  • PSD_DISABLEMARGINS - Отключает элементы управления полями страницы, не допуская пользователя к настройкам полей страницы.
  • PSD_DISABLEORIENTATION - Отключает элементы управления ориентации, не допуская пользователя к настройкам ориентации страницы.
  • PSD_DISABLEPAGEPAINTING - Не допускает диалоговое окно к рисованию содержания макета страницы. Если вы включаете фильтр (hook) - процедуру PagePaintHook, то все еще можете рисовать содержание макета страницы.
  • PSD_DISABLEPAPER - Отключает элементы управления бумагой, не допуская пользователя к настройкам параметров страницы таких как размер бумаги и её источник.
  • PSD_DISABLEPRINTER - Отключает кнопку Печать (Printer), не допуская пользователя к вызову диалогового окна, которое содержит дополнительную информацию о настройках принтера.
  • PSD_ENABLEPAGEPAINTHOOK - Включает фильтр (hook) - процедуру, определяемую в элементе lpfnPagePaintHook.
  • PSD_ENABLEPAGESETUPHOOK - Включает фильтр (hook) - процедуру, определяемую в элементе lpfnPageSetupHook.
  • PSD_ENABLEPAGESETUPTEMPLATE - Указывает, что элементы hInstance и lpPageSetupTemplateName определяют шаблон диалогового окна, который используетсяся вместо шаблона заданного по умолчанию.
  • PSD_ENABLEPAGESETUPTEMPLATEHANDLE - Указывает, что элемент hPageSetupTemplate идентифицирует блок данных, который содержит предварительно загруженный шаблон диалогового окна. Система игнорирует элемент lpPageSetupTemplateName, если этот флажок установлен.
  • PSD_INHUNDREDTHSOFMILLIMETERS - Указывает, что 1/100 миллиметра является единицей измерения для полей страницы и размера бумаги. Значения в элементах rtMargin, rtMinMargin и ptPaperSize находятся в сотых долях миллиметра. Вы можете установить этот флажок при вводе данных, чтобы заменить заданную по умолчанию единицу измерения для региона пользователя. Когда функция возвращает значение, диалоговое окно устанавливает этот флажок, чтобы указать используемые единицы измерения.
  • PSD_INTHOUSANDTHSOFINCHES - Указывает, что тысячные части дюймов - единица измерения для полей страницы и размера бумаги. Значения в элементах rtMargin, rtMinMargin и ptPaperSize находятся в тысячных долях дюйма. Вы можете установить этот флажок при вводе данных, чтобы заменить заданную по умолчанию единицу измерения для региона пользователя. Когда функция возвращает значение, диалоговое окно устанавливает этот флажок, чтобы указать используемые единицы измерения.
  • PSD_INWININIINTLMEASURE - Не выполняется.
  • PSD_MARGINS - Заставляет систему использовать значения, определяемые в элементе rtMargin как начальные размеры для левого, верхнего, правого и нижнего поля страницы. Если флажок PSD_MARGINS не установлен, система устанавливает начальные размеры в один дюйм для всех полей страницы.
  • PSD_MINMARGINS - Вынуждает систему использовать значения, определяемые в элементе rtMinMargin как минимально допустимые размеры для левого, верхнего, правого, и нижнего поля страницы. Система не разрешает пользователю ввод ширины, которая является меньше чем определяемый минимум. Если флажок PSD_MINMARGINS не установлен, система устанавливает минимальные допустимые размеры в которые разрешены для принтера.
  • PSD_NOWARNING - Не разрешает системе отображать на экране предупреждающее сообщение, когда нет никакого заданного по умолчанию принтера.
  • PSD_RETURNDEFAULT - Функция PageSetupDlg не показывает на экране диалоговое окно. Вместо этого, она устанавливает в элементах hDevNames и hDevMode дескрипторы структур DEVMODE и DEVNAMES, которые инициализированы системой как принтер по умолчанию. PageSetupDlg возвращает значение ошибки, если, или hDevNames, или hDevMode не имеют значение ПУСТО (NULL).
  • PSD_SHOWHELP - Заставляет диалоговое окно показать на экране кнопку Справка (Help). Элемент hwndOwner должен определить окно, принимающее зарегистрированные сообщения HELPMSGSTRING , которые блок диалога передает, когда пользователь щелкает мышью по кнопке Справка (Help).

ptPaperSize
Определяет размеры бумаги, выбранные пользователем. Флажок PSD_INTHOUSANDTHSOFINCHES или PSD_INHUNDREDTHSOFMILLIMETERS обозначает единицы измерения.
rtMinMargin
Определяет минимально допустимые размеры для левого, верхнего, правого и нижнего поля страницы. Система игнорирует этот элемент, если флажок PSD_MINMARGINS не установлен. Эти значения должны быть меньше или равны значениям, определяемым в элементе rtMargin. Флажок PSD_INTHOUSANDTHSOFINCHES или PSD_INHUNDREDTHSOFMILLIMETERS обозначает единицы измерения.
rtMargin
Определяет размеры левого, верхнего, правого, и нижнего поля страницы. Если вы устанавливаете флажок PSD_MARGINS, rtMargin определяет начальные значения полей страницы. Когда PageSetupDlg возвращает значение, rtMargin содержит размеры полей страницы, выбранные пользователем. Флажок PSD_INHUNDREDTHSOFMILLIMETERS или PSD_INTHOUSANDTHSOFINCHES обозначает единицы измерения.
hInstance
Если в элементе Flags установлен флажок PSD_ENABLEPAGESETUPTEMPLATE, hInstance - дескриптор прикладной программы или экземпляра модуля, который содержит шаблон диалогового окна, именованный элементом lpPageSetupTemplateName.
lCustData
Устанавливает определяемые программой данные о том, что система передает фильтр (hook) - процедуру, идентифицированную lpfnPageSetupHook элементом. Когда система передает сообщение WM_INITDIALOG фильтр (hook) - процедуре, параметр сообщения lParam - указатель на структуру PAGESETUPDLG, которая была определена, когда диалоговое окно было создано. Фильтр (hook) - процедура может использовать этот указатель, чтобы получить значение элемента lCustData.
lpfnPageSetupHook
Указатель на фильтр (hook) - процедуру PageSetupHook, которая может обрабатывать сообщения, предназначенные для диалогового окна. Если в элементе Flags, флажок PSD_ENABLEPAGESETUPHOOK не установлен, этот элемент игнорируется.
lpfnPagePaintHook
Указатель на фильтр (hook) - процедуру PagePaintHook, которая принимает сообщения WM_PSD_* от диалогового окна всякий раз, когда перерисовывается макет страницы. Обрабатывая сообщения, фильтр (hook) - процедура может настраивать внешний вид макета страницы. Этот элемент игнорируется, если в элементе Flags флажок PSD_ENABLEPAGEPAINTHOOK не установлен.
lpPageSetupTemplateName
Указатель на строку с символом нуля в конце, которая именует ресурс шаблона диалогового окна в модуле, идентифицированном элементом hInstance. Этот шаблон замещает стандартный шаблон блока диалога. Для пронумерованных ресурсов диалогового окна, lpPageSetupTemplateName может быть значением, возвращенным макрокомандой MAKEINTRESOURCE. Этот элемент игнорируется, если в элементе Flags флажок PSD_ENABLEPAGESETUPTEMPLATE не установлен.
hPageSetupTemplate
Если флажок PSD_ENABLEPAGESETUPTEMPLATEHANDLE установлен в элементе Flags, hPageSetupTemplate - дескриптор объекта памяти, содержащего шаблон диалогового окна.

Замечания
Если флажки PSD_INHUNDREDTHSOFMILLIMETERS и PSD_INTHOUSANDTHSOFINCHES не установлены, система делает запрос со значением LOCALE_IMEASURE региона гипотетического пользователя, чтобы обусловить единицу измерения (или одна сотая миллиметра или тысячные доли дюймов) для размеров полей страницы и размера бумаги.
Если и hDevNames и hDevMode имеют правильные дескрипторы, а название принтера, в элементе wDeviceOffset структуры DEVNAMES указано не такое, какое имя указано в элементе dmDeviceName структуры DEVMODE, система по умолчанию использует название указанное в элементе wDeviceOffset.>br>

Смотри также
DEVMODE, DEVNAMES, MAKEINTRESOURCE, PagePaintHook, PageSetupDlg, PageSetupHook, WM_INITDIALOG

Размещение и совместимость PAGESETUPDLG

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				WinNT
Замечания по платформе		Не имеется


4.36.3.7 - Структура PRINTDLG

Структура PRINTDLG содержит информацию о том, что функция PrintDlg используется, чтобы инициализировать стандартное диалоговое окно Печать (Print). После того, как пользователь закрывает блок диалога, система возвращает информацию об определяемом пользователем выборе печати в этой структуре.

Синтаксис

typedef struct tagPD
{
    DWORD lStructSize;
    HWND hwndOwner;
    HANDLE hDevMode;
    HANDLE hDevNames;
    HDC hDC;
    DWORD Flags;
    WORD nFromPage;
    WORD nToPage;
    WORD nMinPage;
    WORD nMaxPage;
    WORD nCopies;
    HINSTANCE hInstance;
    DWORD lCustData;
    LPPRINTHOOKPROC lpfnPrintHook;
    LPSETUPHOOKPROC lpfnSetupHook;
    LPCTSTR lpPrintTemplateName;
    LPCTSTR lpSetupTemplateName;
    HANDLE hPrintTemplate;
    HANDLE hSetupTemplate;
} PRINTDLG;

Элементы
lStructSize
Определяет размер структуры, в байтах.
hwndOwner
Идентифицирует окно, которое владеет блоком диалога. Этот элемент может быть любым допустимым дескриптором окна, или это может быть значение ПУСТО (NULL), если диалоговое окно не имеет никакого владельца.
hDevMode
Идентифицирует перемещаемый объект глобальной памяти, который содержит структуру DEVMODE. Перед вызовом функции PrintDlg, элементы структуры могут содержать данные, используемые, чтобы инициализировать элементы управления диалогового окна. Когда PrintDlg возвращает значение, элементы структуры определяют состояние управляющих элементов диалогового окна.
Если вы используете структуру, чтобы инициализировать управляющие элементы диалогового окна, вы должны распределить доступное пространство памяти и создать структуру DEVMODE. (Вы должны распределить перемещаемый блок памяти).
Если вы не используете структуру, чтобы инициализировать управляющие элементы диалогового окна, hDevMode может иметь значение ПУСТО (NULL). В этом случае, PrintDlg распределяет память для структуры, инициализирует ее элементы и возвращает дескриптор, который идентифицирует структуру.
Если драйвер устройства для определяемого принтера не поддерживает расширенные режимы устройства, когда PrintDlg возвращает значение,то элемент hDevMode имеет значение ПУСТО (NULL).
Если имя устройства (определенное элементом dmDeviceName структуры DEVMODE) не появляется в разделе [devices (устройства)] WIN.INI, PrintDlg возвращает значение ошибки.
Потому что эта структура - перемещаемый объект глобальной памяти, значение которого в hDevMode может изменяться в ходе выполнения PrintDlg.
Для обсуждения того, как система решает возможный конфликт на уровне данных между значениями определеными элементами hDevMode и hDevNames, см. следующий раздел Замечаний.
hDevNames DEVNAMES. Эта структура содержит три строки, которые определяют название драйвера, название принтера и имя порта вывода данных. Перед вызовом PrintDlg, элементы структуры содержат строки, используемые, чтобы инициализировать управляющие элементы диалогового окна. Когда PrintDlg возвращает значение, элементы структуры содержат строки, введенные с клавиатуры пользователем. Вызывающая прикладная программа использует эти строки, чтобы создать контекст устройства или информационный контекст.
Если вы используете структуру, чтобы инициализировать управляющие элементы диалогового окна, то должны распределить доступную память и создать структуру DEVNAMES. (Вы должны разместить перемещаемый блок общей памяти.)
Если вы не используете структуру, чтобы инициализировать управляющие элементы диалогового окна, hDevNames может иметь значение ПУСТО (NULL). В этом случае, PrintDlg распределяет память для структуры, инициализирует элементы (при помощи использования названия принтера, определяемого в структуре DEVMODE) и возвращает дескриптор, который идентифицирует ее. Функция PrintDlg использует первое название порта, которое принято в разделе [devices устройств] WIN.INI, когда она инициализирует элементы в структуре DEVNAMES. Например, функция использует "LPT1:" как имя порта, если следующая строка применена в разделее [devices устройств]:

PCL / HP LaserJet=HPPCL,LPT1:,LPT2:

Если и hDevMode, и hDevNames имеют значение ПУСТО (NULL), PrintDlg инициализирует hDevNames, используя текущий принтер, заданный по умолчанию.
Поскольку эта структура - перемещаемый объект глобальной памяти, значение hDevNames может изменяться в ходе выполнения PrintDlg.
Для обсуждения того, как система решает возможный конфликт на уровне данных между значениями определяемыми hDevNames и hDevMode, см. раздел Замечаний позже в этой статье.
hDC
Идентифицирует контекст устройства или информационный контекст, в зависимости от того, определяет ли элемент Flags флажок PC_RETURNIC или PD_RETURNDC. Если никакой флажок не установлен, значение этого элемента неопределено. Если оба флажка установлены, флажок PD_RETURNDC имеет приоритет.
Flags
Набор битовых флажков, который вы можете использовать, чтобы инициализировать стандартное диалоговое окно Печать (Print). Когда блок диалога возвращает значение, он устанавливает эти флажки, чтобы обозначить ввод данных пользователем. Этот элемент может быть комбинацией следующих флажков:

  • PD_ALLPAGES - Заданный по умолчанию флажок, который обозначает, что вначале была выбрана радио-кнопка Все (All). Этот флажок используется как символ - заместитель, чтобы обозначить, что флажки PD_PAGENUMS и PD_SELECTION не определены.
  • PD_COLLATE - Когда установливается ввод данных, ставит "галочку" в окошке метки Разложить по копиям (Collate),. Когда функция PrintDlg возвращает значение, этот флажок обозначает, что пользователь выбрал параметр Разложить по копиям (Collate), а драйвер принтера не поддерживает комплектовку. В данном случае, прикладная программа должна обеспечить комплектовку. Если функция PrintDlg устанавливает флажок PD_COLLATE при возврате значения, элемент dmCollate структуры DEVMODE неопределен.
  • PD_DISABLEPRINTTOFILE - Отключает окошко отмечаемого блока Печать в файл (Print to File).
  • PD_ENABLEPRINTHOOK - Включает фильтр (hook) - процедуру, определяемую в элементе lpfnPrintHook. Это включение разрешает работу фильтр (hook) - процедуры для диалогового окна Печать (Print).
  • PD_ENABLEPRINTTEMPLATE - Обозначает, что элементы hInstance и lpPrintTemplateName определяют шаблон диалогового окна, который используется вместо заданного по умолчанию шаблона для диалогового окна Печать (Print).
  • PD_ENABLEPRINTTEMPLATEHANDLE - Обозначает, что элемент hPrintTemplate идентифицирует блок данных, который содержит предварительно загруженный шаблон диалогового окна. Система использует этот шаблон вместо заданного по умолчанию шаблона для диалогового окна Печать (Print). Система игнорирует элемент lpPrintTemplateName, если этот флажок определен.
  • PD_ENABLESETUPHOOK - Включает фильтр (hook) - процедуру, определяемую в элементе lpfnSetupHook. Флажок включает фильтр (hook) - процедуру для диалогового окна Параметры печати (Print Setup).
  • PD_ENABLESETUPTEMPLATE - Обозначает, что элементы hInstance и lpSetupTemplateName определяют шаблон диалогового окна, который используется вместо заданного по умолчанию шаблона для диалогового окна Параметры печати (Print Setup).
  • PD_ENABLESETUPTEMPLATEHANDLE - Обозначает, что элемент hSetupTemplate идентифицирует блок данных, который содержит предварительно загруженный шаблон диалогового окна. Система использует этот шаблон вместо заданного по умолчанию шаблона для диалогового окна Параметры печати (Print Setup). Система игнорирует элемент lpSetupTemplateName, если этот флажок определен.
  • PD_HIDEPRINTTOFILE - Скрывает окошко отмечаемого блока Печатать в файл (Print to File).
  • PD_NOPAGENUMS - Отключает радио-кнопки блока Страницы (Pages) и связанные с ним поля редактирования текста.
  • PD_NOSELECTION - Отключает радио-кнопку Выделенный фрагмент (Selection).
  • PD_NOWARNING - Не допускает показа предупреждающего сообщения на экране, когда нет никакого заданного по умолчанию принтера.
  • PD_PAGENUMS - Заставляет радио-кнопки блока Страницы (Pages), быть в выбранном состоянии, когда диалоговое окно создано. Когда функция PrintDlg возвращает значение, этот флажок установливает радио-кнопки блока Страницы (Pages) находится в выбранном состоянии.
  • PD_PRINTSETUP - Заставляет систему показать на экране диалоговое окно Параметры печати (Print Setup), а не диалоговое окно Печать (Print).
  • PD_PRINTTOFILE - Заставляет окошко отмечаемого блока Печать в файл(Print to File) быть отмеченым "галочкой", когда диалоговое окно создано. Когда функция PrintDlg возвращает значение, этот флажок установлен, если окошко отмечено "галочкой". В данном случае, смещение, указанное элементом wOutputOffset структуры DEVNAMES содержит строку " ФАЙЛ: ". Когда вы вызываете функцию StartDoc, чтобы начать операцию печати, определите эту строку " ФАЙЛ: " в элементе lpszOutput структуры DOCINFO. Определение этой строки вынуждает) подсистему печати сделать запрос пользователю, чтобы он определил название выходного файла.
  • PD_RETURNDC - Заставляет функцию PrintDlg возвратить контекст устройства, соответствующий выбору пользователя, сделанному в диалоговом окне. Контекст устройства возвращается в hDC.
  • PD_RETURNDEFAULT - Функция PrintDlg не показывает на экране диалоговое окно. Вместо этого, она устанавливает в элементах hDevNames и hDevMode дескрипторы структур DEVMODE и DEVNAMES, которые инициализированы для системного принтера по умолчанию. И hDevNames, и hDevMode должны иметь значение ПУСТО (NULL), или PrintDlg возвратит значение ошибки. Если системный по умолчанию принтер поддерживается старым драйвером принтера (ранее чем версия 3.0 Windows), значение возвращает только hDevNames; у элемента hDevMode - значение ПУСТО (NULL).
  • PD_RETURNIC - Подобен флажку PD_RETURNDC, за исключением того, что этот флажок возвращает информационный контекста не контекст устройства. Если ни PD_RETURNDC ни PD_RETURNIC не определен, hDC при выводе данных неопределен.
  • PD_SELECTION - Заставляет блок радио-кнопок Выбор (Selection) быть в выбранном состоянии, когда диалоговое окно создано. Когда PrintDlg возвращает значение, если радио-кнопка в блоке Выбор (Selection) выбрана, этот флажок определен. Если ни флажок PD_PAGENUMS, ни флажок PD_SELECTION не установлен, то выбрана радио-кнопка Все (All).
  • PD_SHOWHELP - Заставляет диалоговое окно показать на экране кнопку Справка (Help). Элемент hwndOwner должен определить окно, чтобы принять зарегистрированные сообщения HELPMSGSTRING, которые блок диалога передает, когда пользователь щелкает кнопкой мыши по кнопке Справка (Help).
  • PD_USEDEVMODECOPIES - Такой же как PD_USEDEVMODECOPIESANDCOLLATE
  • PD_USEDEVMODECOPIESANDCOLLATE - Отключает поле редактирования текста Число копий (Copies), если драйвер принтера не поддерживает многочисленные копии, и отключает переключатель Разложить по копиям (Collate), если драйвер принтера не поддерживает комплектовку. Если этот флажок не определен, PrintDlg сохраняет выбор пользователем параметров Число копий (Copies) и Разложить по копиям (Collate) в элементах dmCopies и dmCollate структуры DEVMODE. Если этот флажок не установлен, информация о копировании и раскладке по копиям возвращается в структуре DEVMODE, если драйвер поддерживает многочисленные копии и комплектовку. Если драйвер не поддерживает многочисленные копии и комплектовку, информация возвращается в структуре PRINTDLG. Это означает, что прикладная программа должна только рассмотреть nCopies и PD_COLLATE, чтобы установить, сколько копий требуется выполнить и требуется ли при печатати раскладывать их по копиям.

nFromPage
Определяет исходное значение для начального поля редактирования текста страницы. Когда функция PrintDlg возвращает значение, элемент nFromPage определяет, что начальная страница задана пользователем. Это значение правильно, только в том случае, если определен флажок PD_PAGENUMS.
nToPage
Определяет исходное значение для конечного поля редактирования текста страницы. Когда функция PrintDlg возвращает значение, элемент nToPage определяет, что конечная страница задана пользователем. Это значение правильно, только в том случае, если определен флажок PD_PAGENUMS.
nMinPage
Определяет минимальное значение для диапазона страниц, определяемых в редактируемых полях От (From) и До (To).
nMaxPage
Определяет максимальное значение для диапазона страниц, определяемых в редактируемых полях От (From) и До (To).
nCopies
Если элемент hDevMode имеет значение ПУСТО (NULL), то содержит исходный тираж для поля редактирования в блоке Копии (Copies); иначе, элемент dmCopies структуры DEVMODE содержит начальное значение. Когда PrintDlg возвращает значения, этот элемент содержит фактический тираж для печати. Если драйвер принтера не поддерживает многочисленные копии, это значение может быть большее чем одна копия и прикладная программа должна отпечатать все запрошенные копии. Если в элементе Flags установлено значение PD_USEDEVMODECOPIESANDCOLLATE, nCopies, при возврате, всегда устанавливается в 1, а элемент dmCopies в DEVMODE принимает фактический тираж, для печати.
hInstance
Если в элементе Flags установлен флажок PD_ENABLEPRINTTEMPLATE или PD_ENABLESETUPTEMPLATE, hInstance - дескриптор прикладной программы или экземпляра модуля, который содержит шаблон диалогового окна, именованный элементом lpPrintTemplateName или lpSetupTemplateName.
lCustData
Устанавливает определяемые программой данные, которые система передает фильтр (hook) - процедуре, идентифицированной элементом lpfnPrintHook или lpfnSetupHook. Когда система посылает сообщение WM_INITDIALOG фильтр (hook) - процедуре, параметр сообщения lParam - указатель на структуру PRINTDLG, которая была определена, когда диалоговое окно было создано. Фильтр (hook) - процедура может использовать этот указатель, чтобы получить значение lCustData.
lpfnPrintHook
Указатель на фильтр (hook) - процедуру PrintHookProc, которая может обрабатывать сообщения, предназначенные для диалогового окна Печать (Print). Этот элемент игнорируется, если в элементе Flags не установлен флажок PD_ENABLEPRINTHOOK.
lpfnSetupHook
Указатель на фильтр (hook) - процедуру SetupHookProc, которая может обрабатывать сообщения, предназначенные для диалогового окна Параметры печати (Print Setup). Этот элемент игнорируется, если в элементе Flags не установлен флажок PD_ENABLESETUPHOOK.
lpPrintTemplateName
Указатель на строку с символом нуля в конце, которая именует ресурс шаблона диалогового окна в модуле, идентифицированном элементом hInstance. Этот шаблон замещает стандартный шаблон диалогового окна Печать (Print). Этот элемент игноририруется, если в элементе Flags не установлен флажок PD_ENABLEPRINTTEMPLATE.
lpSetupTemplateName
Указатель на строку с символом нуля в конце, которая именует ресурс шаблона диалогового окна в модуле, идентифицированном элементом hInstance. Этот шаблон замещает стандартный шаблон диалогового окна Параметры печати (Print Setup). Этот элемент игноририруется, если в Элементе Flags не установлен флажок PD_ENABLESETUPTEMPLATE.
hPrintTemplate
Если в элементе Flags установлен флажок PD_ENABLEPRINTTEMPLATEHANDLE, hPrintTemplate - дескриптор объекта памяти, содержащего шаблон диалогового окна. Этот шаблон замещает стандартный шаблон диалогового окна Печать (Print).
hSetupTemplate
Если в элементе Flags установлен флажок PD_ENABLESETUPTEMPLATEHANDLE, hSetupTemplate - дескриптор объекта памяти, содержащего шаблон диалогового окна. Этот шаблон замещает стандартный шаблон диалогового окна Параметры печати (Print Setup).

Замечания
Имеется возможность конфликта на уровне данных между значениями, определяемыми элементами hDevNames и hDevMode, потому что элемент wDeviceOffset структуры DEVNAMES, как предполагается, является идентичным элементу dmDeviceName структуры DEVMODE. Если это не так, система решает конфликт на уровне данных при помощи использования значения wDeviceOffset.
Если пользователь отмечает "галочкой" окошко метки Разобрать по копиям (Collate) в стандартном диалоговом окне Печать (Print), но драйвер принтера не поддерживает комплектовку, элемент Flags структуры PRINTDLG, возвращенный при помощи PrintDlg включает в себя флажок PD_COLLATE. Кроме того, элемент dmCollate структуры DEVMODE, идентифицированной элементом hDevMode установливается в COLLATE_TRUE. Если флажок PD_COLLATE установлен, прикладная программа должна симулировать комплектовку.
Если флажок PD_USEDEVMODECOPIESANDCOLLATE установлен, окошко метки Разобрать по копиям (Collate) внешне недоступно, если драйвер принтера не поддерживает комплектовку. Это гарантирует то, что пользователь может только выбирать одну копию, и в элементе nCopies будет единица. Если драйвер поддерживает многочисленные копии, dmCopies будет содержать тираж, а в nCopies будет единица.
При записи в функцию PrintDlg, элемент nCopies структуры PRINTDLG определяет тираж, если флажок PD_USEDEVMODECOPIESANDCOLLATE не установлен. При выходе из PrintDlg, nCopies содержит тираж, если драйвер принтера не поддерживает многочисленные копии. Иначе он устанавливается в единицу. Если nCopies больше чем единица при выходе из PrintDlg, прикладная программа должна отпечатать многочисленные копии документа.

Смотри также
CreateDC, CreateIC, PrintDlg, DEVMODE, DEVNAMES, WM_INITDIALOG

Размещение и совместимость PRINTDLG

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winspool.h
Unicode				WinNT
Замечания по платформе		Не имеется


4.36.3.8 - Структура OFNOTIFY

[Теперь поддерживается в Windows NT]

Структура OFNOTIFY содержит информацию о сообщении WM_NOTIFY, которое передается фильтр - процедуре диалоговым окном Открыть (Open) или Сохранить как (Save As) в стиле Проводника. Адрес структуры OFNOTIFY посылается как параметр lParam сообщения WM_NOTIFY.

Синтаксис

typedef struct _OFNOTIFY
{
    NMHDR hdr;
    LPOPENFILENAME lpOFN;
    LPTSTR pszFile;
} OFNOTIFY, FAR *LPOFNOTIFY;

Элементы
hdr
Определяет структуру NMHDR. Код элемента структуры NMHDR может быть одним из следующих кодов уведомления, которые идентифицируют передаваемое сообщение: CDN_FILEOK, CDN_FOLDERCHANGE, CDN_HELP, CDN_INITDONE, CDN_SELCHANGE, CDN_SHAREVIOLATION, CDN_TYPECHANGE.
lpOFN
Указатель на структуру OPENFILENAME, которая была определена, когда было создано диалоговое окно Открыть (Open) или Сохранить как (Save As). Для некоторых из уведомительных сообщений, эта структура содержит дополнительную информацию относительно события, которое стало причиной уведомления.
pszFile
Указатель на имя файла, для которого произошла сетевая ошибка совместного доступа. Этот элемент допустим только с уведомительным сообщением CDN_SHAREVIOLATION.

Смотри также
CDN_FILEOK, CDN_FOLDERCHANGE, CDN_HELP, CDN_INITDONE, CDN_SELCHANGE, CDN_SHAREVIOLATION, CDN_TYPECHANGE, NMHDR, OPENFILENAME

Размещение и совместимость OFNOTIFY

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				Нет
Замечания по платформе		Не имеется


4.36.4 - Сообщения стандартного диалогового окна

Следующие константы идентифицируют строки, которые вы можете использовать с функцией RegisterWindowMessage, чтобы получить идентификатор сообщения. Вы можете использовать эти коды сообщений, чтобы передавать или принимать сообщения от стандартных блоков диалога.
COLOROKSTRING
FILEOKSTRING
FINDMSGSTRING
HELPMSGSTRING
LBSELCHSTRING
SETRGBSTRING
SHAREVISTRING

Ниже - сообщения, которые вы можете передавать диалоговому окну Шрифт (Font).
WM_CHOOSEFONT_GETLOGFONT
WM_CHOOSEFONT_SETFLAGS
WM_CHOOSEFONT_SETLOGFONT

Ниже - сообщения, которые передает диалоговое окно Параметры страницы (Page Setup) определяемой программой фильтр - процедуре PagePaintHook.
WM_PSD_ENVSTAMPRECT
WM_PSD_FULLPAGERECT
WM_PSD_GREEKTEXTRECT
WM_PSD_MARGINRECT
WM_PSD_MINMARGINRECT
WM_PSD_PAGESETUPDLG
WM_PSD_YAFULLPAGERECT

Ниже - сообщения, которые фильтр - процедура может посылать диалоговому окну в стиле Проводника Открыть (Open) или Сохранить как (Save As).
CDM_GETFILEPATH
CDM_GETFOLDERIDLIST
CDM_GETFOLDERPATH
CDM_GETSPEC
CDM_HIDECONTROL
CDM_SETCONTROLTEXT
CDM_SETDEFEXT

Ниже - уведомительные сообщения, которые диалоговое окно в стиле Проводника Открыть (Open) или Сохранить как (Save As) могут посылаться фильтр - процедуре.
CDN_FILEOK
CDN_FOLDERCHANGE
CDN_HELP
CDN_INITDONE
CDN_SELCHANGE
CDN_SHAREVIOLATION
CDN_TYPECHANGE


4.36.4.1 - Зарегистрированное сообщение COLOROKSTRING

Диалоговое окно Цвет (Color) передает зарегистрированное сообщение COLOROKSTRING вашей фильтр - процедуре, когда пользователь выбирает цвет и щелкает мышью по кнопке OK. Фильтр - процедура может принять цвет и позволить блоку диалога закрыться, или отклонить цвет и заставить диалоговое окно оставаться открытым.

Синтаксис

MessageID = RegisterWindowMessage(COLOROKSTRING);
wParam = 0;
lpcc = (LPCHOOSECOLOR) lParam;

Параметры
lpcc
Указатель на структуру CHOOSECOLOR. Элемент rgbResult этой структуры содержит значения RGB выбранного цвета.

Возвращаемые значения
Если фильтр - процедура возвращает значение нуль, блок диалога Цвет (Color) принимает выбранный цвет и закрывается.
Если фильтр - процедура возвращает значение не нуль, диалоговое окно Цвет (Color) отклоняет выбранный цвет и остается открытым.

Замечания
Фильтр - процедура должна определить константу COLOROKSTRING при вызове функции RegisterWindowMessage, чтобы получить идентификатор для сообщения, переданного диалоговым окном.

Смотри также
CHOOSECOLOR, RegisterWindowMessage

Размещение и совместимость COLOROKSTRING

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				WinNT
Замечания по платформе		Не имеется


4.36.4.2 - Зарегистрированное сообщение FILEOKSTRING

Диалоговое окно Открыть (Open) или Сохранить как (Save As) передает зарегистрированное сообщение FILEOKSTRING вашей фильтр - процедуре, когда пользователь определяет имя файла и щелкает мышью по кнопке OK. Фильтр - процедура может принять имя файла и позволить блоку диалога закрыться, или отклонить имя файла и заставить диалоговое окно оставаться открытым.

В диалоговых окнах Открыть (Open) и Сохранить как (Save As) стиле Проводника это сообщение было заменено уведомительным сообщением CDN_FILEOK.

Синтаксис

MessageID = RegisterWindowMessage(FILEOKSTRING);
wParam = 0;
lpofn = (LPOPENFILENAME) lParam;

Параметры
lpofn
Указатель на структуру OPENFILENAME. Элемент lpstrFile этой структуры содержит диск, путь и имя файла указанное пользователем.

Возвращаемые значения
Если фильтр - процедура возвращает значение нуль, диалоговое окно Открыть (Open) или Сохранить как (Save As) принимает заданное имя файла и закрывается.
Если фильтр - процедура возвращает значение отличное от нуля, диалоговое окно Открыть (Open) или Сохранить как (Save As) отклоняет заданное имя файла и остается открытым.

Замечания
Фильтр - процедура должна определить константу FILEOKSTRING при вызове функции RegisterWindowMessage, чтобы получить идентификатор для сообщения, переданного диалоговым окном.

Смотри также
CDN_FILEOK, OPENFILENAME, RegisterWindowMessage

Размещение и совместимость FILEOKSTRING

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			-
Заголовочный файл				commdlg.h
Unicode					WinNT
Замечания по платформе			Не имеется


4.36.4.3 - Зарегистрированное сообщение FINDMSGSTRING

Диалоговое окно Найти (Find) или Заменить (Replace) передает зарегистрированное сообщение FINDMSGSTRING в оконную процедуру окна, которое им владеет тогда, когда пользователь щелкает мышью по кнопке Найти далее (Find Next), Заменить (Replace) или Заменить все (Replace All), или закрывает блок диалога.

Синтаксис

MessageID = RegisterWindowMessage(FINDMSGSTRING);
wParam = 0;
lpfr = (LPFINDREPLACE) lParam;

Параметры
lpfr
Указатель на структуру FINDREPLACE. Элементы этой структуры содержат последние данные, введенные пользователем, которые включают в себя последовательность символов для поиска, последовательность символов на замену (если надо) и параметры поиска и замены.

Возвращаемые значения
Возвращаемых значений нет.

Замечания
Вы должны определить константу FINDMSGSTRING при вызове функции RegisterWindowMessage, чтобы получить идентификатор для сообщения, переданного диалоговым окном.
Когда вы создаете блок диалога, чтобы идентифицировать окно, которое примет сообщения FINDMSGSTRING, используете элемент hwndOwner структуры FINDREPLACE.
Элемент Flags структуры FINDREPLACE включает в себя один из следующих флажков, чтобы указать событие, которое стало причиной сообщения:

  • FR_DIALOGTERM - Диалоговое окно закрывается. После того, как окно владельца обрабатывает это сообщение, дескриптор блока диалога больше не правилен.
  • FR_FINDNEXT - Пользователь нажал кнопку Найти далее (Find Next) в диалоговом окне Найти (Find) или Заменить (Replace). Элемент lpstrFindWhat определяет строку, для поиска.
  • FR_REPLACEALL - Пользователь нажал кнопку Заменить все (Replace All) в диалоговом окне Заменить (Replace). Элемент lpstrFindWhat определяет строку, которую надо заменить, а элемент lpstrReplaceWith определяет строку, которой надо заменить.

В сообщениях от кнопок Найти далее (Find Next) или Заменить все (Replace All), элемент Flags, чтобы обозначить параметры поиска, может включать любую комбинацию следующих флажков:

  • FR_DOWN - Если он установлен, среди "радио"-кнопок направления выбрана кнопка Вниз (Down), указывая, что пользователь хочет искать от текущего расположения курсора до конца документа. Если FR_DOWN не установлен, выбрана кнопка Вверх (Up), то есть пользователь хочет искать от курсора в начало документа.
  • FR_MATCHCASE - Если он установлен, в отмечаемом окошке С учетом регистра (Match Case) проставляется "галочка", указывая, что пользователь хочет, чтобы поиск был чувствительным к регистру. Если FR_MATCHCASE не установлен, окошко для флажка без "галочки", так что поиск должен осуществляться без учета регистра.
  • FR_WHOLEWORD - Если он установлен, в отмечаемом окошке Только слово целиком (Match Whole word only) проставляется "галочка", указывая, что пользователь хочет искать только целые слова, которые соответствуют строке для поиска. Если FR_WHOLEWORD не установлен, окошко для флажка без "галочки", так что вы должны также искать фрагменты слова, которые соответствуют строке для поиска.

Смотри также
FINDREPLACE, RegisterWindowMessage

Размещение и совместимость FINDMSGSTRING

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				WinNT
Замечания по платформе		Не имеется


4.36.4.4 - Зарегистрированное сообщение HELPMSGSTRING

Стандартное диалоговое окно передает зарегистрированное сообщение HELPMSGSTRING в оконную процедуру его окна владельца, когда пользователь щелкает мышью по кнопке Справка (Help).
Для диалоговых окон Открыть (Open) и Сохранить как (Save As) в стиле Проводника это сообщение было заменено предупредительным сообщением CDN_HELP.

Синтаксис

MessageID = RegisterWindowMessage(HELPMSGSTRING);
hdlg = (HWND) wParam;
lpStruct = (LPVOID) lParam;

Параметры
hdlg
Дескриптор стандартного диалогового окна.
lpStruct
Указатель на инициализированную структуру для стандартного диалогового окна. Этой структурой могут быть структуры CHOOSECOLOR, CHOOSEFONT, FINDREPLACE, OPENFILENAME, PRINTDLG или PAGESETUPDLG.

Возвращаемые значения
Возвращаемых значений нет.

Замечания
Вы должны определить константу HELPMSGSTRING при вызове функции RegisterWindowMessage, чтобы получить идентификатор для сообщения, переданного диалоговым окном.
Когда вы создаете блок диалога, чтобы идентифицировать окно, которое примет сообщения HELPMSGSTRING, используете элемент hwndOwner структуры инициализации.

Смотри также
CDN_HELP, CHOOSECOLOR, CHOOSEFONT, FINDREPLACE, OPENFILENAME, PRINTDLG, PAGESETUPDLG, RegisterWindowMessage

Размещение и совместимость HELPMSGSTRING

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				WinNT
Замечания по платформе		Не имеется


4.36.4.5 - Зарегистрированное сообщение LBSELCHSTRING

Диалоговое окно Открыть (Open) или Сохранить как (Save As) передает зарегистрированное сообщение LBSELCHSTRING вашей фильтр - процедуре, когда в каком-либо из окон списка или комбинированных блоков диалогового окна изменяется выбор.
В блоках диалога Открыть (Open) и Сохранить как (Save As) в стиле Проводника это сообщение было заменено сообщениями CDN_TYPECHANGE и CDN_SELCHANGE.

Синтаксис

MessageID = RegisterWindowMessage(LBSELCHSTRING);
idListBox = (UINT) wParam;
iItem = LOWORD (lParam);
iType = HIWORD (lParam);

Параметры
idListBox
Идентификатор окна списка или комбинированного блока, в котором изменился выбор.
iItem
Номер элемента выбранной строки в окне списка или комбинированном блоке.
iType
Тип изменения выбора. Этот параметр может быть одним из следующих значений:

  • CD_LBSELCHANGE - Элемент, идентифицированный iItem - единственный элемент, выбранный в окне списка с единственным элементом для выбора.
  • CD_LBSELADD - Элемент, идентифицированный iItem - один из элементов, выбранный в окне списка с многочисленными элементами для выбора.
  • CD_LBSELSUB - Элемент, идентифицированный iItem - больше не выбран в окне списка с многочисленными элементами для выбора.
  • CD_LBSELNOITEMS - В окне списка с многочисленными элементами для выбора элементов не существует.

Возвращаемые значения
Возвращаемых значений нет.

Замечания
Фильтр - процедура должна определить константу LBSELCHSTRING при вызове функции RegisterWindowMessage, чтобы получить идентификатор для сообщения, переданного диалоговым окном.

Смотри также
CDN_SELCHANGE, CDN_TYPECHANGE, RegisterWindowMessage

Размещение и совместимость LBSELCHSTRING

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				Нет
Замечания по платформе		Не имеется


4.36.4.6. - Зарегистрированное сообщение SETRGBSTRING

Фильтр - процедура диалогового окна Цвет (Color) может передавать зарегистрированное сообщение SETRGBSTRING блоку диалога, чтобы установить текущий выбранный цвет.

Синтаксис

MessageID = RegisterWindowMessage(SETRGBSTRING);
wParam = 0;
lParam = (COLORREF) rgbColor;

Параметры
rgbColor
Определяет значение RGB цвета, который выбран в диалоговом окне Цвет (Color). Вы можете использовать макрокоманду RGB, чтобы определить значение интенсивности RGB красного, зеленого и синего цвета.

Возвращаемые значения
Возвращаемых значений нет.

Замечания
Если rgbColor соответствует одному из основных цветов или одному из 16 дополнительных цветов, процедура диалогового окна выбирает этот цвет. Процедура диалогового окна также модифицирует все элементы управления в дополнительном пользовательском цвете блока диалога Цвет (Color), если оно открыто.
Если rgbColor не соответствует основному или дополнительному цвету, процедура диалогового окна не изменяет текущий выбранный цвет, но она обновляет цвет элементов управления, если они видимы.
Например, следующий типовой код получает код сообщения SETRGBSTRING, а затем устанавливает выбранный цвета в синий.

UINT uiSetRGB;
uiSetRGB = RegisterWindowMessage(SETRGBSTRING);
SendMessage(hwndDlg, uiSetRGB, 0, (LPARAM) RGB(0, 0, 255));

Смотри также
RegisterWindowMessage, RGB, SendMessage

Размещение и совместимость SETRGBSTRING

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				Нет
Замечания по платформе		Не имеется


4.36.4.7 - Зарегистрированное сообщение SHAREVISTRING

Диалоговое окно Открыть (Open) или Сохранить как (Save As) передает зарегистрированное сообщение SHAREVISTRING вашей фильтр - процедуре, если для выбранного файла происходит ошибка совместного доступа, когда пользователь щелкает мышью по кнопке OK.
В диалоговых окнах Открыть (Open) и Сохранить как (Save As) в стиле Проводника , это сообщение было заменено уведомительным сообщением CDN_SHAREVIOLATION.

Синтаксис

MessageID = RegisterWindowMessage(SHAREVISTRING);
wParam = 0;
lpofn = (LPOPENFILENAME) lParam;

Параметры
lpofn
Указатель на структуру OPENFILENAME. Элемент lpstrFile этой структуры содержит имя файла, которое стало причиной ошибки совместного доступа.

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

  • OFN_SHAREFALLTHROUGH - Согласится с именем файла.
  • OFN_SHARENOWARN - Отклоняется имя файла, но пользователь не предупреждается. Прикладная программа ответственна за отображение на экране предупреждающего сообщения.
  • OFN_SHAREWARN - Отклоняется имя файла и отображается предупреждающее сообщение (тот же самый результат, как будто нет никакой фильтр - процедуры).

Замечания
Фильтр - процедура должна определить константу SHAREVISTRING при вызове функции RegisterWindowMessage, чтобы получить идентификатор для сообщения, переданного блоком диалога.
Диалоговое окно передает зарегистрированное сообщение SHAREVISTRING, только тогда, если вы, когда создавали диалог, не определили флажок OFN_SHAREAWARE в элементе Flags структуры OPENFILENAME.
Если фильтр - процедура возвращает неопределенное значение, блок диалога отвечает, как если бы было возвращено значение OFN_SHAREWARN.

Смотри также
CDN_SHAREVIOLATION, OPENFILENAME, RegisterWindowMessage

Размещение и совместимость SHAREVISTRING

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				WinNT
Замечания по платформе		Не имеется


4.36.4.8 - Сообщение WM_CHOOSEFONT_GETLOGFONT

Сообщение WM_CHOOSEFONT_GETLOGFONT передается диалоговому окну Шрифт (Font), чтобы извлечь информацию о выборе текущего шрифта пользователем.

Синтаксис

WM_CHOOSEFONT_GETLOGFONT
wParam = 0;                	// не используется, должен быть нуль
lParam = (LPLOGFONT) lplf; 	// адрес структуры с данными шрифта

Параметры
lplf
Указатель на структуру LOGFONT, которая принимает информацию о выборе текущего шрифта пользователем.

Возвращаемые значения
Это сообщение не возвращает значений.

Замечания
Функция ChooseFont создает диалоговое окно Шрифт (Font). Когда пользователь закрывает этот блок диалога, функция ChooseFont возвращает информацию о выборе шрифта пользователем в структуре CHOOSEFONT. Элемент lpLogFont структуры CHOOSEFONT - указатель на структуру LOGFONT.
Используйте сообщение WM_CHOOSEFONT_GETLOGFONT, чтобы получить информацию о текущих выбранных шрифтах пользователем, пока диалоговое окно Шрифт (Font) открыто. Например, если вы включаете кнопку Применить (Apply) в этом блоке диалога, то передайте это сообщение, чтобы заставить информацию о шрифте применить к текущему выбранному тексту.
Как правило, вы даете возможность фильтр - процедуре CFHookProc обработать сообщения WM_COMMAND для кнопки Применить (Apply). Когда пользователь щелкает мышью по этой кнопке, фильтр - процедура передает сообщение WM_CHOOSEFONT_GETLOGFONT диалоговому окну.

Смотри также
CFHookProc, ChooseFont, CHOOSEFONT, LOGFONT, WM_COMMAND

Размещение и совместимость WM_CHOOSEFONT_GETLOGFONT

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека			-
Заголовочный файл			commdlg.h
Unicode				WinNT
Замечания по платформе		Не имеется


4.36.4.9 - Сообщение WM_CHOOSEFONT_SETFLAGS

Сообщение WM_CHOOSEFONT_SETFLAGS передается диалоговому окну Шрифт (Font), чтобы установить параметры отображения на экране блока диалога.

Синтаксис

WM_CHOOSEFONT_SETFLAGS
wParam = 0;                  			// не используется, должен быть нуль
lParam = (LPCHOOSEFONT) lpcf;	 		// адрес структуры с данными на флажки

Параметры
lpcf Указатель на структуру CHOOSEFONT, которая содержит в элементе Flags новые параметры настройки.

Возвращаемые значения
Возвращаемых значений нет.

Замечания
Функция ChooseFont создает диалоговое окно Шрифт (Font) и использует структуру CHOOSEFONT, чтобы определить начальные значения для элемента Flags. Сообщение WM_CHOOSEFONT_SETFLAGS используется, чтобы определить другие значения для элемента Flags, пока блок диалога Шрифт (Font) открыт.
Как правило, сообщение WM_CHOOSEFONT_SETFLAGS вы должны передать из фильтр - процедуры CFHookProc.

Смотри также
CFHookProc, ChooseFont, CHOOSEFONT

Размещение и совместимость WM_CHOOSEFONT_SETFLAGS

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				WinNT
Замечания по платформе		Не имеется


4.36.4.10 - Сообщение WM_CHOOSEFONT_SETLOGFONT

Сообщение WM_CHOOSEFONT_SETLOGFONT передается диалоговому окну Шрифт (Font), чтобы установить текущую информацию о логическом шрифте.

Синтаксис

WM_CHOOSEFONT_SETLOGFONT
wParam = 0;                			// не используется, должен быть нуль
lParam = (LPLOGFONT) lplf;	 		// адрес структуры с данными на шрифт

Параметры
lplf
Указатель на структуру LOGFONT, которая содержит информацию о текущем логическом шрифте.

Возвращаемые значения
Возвращаемых значений нет.

Замечания
Когда вы вызываете функцию ChooseFont, чтобы создать диалоговое окно Шрифт (Font), вы можете использовать элемент lpLogFont структуры CHOOSEFONT, чтобы определить структуру LOGFONT, содержащую начальные значения для блока диалога. Чтобы определить структуру LOGFONT с другими значениями, используйте сообщение WM_CHOOSEFONT_SETLOGFONT, пока диалоговое окно Шрифт (Font) открыто.
Как правило, сообщение WM_CHOOSEFONT_SETLOGFONT передается из фильтр - процедуры CFHookProc. Фильтр - процедура может также передавать сообщения WM_CHOOSEFONT_SETFLAGS и WM_CHOOSEFONT_GETLOGFONT.

Смотри также CFHookProc, ChooseFont, CHOOSEFONT, LOGFONT, WM_CHOOSEFONT_GETLOGFONT, WM_CHOOSEFONT_SETFLAGS

Размещение и совместимость WM_CHOOSEFONT_SETLOGFONT

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				WinNT
Замечания по платформе		Не имеется


4.36.4.11 - Сообщение WM_PSD_ENVSTAMPRECT

Сообщение WM_PSD_ENVSTAMPRECT уведомляет фильтр - процедуру диалогового окна Параметры страницы (Page Setup), что блок диалога собирается чертить прямоугольник марки конверта в шаблоне страницы.

Синтаксис

WM_PSD_ENVSTAMPRECT
hDC = (WPARAM) (HDC) wParam;                          	// дескриптор контекста устройства
lprcEnvStamp = (LPARAM) (LPRECT) lParam; 		// прямоугольник марки конверта

Параметры
hDC
Значение wParam. Идентифицирует контекст устройства для макета станицы.
lprcMargin
Значение lParam. Указатель на структуру RECT, которая содержит координаты, в пикселях, прямоугольника марки конверта.

Возвращаемые значения
Если фильтр - процедура возвращает значение ИСТИНА (TRUE), диалоговое окно не рисует блок марки конверта макета страницы.
Если фильтр - процедура возвращает значение ЛОЖЬ(FALSE), блок диалога рисует блок марки конверта макета страницы.

Замечания
Диалоговое окно Параметры страницы (Page Setup) включает в себя изображение макета страницы, который показывает, как выбор пользователя воздействуют на внешний вид напечатанного вывода информации. Когда вы вызываете функцию PageSetupDlg, то можете предоставить фильтр - процедуру PagePaintHook, чтобы настроить внешний вид макета страницы. Всякий раз, когда блок диалога собирается рисовать содержимое макета страницы, диалоговое окно передает последовательность сообщений WM_PSD* фильтр - процедуре.
Фильтр - процедура принимает это сообщение только тогда, если выбранный тип бумаги является конверт.

Смотри также
PagePaintHook, PageSetupDlg, RECT, WM_PSD_PAGESETUPDLG

Размещение и совместимость WM_PSD_ENVSTAMPRECT

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				WinNT
Замечания по платформе		Не имеется


4.36.4.12 - Сообщение WM_PSD_FULLPAGERECT

Сообщение WM_PSD_FULLPAGERECT ставит в известность фильтр - процедуру PagePaintHook о координатах прямоугольника макета страницы в диалоговом окне Параметры страницы (Page Setup). Блок диалога передает это сообщение, когда он собирается рисовать содержимое макета страницы.

Синтаксис

WM_PSD_FULLPAGERECT
hDC = (WPARAM) (HDC) wParam;         // дескриптор контекста устройства
lprcPage = (LPARAM) (LPRECT) lParam; // размеры прямоугольника страницы

Параметры
hDC
Значение wParam. Дескриптор контекста устройства для макета страницы.
lprcPage
Значение lParam. Указатель на структуру RECT, которая содержит координаты, в пикселях, макета страницы.

Возвращаемые значения
Если фильтр - процедура возвращает значение ИСТИНА (TRUE), диалоговое окно больше не передает сообщения WM_PSD* и не рисует в макете страницы до тех пор, пока в следующий раз системе не потребуется перерисовать макет страницы.
Если фильтр - процедура возвращает значение ЛОЖЬ(FALSE), блок диалога передает оставшиеся сообщения прядке следования прорисовки.

Замечания
Диалоговое окно Параметры страницы (Page Setup) включает в себя изображение макета страницы, который показывает, как выбор пользователя воздействуют на внешний вид напечатанного вывода информации. Когда вы вызываете функцию PageSetupDlg, вы можете предоставить фильтр - процедуру PagePaintHook, чтобы настроить внешний вид макета страницы. Всякий раз, когда блок диалога собирается рисовать содержимое макета страницы, диалоговое окно передает фильтр - процедуре последовательность сообщений WM_PSD*.

Смотри также
PagePaintHook, PageSetupDlg, RECT, WM_PSD_PAGESETUPDLG

Размещение и совместимость WM_PSD_FULLPAGERECT

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				WinNT
Замечания по платформе		Не имеется


4.36.4.13 - Сообщение WM_PSD_GREEKTEXTRECT

Сообщение WM_PSD_GREEKTEXTRECT уведомляет фильтр - процедуру диалогового окна Параметры страницы (Page Setup), что блок диалога собирается вывести внутри прямоугольника поля макета страницы греческий текст.

Синтаксис

WM_PSD_GREEKTEXTRECT
hDC = (WPARAM) (HDC) wParam;              // дескриптор контекста устройства
lprcGreekText = (LPARAM) (LPRECT) lParam; // прямоугольник греческого текста

Параметры
hDC
Значение wParam. Идентифицирует контекст устройства для макета страницы.
lprcMargin
Значение lParam. Указатель на структуру RECT, которая содержит координаты, в пикселях, прямоугольника греческого текста.

Возвращаемые значения
Если фильтр - процедура возвращает значение ИСТИНА (TRUE), диалоговое окно не выводит блок греческого текста в макет страницы.
Если фильтр - процедура возвращает ЛОЖЬ(FALSE), блок диалога выводит блок греческого текста в макет страницы.

Замечания
Диалоговое окно Параметры страницы (Page Setup) включает в себя изображение макета страницы, который показывает, как выбор пользователя воздействуют на внешний вид напечатанного вывода информации. Когда вы вызываете функцию PageSetupDlg, то можете предоставить фильтр - процедуру PagePaintHook, чтобы настроить внешний вид макета страницы. Всякий раз, когда блок диалога собирается рисовать содержимое макета страницы, диалоговое окно передает фильтр - процедуре последовательность сообщений WM_PSD*.

Смотри также
PagePaintHook, PageSetupDlg, RECT, WM_PSD_PAGESETUPDLG

Размещение и совместимость WM_PSD_GREEKTEXTRECT

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			-
Заголовочный файл				commdlg.h
Unicode					WinNT
Замечания по платформе			Не имеется


4.36.4.14 - Сообщение WM_PSD_MARGINRECT

Сообщение WM_PSD_MARGINRECT уведомляет фильтр - процедуру диалогового окна Параметры страницы (Page Setup), что блок диалога собирается рисовать прямоугольник поля макета страницы.

Синтаксис

WM_PSD_MARGINRECT
hDC = (WPARAM) (HDC) wParam;           	// дескриптор контекста устройства
lprcMargin = (LPARAM) (LPRECT) lParam; 	// прямоугольник поля

Параметры
hDC
Значение wParam. Идентифицирует контекст устройства для макета страницы.
lprcMargin
Значение lParam. Указатель на структуру RECT, которая содержит координаты, в пикселях, прямоугольника поля.

Возвращаемые значения
Если фильтр - процедура возвращает значение ИСТИНА (TRUE), диалоговое окно не чертит прямоугольник поля в макете страницы.
Если фильтр - процедура возвращает значение ЛОЖЬ(FALSE), блок диалога чертит прямоугольник поля в макете страницы.

Замечания
Диалоговое окно Параметры страницы (Page Setup) включает в себя изображение макета страницы, который показывает, как выбор пользователя воздействует на внешний вид напечатанного вывода информации. Когда вы вызываете функцию PageSetupDlg, то можете предоставить фильтр - процедуру PagePaintHook, чтобы настроить внешний вид макета страницы. Всякий раз, когда блок диалога собирается чертить содержимое макета страницы, диалоговое окно передает фильтр - процедуре последовательность сообщений WM_PSD*.

Смотри также
PagePaintHook, PageSetupDlg, RECT, WM_PSD_PAGESETUPDLG

Размещение и совместимость WM_PSD_MARGINRECT

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				WinNT
Замечания по платформе		Не имеется


4.36.4.15 - Сообщение WM_PSD_MINMARGINRECT

Сообщение WM_PSD_MINMARGINRECT ставит в известность фильтр - процедуру PagePaintHook о координатах прямоугольника поля в макете страницы. Диалоговое окно Параметры страницы (Page Setup) передает это сообщение, когда оно собирается рисовать содержимое макета страницы.

Синтаксис

WM_PSD_MINMARGINRECT
hDC = (WPARAM) (HDC) wParam;              	// дескриптор контекста устройства
lprcMinMargin = (LPARAM) (LPRECT) lParam; 	// минимальный прямоугольник поля

Параметры
hDC
Значение wParam. Идентифицирует контекст устройства для макета страницы.
lprcMinMargin
Значение lParam. Указатель на структуру RECT, которая содержит координаты, в пикселях, минимального прямоугольника поля.

Возвращаемые значения
Если фильтр - процедура возвращает значение ИСТИНА (TRUE), диалоговое окно больше не передает сообщения WM_PSD* и не рисует в макете страницы до тех пор, пока в следующий раз у системы не появится необходимость перерисовать макет страницы.
Если фильтр - процедура возвращает значение ЛОЖЬ(FALSE), блок диалога передает остающиеся сообщения в порядке следования прорисовки.

Замечания
Диалоговое окно Параметры страницы (Page Setup) включает в себя изображение макета страницы, который показывает, как выбор пользователя воздействует на внешний вид напечатанного вывода информации. Когда вы вызываете функцию PageSetupDlg, то можете предоставить фильтр - процедуру PagePaintHook, чтобы настроить внешний вид макета страницы. Всякий раз, когда блок диалога собирается рисовать содержимое макета страницы, диалоговое окно передает фильтр - процедуре последовательность сообщений WM_PSD*

Смотри также
PagePaintHook, PageSetupDlg, RECT, WM_PSD_PAGESETUPDLG

Размещение и совместимость WM_PSD_MINMARGINRECT

Windows NT				Да
Win95					Да
Win32s					Да
Импортируемая библиотека			-
Заголовочный файл				commdlg.h
Unicode					WinNT
Замечания по платформе			Не имеется


4.36.4.16 - Сообщение WM_PSD_PAGESETUPDLG

Сообщение WM_PSD_PAGESETUPDLG уведомляет фильтр - процедуру PagePaintHook, что диалоговое окно Параметры страницы (Page Setup) собирается рисовать содержимое макета страницы. Фильтр - процедура может использовать это сообщение, чтобы завершить задачи инициализации, связанные с прорисовкой содержания макета страницы.

Синтаксис

WM_PSD_PAGESETUPDLG
wPaper = LOWORD(wParam);         // флажок размера бумаги
wFlags = HIWORD(wParam);         // флажок ориентации бумаги
lppsd = (LPPAGESETUPDLG) lParam; // информация о диалоговом окне

Параметры
wPaper
Значение младшего слова wParam. Определяет значение, которое указывает размер бумаги. Это значение может быть одно из значений DMPAPER_, перечисленных в описании структуры DEVMODE.
wFlags
Значение старшего слова wParam. Указывает ориентацию бумаги или конверта, и какое из двух устройств: либо точечный матричный принтер, либо HPPCL (Язык управления принтеров Hewlett Packard). Этот параметр может быть одним из следующих значений:

  • 0x0001 - Бумага в альбомной форме (точечный матричный)
  • 0x0003 - Бумага в альбомной форме (HPPCL)
  • 0x0005 - Бумага в портретной форме (точечный матричный)
  • 0x0007 - Бумага в портретной форме (HPPCL)
  • 0x000b - Конверт в альбомной форме (HPPCL)
  • 0x000d - Конверт в портретной форме(точечный матричный)
  • 0x0019 - Конверт в альбомной форме (точечный матричный)
  • 0x001f - Конверт в портретной форме (HPPCL)

lppsd
Значение lParam. Указывает на структуру PAGESETUPDLG, которая содержит информацию, используемую, чтобы инициализировать диалоговое окно Параметры страницы (Page Setup).

Возвращаемые значения
Если фильтр - процедура возвращает значение ИСТИНА (TRUE), диалоговое окно больше не передает сообщения WM_PSD* и не рисует в макете страницы до тех пор, пока в следующий раз системе не потребуется перерисовать макет страницы.
Если фильтр - процедура возвращает значение ЛОЖЬ(FALSE), блок диалога передает остающиеся сообщения в порядке следования прорисовки.

Замечания
Диалоговое окно Параметры страницы (Page Setup) включает в себя изображение макета страницы, который показывает, как выбор пользователя воздействует на внешний вид напечатанного вывода информации. Когда вы вызываете функцию PageSetupDlg, то можете предоставить фильтр - процедуру PagePaintHook, чтобы настроить внешний вид макета страницы. Всякий раз, когда блок диалога собирается рисовать содержимое макета страницы, диалоговое окно передает фильтр - процедуре последовательность сообщений WM_PSD*.
Первые три сообщения в порядке следования прорисовки (WM_PSD_PAGESETUPDLG, WM_PSD_FULLPAGERECT или WM_PSD_MINMARGINRECT) предоставляют информацию о том, что фильтр - процедура может использоваться, чтобы рисовать содержание макета страницы. Остающиеся сообщения (WM_PSD_MARGINRECT, WM_PSD_GREEKTEXTRECT, WM_PSD_ENVSTAMPRECT, WM_PSD_YAFULLPAGERECT) уведомляют фильтр - процедуру, что диалоговое окно собирается рисовать конкретную часть макета страницы. Это позволяет фильтр - процедуре выборочно рисовать узлы макета страницы.

Смотри также
DEVMODE, PagePaintHook, PageSetupDlg, PAGESETUPDLG, WM_PSD_ENVSTAMPRECT, WM_PSD_FULLPAGERECT, WM_PSD_GREEKTEXTRECT, WM_PSD_MARGINRECT, WM_PSD_MINMARGINRECT, WM_PSD_YAFULLPAGERECT

Размещение и совместимость WM_PSD_PAGESETUPDLG

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				WinNT
Замечания по платформе		Не имеется


4.36.4.17 - Сообщение WM_PSD_YAFULLPAGERECT

Сообщение WM_PSD_YAFULLPAGERECT уведомляет фильтр - процедуру диалогового окна Параметры страницы (Page Setup), что блок диалога собирается рисовать узел адреса возврата в макете страницы конверта.

Синтаксис

WM_PSD_YAFULLPAGERECT
hDC = (WPARAM) (HDC) wParam;                                    // дескриптор контекста устройства
lprcYaFullPage = (LPARAM) (LPRECT) lParam; 			// размеры прямоугольника страницы

Параметры
hDC
Значение wParam. Дескриптор контекста устройства для макета страницы.
lprcPage
Значение lParam. Указатель на структуру RECT, которая содержит координаты, в пикселях, макета страницы.

Возвращаемые значения
Если фильтр - процедура возвращает значение ИСТИНА (TRUE), диалоговое окно не рисует узел адреса возврата в макете страницы конверта.
Если фильтр - процедура возвращает значение ЛОЖЬ(FALSE), блок диалога рисует узел адреса возврата в макете страницы конверта.
Если тип бумаги не конверт, величина возвращаемого значения не имеет никакого влияния.

Замечания
Диалоговое окно Параметры страницы (Page Setup) включает в себя изображение макета страницы, который показывает, как выбор пользователя воздействуют на внешний вид напечатанного вывода информации. Когда вы вызываете функцию PageSetupDlg, вы можете предоставить фильтр - процедуру PagePaintHook, чтобы настроить внешний вид макета страницы. Всякий раз, когда диалоговое окно собирается рисовать содержимое макета страницы, блок диалога передает фильтр - процедуре последовательность сообщений WM_PSD*.

Смотри также
PagePaintHook, PageSetupDlg, RECT, WM_PSD_PAGESETUPDLG

Размещение и совместимость WM_PSD_YAFULLPAGERECT

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				Нет
Замечания по платформе		Не имеется


4.36.4.18 - Сообщение CDM_GETFILEPATH

Сообщение CDM_GETFILEPATH извлекает данные о пути и имени выбранного файла в стандартном диалоговом окне Открыть (Open) или Сохранить как (Save As) в стиле Проводника. Блок диалога должен быть создан с флажком OFN_EXPLORER; иначе, сообщение завершается с ошибкой.

Синтаксис

CDM_GETFILEPATH
wParam = (WPARAM) cbmax;
lParam = (LPARAM) (LPTSTR) psz;
// Соответствующая макрокоманда
int CommDlg_OpenSave_GetFilePath(hdlg, psz, cbmax);

Параметры
hdlg
Дескриптор стандартного диалогового окна, которое примет сообщение.
psz
Указатель на буфер, который принимает имя файла и путь к нему.
cbmax
Размер, в байтах (для версии ANSI) или в символах (для версии Уникода), буфера psz.

Возвращаемые значения
Если сообщение завершается успешно, величина возвращаемого значения - размер, в байтах или символах, строки имени файла и пути, включая символ завершения строки (ноль-терминатор). Это является или числом байтов или символов, скопированных в буфер psz, или требующийся размер буфера, если буфер слишком маленький.
Если происходит ошибка, величина возвращаемого значения - меньше чем нуль.

Смотри также
GetOpenFileName, GetSaveFileName, OPENFILENAME

Размещение и совместимость CDM_GETFILEPATH

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				WinNT
Замечания по платформе		Не имеется


4.36.4.19 - Сообщение CDM_GETFOLDERIDLIST

Сообщение CDM_GETFOLDERIDLIST извлекает адрес списка идентификаторов элементов соответствующей папки, которую в настоящее время открыло стандартное диалоговое окно Открыть (Open) или Сохранить как (Save As) в стиле Проводника. Блок диалога должен быть создан с флажком OFN_EXPLORER; иначе, сообщение завершается с ошибкой.

Синтаксис

CDM_GETFOLDERIDLIST
wParam = (WPARAM) cbmax;
lParam = (LPARAM) (LPVOID) pidl;
// Соответствующая макрокоманда
int CommDlg_OpenSave_GetFolderIDList(hdlg, pidl, cbmax);

Параметры
hdlg
Дескриптор стандартного диалогового окна, которое примет сообщение.
pidl
Указатель на буфер, который принимает список идентификаторов элементов.
cbmax
Размер буфера pidl, в байтах.

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

Смотри также
GetOpenFileName, GetSaveFileName,OPENFILENAME

Размещение и совместимость CDM_GETFOLDERIDLIST

Windows NT				Да
Win95					Да
Win32s					Нет
Импортируемая библиотека			-
Заголовочный файл				commdlg.h
Unicode					Нет
Замечания по платформе			Не имеется


4.36.4.20 - Сообщение CDM_GETFOLDERPATH

Сообщение CDM_GETFOLDERPATH извлекает данные о пути текущей открытой папки или каталога стандартным диалоговым окном Открыть (Open) или Сохранить как (Save As) в стиле Проводника. Блок диалога должен быть создан с флажком OFN_EXPLORER; иначе, сообщение завершается ошибкой.

Синтаксис

CDM_GETFOLDERPATH
wParam = (WPARAM) cbmax;
lParam = (LPARAM) (LPTSTR) psz;
// Соответствующая макрокоманда
int CommDlg_OpenSave_GetFolderPath(hdlg, psz, cbmax);

Параметры
hdlg
Дескриптор стандартного диалогового окна, которое примет сообщение.
psz
Указатель на буфер, который принимает путь.
cbmax
Размер, в байтах (для версии ANSI) или в символах (для версии Уникода), буфера psz.

Возвращаемые значения
Если сообщение завершается успешно, величина возвращаемого значения - размер строки пути, в байтах или символах, включая символ завершения строки (ноль-терминатор). Оно является или числом байтов или символов, скопированных в буфер psz, или требующийся размер буфера, если буфер слишком маленький.
Если происходит ошибка, величина возвращаемого значения - меньше чем нуль.

Смотри также
GetOpenFileName, GetSaveFileName, OPENFILENAME

Размещение и совместимость CDM_GETFOLDERPATH

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				WinNT
Замечания по платформе		Не имеется


4.36.4.21 - Сообщения CDM_GETSPEC

Сообщение CDM_GETSPEC извлекает имя (не, включая путь) текущего выбранного файла в диалоговом окне Открыть (Open) или Сохранить как (Save As) в стиле Проводника. Блок диалога, должен быть создан с флажком OFN_EXPLORER; иначе, сообщение завершается ошибкой.

Синтаксис

CDM_GETSPEC
wParam = (WPARAM) cbmax;
lParam = (LPARAM) (LPTSTR) psz;
// Соответствующая макрокоманда
int CommDlg_OpenSave_GetSpec(hdlg, psz, cbmax);

Параметры
hdlg
Дескриптор стандартного диалогового окна, которое примет сообщение.
psz
Адрес буфера, который примет имя файла.
cbmax
Размер, в байтах (для версии ANSI) или в символах (для версии Уникода), буфера psz.

Возвращаемые значения
Если сообщение завершается успешно, величина возвращаемого значения - размер строки с именем файла, в байтах или символах, включая символ завершения строки (ноль-терминатор). Оно является или числом байтов или символов, скопированных в буфер psz, или требующийся размер буфера, если буфер слишком маленький.
Если происходит ошибка, величина возвращаемого значения - меньше чем нуль.

Смотри также
GetOpenFileName, GetSaveFileName, OPENFILENAME

Размещение и совместимость CDM_GETSPEC

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				WinNT
Замечания по платформе		Не имеется


4.36.4.22 - Сообщение CDM_HIDECONTROL

Сообщение CDM_HIDECONTROL скрывает заданный элемент управления стандартного диалогового окна Открыть (Open) или Сохранить как (Save As) в стиле Проводника. Блок диалога должен быть создан с флажком OFN_EXPLORER; иначе, сообщение завершается ошибкой.

Синтаксис

CDM_HIDECONTROL
wParam = (WPARAM) id;
lParam = 0;
// Соответствующая макрокоманда
void CommDlg_OpenSave_HideControl(hdlg, id);

Параметры
hdlg
Дескриптор стандартного диалогового окна, которое примет сообщение.
id
Идентификатор элемента управления, который скрывается.

Возвращаемые значения
Возвращаемого значения нет.

Смотри также
GetOpenFileName, GetSaveFileName, OPENFILENAME

Размещение и совместимость CDM_HIDECONTROL

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				Нет
Замечания по платформе		Не имеется


4.36.4.23 - Сообщение CDM_SETCONTROLTEXT

Сообщение CDM_SETCONTROLTEXT устанавливает текст для заданного элемента управления в стандартном диалоговом окне Открыть (Open) или Сохранить как (Save As) в стиле Проводника. Блок диалога, должен быть создан с флажком OFN_EXPLORER; иначе, сообщение завершается с ошибкой.

Синтаксис

CDM_SETCONTROLTEXT
wParam = (WPARAM) id;
lParam = (LPARAM) (LPSTR) text;
// Соответствующая макрокоманда
void CommDlg_OpenSave_SetControlText(hdlg, id, text)

Параметры
hdlg
Дескриптор стандартного диалогового окна, которое примет сообщение.
id
Идентификатор элемента управления, для которого устанавливается текст.
text
Указатель на строку с символом нуля в конце, определяющую новый текст для элемента управления.

Возвращаемые значения
Возвращаемого значения нет.

Смотри также
GetOpenFileName, GetSaveFileName, OPENFILENAME

Размещение и совместимость CDM_SETCONTROLTEXT

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				Нет
Замечания по платформе		Не имеется


4.36.4.24 - Сообщение CDM_SETDEFEXT

Сообщение CDM_SETDEFEXT устанавливает заданное по умолчанию расширение имени файла в стандартном диалоговом окне Открыть (Open) или Сохранить как (Save As) в стиле Проводника. Блок диалога должно быть создан с флажком OFN_EXPLORER; иначе, сообщение завершается с ошибкой.

Синтаксис

CDM_SETDEFEXT
wParam = 0;
lParam = (LPARAM) (LPSTR) pszext;
// Соответствующая макрокоманда
void CommDlg_OpenSave_SetDefExt(hdlg, pszext)

Параметры
hdlg
Дескриптор стандартного диалогового окна, которое примет сообщение.
pszext
Указатель на новое расширение имени файлов. Не должен включать в себя точку (.).

Возвращаемые значения
Возвращаемого значения нет.

Смотри также
GetOpenFileName, GetSaveFileName, OPENFILENAME

Размещение и совместимость CDM_SETDEFEXT

Windows NT				Да
Win95					Да
Win32s					Нет
Импортируемая библиотека			-
Заголовочный файл				commdlg.h
Unicode					Нет
Замечания по платформе			Не имеется

Предупреждающие сообщения, которые стандартное диалоговое окно Открыть (Open) или Сохранить как (Save As) передает в фильтр-процедуру.


4.36.4.25 - Сообщение CDN_FILEOK

[Теперь поддерживается в Windows NT]

Уведомительное сообщение CDN_FILEOK передается стандартным диалоговым окном Открыть (Open) или Сохранить как (Save As) в стиле Проводника, когда пользователь определяет имя файла и щелкает мышью по кнопке OK. Ваша фильтр - процедура OFNHookProc принимает это сообщение в форме сообщения WM_NOTIFY.

Синтаксис

CDN_FILEOK
lpon = (LPOFNOTIFY) lParam;

Параметры
lpon
Указатель на структуру OFNOTIFY.
Структура OFNOTIFY содержит структуру NMHDR, элемент code которой указывает код уведомления CDN_FILEOK.
Структура OFNOTIFY содержит также указатель на структуру OPENFILENAME, чей элемент lpstrFile которой определяет адрес выбранного имени файла.

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

Замечания
Система передает это уведомление только тогда, если диалоговое окно было создано с использованием значения OFN_EXPLORER.

Смотри также
GetOpenFileName, GetSaveFileName, NMHDR, OFNHookProc, OFNOTIFY, OPENFILENAME, SetWindowLong, WM_NOTIFY

Размещение и совместимость CDN_FILEOK

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				Нет
Замечания по платформе		Не имеется


4.36.4.26 - Сообщение CDN_FOLDERCHANGE

[Теперь поддерживается в Windows NT]

Уведомительное сообщение CDN_FOLDERCHANGE передается стандартным диалоговым окном Открыть (Open) или Сохранить как (Save As) в стиле Проводника, когда открывается новая папка. Ваша фильтр - процедура OFNHookProc принимает это сообщение в форме сообщения WM_NOTIFY.

Синтаксис

CDN_FOLDERCHANGE
lpon = (LPOFNOTIFY) lParam;

Параметры
lpon
Указатель на структуру OFNOTIFY.
Структура OFNOTIFY содержит структуру NMHDR, элемент code которой указывает код уведомления CDN_FOLDERCHANGE.

Возвращаемые значения
Возвращаемое значение игнорируется.

Замечания
Система передает это уведомление только тогда, если диалоговое окно было создано с использованием значения OFN_EXPLORER.
Чтобы получить путь недавно открытой папки, фильтр - процедура может передать блоку диалога сообщение CDM_GETFOLDERPATH.

Смотри также
CDM_GETFOLDERPATH, GetOpenFileName, GetSaveFileName, NMHDR, OFNHookProc, OFNOTIFY, WM_NOTIFY

Размещение и совместимость CDN_FOLDERCHANGE

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				Нет
Замечания по платформе		Не имеется


4.36.4.27 - Сообщение CDN_HELP

[Теперь поддерживается в Windows NT]

Уведомительное сообщение CDN_HELP передается стандартным диалоговым окном Открыть (Open) или Сохранить как (Save As) в стиле Проводника, когда пользователь щелкает мышью по кнопке Справка (Help). Ваша фильтр - процедура OFNHookProc принимает это сообщение в форме сообщения WM_NOTIFY.

Синтаксис

CDN_HELP
lpon = (LPOFNOTIFY) lParam;

Параметры
lpon
Указатель на структуру OFNOTIFY.
Структура OFNOTIFY содержит структуру NMHDR, элемента code которой указывает код уведомления CDN_HELP.

Возвращаемые значения
Возвращаемое значение игнорируется.

Замечания
Система передает это уведомление только тогда, если диалоговое окно было создано с использованием значения OFN_EXPLORER.

Смотри также
GetOpenFileName, GetSaveFileName, NMHDR, OFNHookProc, OFNOTIFY, OPENFILENAME, WM_NOTIFY

Размещение и совместимость CDN_HELP

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				Нет
Замечания по платформе		Не имеется


4.36.4.28 - Сообщение CDN_INITDONE

[Теперь поддерживается в Windows NT]

Уведомительное сообщение CDN_INITDONE передается стандартным диалоговым окном Открыть (Open) или Сохранить как (Save As) в стиле Проводника, когда система закончила упорядочивать элементы управления в блоке диалога. Система перемещает стандартные элементы управления, чтобы создать место для элементов управления дочернего диалогового окна. Ваша фильтр - процедура OFNHookProc принимает это сообщение в форме сообщения WM_NOTIFY.

Синтаксис

CDN_INITDONE
lpon = (LPOFNOTIFY) lParam;

Параметры
lpon
Указатель на структуру OFNOTIFY.
Структура OFNOTIFY содержит структуру NMHDR, элемент code которой указывает код уведомления CDN_INITDONE.

Возвращаемые значения
Возвращаемое значение игнорируется.

Замечания
Система передает это уведомление только тогда, если диалоговое окно было создано, с использованием значения OFN_EXPLORER.

Смотри также
GetOpenFileName, GetSaveFileName, NMHDR, OFNHookProc, OFNOTIFY, OPENFILENAME, WM_NOTIFY

Размещение и совместимость CDN_INITDONE

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				Нет
Замечания по платформе		Не имеется


4.36.4.29 - Сообщение CDN_SELCHANGE

[Теперь поддерживается в Windows NT]

Уведомительное сообщение CDN_SELCHANGE передается стандартным диалоговым окном Открыть (Open) или Сохранить как (Save As) в стиле Проводника, когда выбор в окне списка, которое отображает содержание текущей открытой папки или каталога, изменяется. Ваша фильтр - процедура OFNHookProc принимает это сообщение в форме сообщения WM_NOTIFY.

Синтаксис

CDN_SELCHANGE
lpon = (LPOFNOTIFY) lParam;

Параметры
lpon
Указатель на структуру OFNOTIFY.
Структура OFNOTIFY содержит структуру NMHDR, элемент code которой указывает код уведомления CDN_SELCHANGE.

Возвращаемые значения
Возвращаемое значение игнорируется.

Замечания
Система передает это уведомление только тогда, если диалоговое окно было создано с использованием значения OFN_EXPLORER.
Чтобы получить имя недавно выбранного файла или папки, фильтр - процедура может передать стандартному диалоговому окну сообщение CDM_GETFILEPATH или CDM_GETSPEC.

Смотри также
CDM_GETFILEPATH, CDM_GETSPEC, GetOpenFileName, GetSaveFileName, NMHDR, OFNHookProc, OFNOTIFY, WM_NOTIFY

Размещение и совместимость CDN_SELCHANGE

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				Нет
Замечания по платформе		Не имеется


4.36.4.30 - Сообщение CDN_SHAREVIOLATION

[Теперь поддерживается в Windows NT]

Уведомительное сообщение CDN_SHAREVIOLATION передается стандартным диалоговым окном Открыть (Open) или Сохранить как (Save As) в стиле Проводника, когда пользователь щелкает мышью по кнопке OK и происходит сетевая ошибка совместного доступа для выбранного файла. Ваша фильтр - процедура OFNHookProc принимает это сообщение в форме сообщения WM_NOTIFY.

Синтаксис

CDN_SHAREVIOLATION
lpon = (LPOFNOTIFY) lParam;

Параметры
lpon
Указатель на структуру OFNOTIFY. Элемент pszFile этой структуры указывает на имя файла, который имел ошибку совместного доступа.
Структура OFNOTIFY содержит структуру NMHDR, элемент code которой указывает код уведомления CDN_SHAREVIOLATION.

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

  • OFN_SHAREFALLTHROUGH - Заставляет диалоговое окно возвратить имя файла без предупреждения пользователя об ошибке совместного доступа.
  • OFN_SHARENOWARN - Заставляет диалоговое окно отклонить имя файла без предупреждения пользователя об ошибке совместного доступа.

Замечания
Система передает это уведомление только тогда, если диалоговое окно было создано с использованием значения OFN_EXPLORER.
Система передает это уведомление только тогда, если значение OFN_SHAREAWARE не было определено, когда был создан блок диалога.

Смотри также
GetOpenFileName, GetSaveFileName, NMHDR, OFNHookProc, OFNOTIFY, OPENFILENAME, SetWindowLong, WM_NOTIFY

Размещение и совместимость CDN_SHAREVIOLATION

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		-
Заголовочный файл			commdlg.h
Unicode				Нет
Замечания по платформе		Не имеется


4.36.4.31 - Сообщение CDN_TYPECHANGE

[Теперь поддерживается в Windows NT]

Уведомительное сообщение CDN_TYPECHANGE передается стандартным диалоговым окном Открыть (Open) или Сохранить как (Save As) в стиле Проводника, когда пользователь выбирает новый тип файла из типов файлов в комбинированном блоке. Ваша фильтр - процедура OFNHookProc принимает это сообщение в форме сообщения WM_NOTIFY.

Синтаксис

CDN_TYPECHANGE
lpon = (LPOFNOTIFY) lParam;

Параметры
lpon
Адрес структуры OFNOTIFY.
Структура OFNOTIFY содержит структуру NMHDR, элемент code которой указывает код уведомления CDN_TYPECHANGE.
Структура OFNOTIFY содержит также указатель на структуру OPENFILENAME, элемент nFilterIndex которой указывает однобазовый индекс недавно выбранного фильтра типа файла.

Возвращаемые значения
Возвращаемое значение игнорируется.

Замечания
Система передает это уведомление только тогда, если диалоговое окно было создано с использованием значения OFN_EXPLORER.

Смотри также
GetOpenFileName, GetSaveFileName, NMHDR, OFNHookProc, OFNOTIFY, OPENFILENAME, WM_NOTIFY

Размещение и совместимость CDN_TYPECHANGE

Windows NT				Да
Win95					Да
Win32s					Нет
Импортируемая библиотека			-
Заголовочный файл				commdlg.h
Unicode					Нет
Замечания по платформе			Не имеется
Предыдущий Шаг


Глава 9 - Ускорители клавиатуры

В Microsoft Windows, ускоритель клавиатуры (keyboard accelerator) (или, просто, акселератор) - это нажатие клавиши или комбинация нажатий клавиш, которые генерирует для прикладной программы сообщение WM_COMMAND или WM_SYSCOMMAND.

Следующий Шаг


9.1 - Об ускорителях клавиатуры

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


9.2 - Таблицы клавиш-ускорителей

Таблица клавиш – ускорителей (accelerator table) состоит из массива структур ACCEL, каждая из которых определяет конкретный акселератор. Каждая структура ACCEL включает в себя следующую информацию:

  1. Комбинацию нажатия клавиши - ускорителя.
  2. Идентификатор акселератора.
  3. Различные флажки. Эти флажки включают в себя и тот, который определяет, должен ли Windows предоставлять визуальную обратную связь, когда акселератор использован, высвечивая соответствующий пункт меню, если он есть в наличии.

Чтобы обрабатывать нажатия клавиш - акселераторов для данного потока, разработчик должен вызвать функцию TranslateAccelerator в цикле сообщения, связанном с очередью сообщений потока. Функция TranslateAccelerator контролирует ввод с клавиатуры в очереди сообщений, проверяя комбинации клавиш, которые соответствуют элементу в таблицах клавиш - ускорителей. Когда TranslateAccelerator находит соответствие, она переводит ввод с клавиатуры (то есть сообщения WM_KEYUP и WM_KEYDOWN) в сообщение WM_COMMAND или WM_SYSCOMMAND, а затем отправляет сообщение оконной процедуре определяемого окна. Следующая иллюстрация показывает, как обрабатываются акселераторы.

3_1.gif (12009 b)

Сообщение WM_COMMAND включает в себя идентификатор клавиши-ускорителя, которая заставила TranslateAccelerator сгенерировать сообщение. Оконная процедура проверяет идентификатор, чтобы определить источник сообщения, а затем соответственно обрабатывает сообщение.

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

Windows поддерживает также и таблицы клавиш – ускорителей для каждой прикладной программы. Приложение может определять любое число таблиц акселераторов для использования своими собственными окнами. Уникальный 32-разрядный дескриптор (HACCEL) идентифицирует каждую таблицу. Однако только одна таблица клавиш – ускорителей одновременно может быть активна для данного потока. Дескриптор таблицы клавиш - ускорителей, передаваемый в функцию TranslateAccelerator, определяет, какая таблица акселераторов является активной для потока. Активная таблица акселераторов может быть переопределена в любое время, при помощи передачи соответствующего дескриптора таблицы клавиш-ускорителей в TranslateAccelerator.


9.3 - Создание таблиц клавиш ускорителей

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

Таблица акселераторов также может быть создана для приложения и во время выполнения программы, при помощи передачи массива структур ACCEL в функцию CreateAcceleratorTable. Этот метод поддерживает определяемые пользователем акселераторы в прикладной программе. Подобно функции LoadAccelerators, CreateAcceleratorTable возвращает дескриптор таблицы клавиш-ускорителей, который может быть передан в TranslateAccelerator, чтобы привести в действие таблицу акселераторов.

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

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


9.4 - Присваивание нажатий клавиш - ускорителей

Чтобы определить клавишу - ускоритель, может быть использован код символа ASCII или код виртуальной клавиши. Код символа ASCII делает клавишу - ускоритель чувствительной к регистру. Символ ASCII "C" может определять акселератор как ALT+c, а не ALT+C. Однако чувствительные к регистру клавиши - акселераторы могут быть сложными для использования. Например, клавиша - акселератор ALT+C будет сгенерирована, если клавиша CAPS LOCK или SHIFT - нажата, но не в случае, если нажаты обе.

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

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

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

  • ALT+ESC - Переключает в следующее приложение (для Windows версии 3.1). Переключает приложения на панели задач в Windows 95 и выше.
  • ALT+F4 - Закрывает приложение или окно.
  • ALT+HYPHEN - Открывает Системное меню для окна документа.
  • ALT+PRINT SCREEN - Копирует изображение активного окна в буфер обмена.
  • ALT+SPACEBAR - Открывает Системное меню для окна приложения.
  • ALT+TAB - Переключает в следующее приложение.
  • CTRL+ESC - Переключает список задач (для Windows версии 3.1) Эквивалентно нажатию кнопки Пуск (для Windows 95 и выше).
  • CTRL+F4 - Закрывает активную группу или окно документа.
  • F1 - Если у приложения имеется Справка (Help), запускает Справку.
  • PRINT SCREEN - Копирует изображения экрана в буфер обмена.
  • SHIFT+ALT+TAB - Переключает в предыдущее приложение. Пользователь должен нажать и удерживать нажатыми кнопки ALT+SHIFT до нажатия кнопки TAB.


9.5 - Клавиши - ускорители и меню

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

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

Идентификатор определяет, генерирует ли клавиша - ускоритель сообщение WM_SYSCOMMAND или WM_COMMAND. Если идентификатор имеет то же самое значение, что и пункт меню в Системном меню, акселератор создает сообщение WM_SYSCOMMAND. В противном случае, клавиша - ускоритель генерирует сообщение WM_COMMAND.

Если клавиша - ускоритель имеет тот же самый идентификатор, что и пункт меню, а пункт меню недоступен или заблокирован, акселератор блокируется и не генерирует сообщение WM_SYSCOMMAND или WM_COMMAND. Клавиша – ускоритель также не генерирует сообщение команды, если соответствующее окно свернуто.

Когда пользователь использует клавишу - ускоритель, которая соответствует пункту меню, оконная процедура принимает сообщения WM_INITMENU и WM_INITMENUPOPUP, как если бы пользователь выбрал пункт меню. За информацией относительно того, как обрабатывать эти сообщения, обратитесь к статье. Меню.

Клавиша - ускоритель, которая соответствует пункту меню, должна быть включена в текст пункта меню.


9.6 - Использование клавиш-ускорителей клавиатуры

Использование ресурса таблицы клавиш-ускорителей
Использование таблицы клавиш-ускорителей, созданной во время прогона программы


9.6.1 - Использование ресурса таблицы клавиш-ускорителей

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

  1. Создайте таблицу клавиш-ускорителей в файле определения ресурса. Компилируйте его и добавьте итоговый ресурс к исполняемому файлу вашей прикладной программы.
  2. Включите вызов функции LoadAccelerators, чтобы загрузить ресурс таблицы клавиш-ускорителей и примите дескриптор таблицы клавиш-ускорителей.
  3. Добавьте функцию TranslateAccelerator к циклу сообщения, связанному с таблицей клавиш-ускорителей.
  4. Организуйте обработку создаваемого сообщения WM_COMMAND, когда пользователь использует клавишу - ускоритель.


9.6.2 - Создание ресурса таблицы клавиш-ускорителей

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

Каждая клавиша - ускоритель, которую Вы определяете, требует отдельного элемента в таблице клавиш-ускорителей. В каждом элементе, Вы определяете нажатие клавиши (или код символа ASCII или код виртуальной клавиши), который создает клавишу - ускоритель и ее идентификатор. Вы должны также определить, должно ли нажатие клавиши быть использовано в некоторой комбинации с клавишами ALT, SHIFT или CTRL. Для получения дополнительной информации о виртуальных клавишах, см. статью Ввод с клавиатуры.

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

"A", ID_ACCEL1         ; SHIFT+A
65,  ID_ACCEL2, ASCII  ; SHIFT+A

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

"a",       ID_ACCEL3, VIRTKEY   ; A (клавиша заглавных букв вкл.) или a
VK_INSERT, ID_ACCEL4, VIRTKEY   ; клавиша INSERT

Следующий пример показывает ресурс таблицы клавиш-ускорителей, который определяет клавиши - ускорители для операций с файлами. Название ресурса - FileAccel.

FileAccel ACCELERATORS
BEGIN
    VK_F12, IDM_OPEN, CONTROL, VIRTKEY  ; CTRL+F12
    VK_F4,  IDM_CLOSE, ALT, VIRTKEY     ; ALT+F4
    VK_F12, IDM_SAVE, SHIFT, VIRTKEY    ; SHIFT+F12
    VK_F12, IDM_SAVEAS, VIRTKEY         ; F12
END

Если Вы хотите, чтобы пользователь нажимал клавиши ALT, SHIFT или CTRL в некоторой комбинации с нажатием клавиши - ускорителя, установите флажки ALT, SHIFT и CONTROL в определении клавиши - ускорителя. Ниже следуют - некоторые примеры.

"B",   ID_ACCEL5, ALT                   ; ALT_SHIFT+B
"I",   ID_ACCEL6, CONTROL, VIRTKEY      ; CTRL+I
VK_F5, ID_ACCEL7, CONTROL, ALT, VIRTKEY ; CTRL+ALT+F5

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

VK_DELETE, ID_ACCEL8, VIRTKEY, SHIFT, NOINVERT ;SHIFT+DELETE

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

FilePopup MENU
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "&New..",           IDM_NEW
        MENUITEM "&Open\tCtrl+F12",  IDM_OPEN
        MENUITEM "&Close\tAlt+F4"    IDM_CLOSE
        MENUITEM "&Save\tShift+F12", IDM_SAVE
        MENUITEM "Save &As...\tF12", IDM_SAVEAS
    END
END


9.6.3 - Загрузка ресурса таблицы клавиш-ускорителей

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

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


9.6.4 - Вызов функции TranslateAccelerator

Чтобы обрабатывать клавиши - ускорители, цикл сообщения прикладной программы (или потока) должен содержать вызов функции TranslateAccelerator. TranslateAccelerator сравнивает нажатия клавиши с таблицей клавиш-ускорителей и, если она находит соответствие, переводит нажатия клавиш в сообщения WM_COMMAND (или WM_SYSCOMMAND). Затем функция отправляет сообщение оконной процедуре. Параметры функции TranslateAccelerator включают в себя дескриптор окна, которое должно принять сообщения WM_COMMAND, дескриптор таблицы клавиш-ускорителей, использованной трансляции клавиш - ускорителей и указатель на структуру MSG, содержащую сообщение из очереди. Следующий пример показывает, как вызвать TranslateAccelerator изнутри цикла сообщения.

while (GetMessage(&msg, (HWND) NULL, 0, 0))
{
    /* Проверка нажатия клавиши-ускорителя. */

    if (!TranslateAccelerator(
        hwndMain,	/* дескриптор окна - приемника */
        haccel,	/* дескриптор таблицы активной клавиши-ускорителя */
        &msg))	/* адрес данных сообщений */
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}


9.6.5 - Обработка сообщений WM_COMMAND

Когда используется клавиша - ускоритель, окно, определенное в функции TranslateAccelerator принимает сообщение WM_SYSCOMMAND или WM_COMMAND. Младшее слово параметра wParam содержит идентификатор акселератора. Оконная процедура проверяет идентификатор, чтобы решить, какой источник посылает сообщение WM_COMMAND и соответственно обрабатывает сообщение.

Как правило, если клавиша - ускоритель соответствует пункту меню в прикладной программе, ей и пункту меню назначается один и тот же идентификатор. Если Вам нужно знать, было ли данное сообщение WM_COMMAND создано акселератором или пунктом меню, Вы можете проверить старшее слово параметра wParam. Если сообщение генерировала клавиша - ускоритель, старшее слово равно 1; если сообщение создал пункт меню, старшее слово - 0.


9.6.6 - Уничтожение ресурса таблицы клавиш-ускорителей

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


9.6.7 - Создание клавиш - ускорителей для атрибутов шрифта

Пример в этом разделе показывает, как исполнить следующие задачи:

  1. Создать ресурс таблицы клавиш-ускорителей.
  2. Загрузить таблицу акселераторов во время прогона программы.
  3. Преобразовать клавиши - ускорители в цикле сообщений.
  4. Обработать сообщения WM_COMMAND, сгенерированные акселераторами.

Эти задачи демонстрируются применительно к прикладной программе, которая включает в себя меню Символ (Character) и соответствующие клавиши - ускорители, которые позволяют пользователю выбирать атрибуты текущего шрифта.

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

Обратите внимание!, что пункты меню показывают нажатие клавиши - ускорителя и то, что каждый акселератор имеет тот же самый идентификатор, что и связанный с ним пункт меню.

#include <windows.h>
#include "acc.h"

MainMenu MENU
BEGIN
    POPUP "&Character"
    BEGIN
        MENUITEM "&Regular\tF5", IDM_REGULAR
        MENUITEM "&Bold\tCtrl+B", IDM_BOLD
        MENUITEM "&Italic\tCtrl+I", IDM_ITALIC
        MENUITEM "&Underline\tCtrl+U", IDM_ULINE
    END
END

FontAccel ACCELERATORS
BEGIN
    VK_F5, IDM_REGULAR, VIRTKEY
    "B", IDM_BOLD, CONTROL, VIRTKEY
    "I", IDM_ITALIC, CONTROL, VIRTKEY
    "U", IDM_ULINE, CONTROL, VIRTKEY
END

Следующий раздел исходного файла приложения показывает как реализовать акселератор:

HWND hwndMain; /* дескриптор главного окна */
HANDLE hinstAcc; /*дескриптор экземпляра приложения */

int WINAPI WinMain(hinst, hinstPrev, lpCmdLine, nCmdShow)
HINSTANCE hinst;
HINSTANCE hinstPrev;
LPSTR lpCmdLine;
int nCmdShow;
{
    MSG msg; /* сообщения прикладной программы */
    HACCEL haccel; /* дескриптор таблицы клавиш-ускорителей */

    .
    . /* Исполнение процедуры инициализации */
    .

    /* создание главного окна для этого экземпляра приложения.  */
    hwndMain = CreateWindowEx(0L, "MainWindowClass",
        "Sample Application", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL,
        hinst, NULL );

    /* Если окно невозможно создать возвращается значение "failure." -неудача. */

    if (!hwndMain) return FALSE;

    /* Сделаем окно видимым и обновим его рабочую область. */

    ShowWindow(hwndMain, nCmdShow);
    UpdateWindow(hwndMain);

    /* Загрузим таблицу клавиш-ускорителей. */

    haccel = LoadAccelerators(hinstAcc, "FontAccel");
    if (haccel == NULL)
        HandleAccelErr(ERR_LOADING); /* заданное приложение */

    /*
    * Получим и отправим по назначению сообщения, пока не принято сообщение WM_QUIT.
    * .
    */

    while (GetMessage(&msg, NULL, NULL, NULL)) {
        /* Проверка нажата ли клавиша-ускоритель. */
        if (!TranslateAccelerator(
            hwndMain,	/* дескриптор окна-приемника */
            haccel,	/* дескриптор таблицы активного акселератора */
            &msg)) {	/* адрес данных для сообщений */
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return msg.wParam;
}

LRESULT APIENTRY MainWndProc(hwndMain, uMsg, wParam, lParam)
HWND hwndMain;
UINT uMsg;
WPARAM wParam;
LPARAM lParam;
{
    BYTE fbFontAttrib; /* массив флажков атрибутов шрифта */
    static HMENU hmenu; /* дескриптор главного меню */

    switch (uMsg) {

        case WM_CREATE:
            /*
            * Прибавим галочку к пункту меню Regular, чтобы указать, что это - значение по
            *. умолчанию.
            */

            hmenu = GetMenu(hwndMain);
            CheckMenuItem(hmenu, IDM_REGULAR, MF_BYCOMMAND |  MF_CHECKED);
            return 0;

        case WM_COMMAND:
            switch (LOWORD(wParam)) {
                /* Обработаем клавишу - ускоритель и команды меню

                case IDM_REGULAR:
                case IDM_BOLD:
                case IDM_ITALIC:
                case IDM_ULINE:

                /*
                * GetFontAttributes - это функция, определяемая программой
                * функция, которая выставляет метки пунктам меню
                * и возвращает атрибуты шрифта, выбранные пользователем.
                */
                    fbFontAttrib = GetFontAttributes(
                    (BYTE) LOWORD(wParam), hmenu);

                /*
                * SetFontAttributes - это функция, определяемая приложением,
                * которая создает шрифт с атрибутами, определенными пользователем
                * при помощи контекста устройства главного окна.
                */

                    SetFontAttributes(fbFontAttrib);
                    break;

                default:
                    break;
            }
            break;

            .
            . /* Обработка других сообщений. */
            .

        default:
            return DefWindowProc(hwndMain, uMsg, wParam, lParam);
    }
    return NULL;
}


9.7 - Использование таблицы клавиш-ускорителей, созданной во время прогона программы

Win32 прикладной программный интерфейс (API) позволяет Вам создавать таблицы клавиш-ускорителей во время прогона программы. Шаги, включенные в создание и использование таблицы акселераторов во время прогона программы следующие:

Определение клавиш - ускорителей при помощи заполнения массива структур ACCEL, а затем создание таблицы клавиш-ускорителей, посредством передачи массива в функцию CreateAcceleratorTable.

Активизация таблицы клавиш-ускорителей и обработка сообщений WM_COMMAND, сгенерированных акселераторами.

Уничтожение таблицы клавиш-ускорителей прежде, чем прикладная программа закроется.


9.7.1 - Создание таблицы клавиш-ускорителей

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

typedef struct tagACCEL {	// accl
    BYTE fVirt;
    WORD key;
    WORD cmd;
} ACCEL;

Вы определяете нажатие клавиши - ускорителя, при помощи установки кода буквы ASCII или кода виртуальной клавиши в члене key структуры ACCEL. Если Вы определяете код виртуальной клавиши, Вы должны сначала включить флажок FVIRTKEY в члене fVirt; иначе, Windows поймет код как код буквы ASCII. Вы можете включить флажок FCONTROL, FALT или FSHIFT, или все три, чтобы комбинировать с нажатиями клавиш клавиши CTRL, ALT или SHIFT.

Чтобы создать таблицу клавиш-ускорителей, пошлите адрес массива структур ACCEL в функцию CreateAcceleratorTable. CreateAcceleratorTable создает таблицу клавиш-ускорителей и возвращает ее дескриптор.


9.7.2 - Обработка клавиш-ускорителей

Процесс загрузки и вызова клавиш - ускорителей, предусмотренных их таблицей, созданной во время прогона программы, аналогичен обработке этих клавиш, предусмотренных ресурсом таблицы клавиш-ускорителей. Для получения дополнительной информации, см. со статьи Загрузка ресурса таблицы клавиш-ускорителей до статьи Обработка сообщения WM_COMMAND.


9.7.3 - Разрушение таблицы клавиш-ускорителей

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


9.8 - Создание доступных для редактирования пользователем клавиш - ускорителей

Этот пример показывает, как создать диалоговое окно, которое позволяет пользователю изменять клавишу - ускоритель, связанную с пунктом меню. Диалоговое окно состоит из комбинированного блока содержащего пункты меню, комбинированного блока, содержащего названия клавиш и окошек для флажка "галочка" для выбора клавиш CTRL, ALT и SHIFT. Иллюстрация ниже показывает это диалоговое окно.

19_1.gif (14805 b)

Следующий пример показывает, как диалоговое окно определяется в файле определения ресурса.

EdAccelBox DIALOG 5, 17, 193, 114
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION
CAPTION "Edit Accelerators"
BEGIN
    COMBOBOX		IDD_MENUITEMS, 10, 22, 52, 53,
                    CBS_SIMPLE | CBS_SORT | WS_VSCROLL |
                    WS_TABSTOP
    CONTROL		 "Control", IDD_CNTRL, "Button",
                        BS_AUTOCHECKBOX | WS_TABSTOP,
                        76, 35, 40, 10
    CONTROL		 "Alt", IDD_ALT, "Button",
                        BS_AUTOCHECKBOX | WS_TABSTOP,
                        76, 48, 40, 10
    CONTROL		 "Shift", IDD_SHIFT, "Button",
                        BS_AUTOCHECKBOX | WS_TABSTOP,
                        76, 61, 40, 10
    COMBOBOX		IDD_KEYSTROKES, 124, 22, 58, 58,
                    CBS_SIMPLE | CBS_SORT | WS_VSCROLL |
                    WS_TABSTOP
    PUSHBUTTON	  "Ok", IDOK, 43, 92, 40, 14
    PUSHBUTTON	  "Cancel", IDCANCEL, 103, 92, 40, 14
    LTEXT		   "Select Item:", 101, 10, 12, 43, 8
    LTEXT		   "Select Keystroke:", 102, 123, 12,
                     60, 8
END

Диалоговое окно использует массив определяемых программой структур VKEY, каждая из которых содержит текстовую строку о нажатии клавиши и текстовую строку о клавише - ускорителе. Когда диалоговое окно создается, оно анализирует массив и добавляет текстовую строку о каждом нажатии клавиши в комбинированный блок Выбор Нажатия клавиши (Select Keystroke). Когда пользователь щелкает по кнопке Ok, блок диалога ищет текстовую строку о выбранном нажатии клавиши и извлекает данные соответствующие текстовой строке о клавише - ускорителе. Диалоговое окно приобщает текстовую строку о клавише - ускорителе к тексту пункта меню, который выбрал пользователь. Следующий пример показывает массив структур VKEY:

/* Настройка поиска VKey */

#define MAXKEYS 26

typedef struct _VKEYS {
    char *pKeyName;
    char *pKeyString;
} VKEYS;

VKEYS vkeys[MAXKEYS] = {
    "BkSp", "Back Space",
    "PgUp", "Page Up",
    "PgDn", "Page Down",
    "End", "End",
    "Home", "Home",
    "Lft", "Left",
    "Up", "Up",
    "Rgt", "Right",
    "Dn", "Down",
    "Ins", "Insert",
    "Del", "Delete",
    "Mult", "Multiply",
    "Add", "Add",
    "Sub", "Subtract",
    "DecPt", "Decimal Point",
    "Div", "Divide",
    "F2", "F2",
    "F3", "F3",
    "F5", "F5",
    "F6", "F6",
    "F7", "F7",
    "F8", "F8",
    "F9", "F9",
    "F11", "F11",
    "F12", "F12"
};

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

/* Глобальные переменные */

HWND hwndMain;	  /* дескриптор главного окна */
HANDLE hinstAcc;	/* дескриптор экземпляра приложения */
HACCEL haccel;	  /* дескриптор таблицы клавиши-ускорителя */

.
.
.

/* Процедура диалогового окна */

LRESULT CALLBACK EdAccelProc(hwndDlg, uMsg, wParam, lParam)
HWND hwndDlg;
UINT uMsg;
WPARAM wParam;
LPARAM lParam;
{
    int nCurSel;		/* Индекс элемента окна списка */
    UINT idItem;		/* Идентификатор пункта меню */
    UINT uItemPos;		/* Позиция пункта меню */
    UINT i, j = 0;		/* Счетчики цикла */
    static UINT cItems;	/* Номер элемента в меню */
    char szTemp[32];	i>/* Временный буфер */
    char szAccelText[32];	/* Буфер для текста клавиши-ускорителя */
    char szKeyStroke[16];	/* Буфер для текста нажатой клавиши */
    static char szItem[32];	/* Буфер для текста пункта меню */
    HWND hwndCtl;		/* Дескриптор окна управления */
    static HMENU hmenu;	/* Дескриптор меню "Character" */
    PCHAR pch, pch2;		/* Указатели на копируемую строку */
    WORD wVKCode;		/* Код виртуальной клавиши - ускорителя */
    BYTE fAccelFlags;		/* Флажки fVirt для структуры ACCEL */
    LPACCEL lpaccelNew;	/* Адрес новой таблицы клавишей ускорителей */
    HACCEL haccelOld;		/* Адрес старой таблицы клавишей ускорителей */
    int cAccelerators;		/* Число клавиш-ускорителей в таблице */
    static BOOL fItemSelected = FALSE;	/* Флажок выбора элемента */
    static BOOL fKeySelected = FALSE;	/* Флажок выбора клавиши */

    switch (uMsg) {
        case WM_INITDIALOG:

        /* Получим дескриптор пункта меню комбинированного блока */
            hwndCtl = GetDlgItem(hwndDlg, IDD_MENUITEMS);

        /*
        * Строка меню прикладной программы содержит подменю "Character",
        * пункты которого присоединяют клавиши - ускорители к ним.
        * Получим дескриптор подменю "Character" "
        * (его позиция в пределах главного меню и 2),
        * и подсчет числа пунктов, которые в нем есть.
        */

            hmenu = GetSubMenu(GetMenu(hwndMain), 2);
            cItems = GetMenuItemCount(hmenu);

        /* Получим текст каждого пункта,
        * полоску из '&' и текста  клавиши - ускорителя
        * и добавим текст в пункт меню комбинированный блока
        *

            for (i = 0; i < cItems; i++) {
                if (!(GetMenuString(hmenu, i, szTemp,
                    sizeof(szTemp), MF_BYPOSITION)))
                    continue;
                for (pch = szTemp, pch2 = szItem;
                    *pch != '\0'; )
                {
                    if (*pch != '&')
                    {
                        if (*pch == '\t')
                        {
                            *pch = '\0';
                            *pch2 = '\0';
                        } else *pch2++ = *pch++;
                    } else pch++;
                }
                SendMessage(hwndCtl, CB_ADDSTRING, 0,
                    (LONG) (LPSTR) szItem);
            }

            /* Теперь заполним комбинированный блок нажатия клавиши
            * списком нажатий клавиши, которые будут позволяться для клавиш - ускорителей.
            * Список нажатий клавиши находится в определяемой программой
            * структуре, называемой "vkeys".
            */

            hwndCtl = GetDlgItem(hwndDlg, IDD_KEYSTROKES);
            for (i = 0; i < MAXKEYS; i++)
                SendMessage(hwndCtl, CB_ADDSTRING, 0,
                    (LONG) (LPSTR) vkeys[i].pKeyString);

            return TRUE;

        case WM_COMMAND:
            switch (LOWORD(wParam))
            {
                case IDD_MENUITEMS:

                    /* Пользователь должен выбрать элемент
                    * из пункта меню - комбинированного блока.
                    * Этот флажок проверяется в ходе обработки IDOK,
                    * чтобы убедиться, что выбор был сделан.
                    */

                    fItemSelected = TRUE;
                    return 0;

                case IDD_KEYSTROKES:

                    /*
                     * Пользователь должен выбрать элемент из пунктов меню
                     * комбинированного блока. Этот флажок проверяется в ходе
                     * обработки IDOK, чтобы гарантировать, что выбор был сделан.
                     */

                    fKeySelected = TRUE;

                    return 0;

                case IDOK:

                    /*
                     * Если пользователь не выбрал пункт меню
                     * и нажал клавишу, на экране появится напоминание
                     * в окне сообщений.
                     */

               if (!fItemSelected || !fKeySelected)
               {
                    MessageBox(hwndDlg,
                       "Item or key not selected.", NULL,
                        MB_OK);
                        return 0;
               }

                    /*
                     * Определим, выбраны ли клавиши CTRL, ALT и SHIFT.
                     * Свяжем соответствующие строки клавиши - ускорителя
                     * с буферной памятью для хранения текста и установим
                     * соответствующие флажки клавиши - ускорителя.
                     */

                    szAccelText[0] = '\0';

                    hwndCtl = GetDlgItem(hwndDlg, IDD_CNTRL);
                    if (SendMessage(hwndCtl, BM_GETCHECK, 0, 0) == 1)
                    {
                        lstrcat(szAccelText, "Ctl+");
                        fAccelFlags |= FCONTROL;
                    }
                    hwndCtl = GetDlgItem(hwndDlg, IDD_ALT);
                    if (SendMessage(hwndCtl, BM_GETCHECK, 0, 0) == 1) {
                        lstrcat(szAccelText, "Alt+");

                        fAccelFlags |= FALT;
                    }
                    hwndCtl = GetDlgItem(hwndDlg, IDD_SHIFT);
                    if (SendMessage(hwndCtl, BM_GETCHECK, 0, 0) == 1) {
                        lstrcat(szAccelText, "Shft+");
                        fAccelFlags |= FSHIFT;
                    }

                    /*
                     * Получим выбранное нажатие клавиши и найдем
                     * текст клавиши-ускорителя, и код виртуальной клавиши
                     * для нажатия клавиши в структуре vkeys.
                     */

                    hwndCtl = GetDlgItem(hwndDlg, IDD_KEYSTROKES);
                    nCurSel = (int) SendMessage(hwndCtl,
                        CB_GETCURSEL, 0, 0);
                    SendMessage(hwndCtl, CB_GETLBTEXT,
                        nCurSel, (LONG) (LPSTR) szKeyStroke);
                    for (i = 0; i < MAXKEYS; i++) {
                        if(lstrcmp(vkeys[i].pKeyString,
                                szKeyStroke) == 0)
                        {
                            lstrcpy(szKeyStroke,
                                vkeys[i].pKeyName);
                            break;
                        }
                    }

                    /*
                     * Свяжем текст нажатия клавиши со строкой " Ctl + ", " Alt + " или " Shft + ".
                     *
                     */

                    lstrcat(szAccelText, szKeyStroke);

                    /*
                     * Установим позицию в меню
                     * выбранного пункта меню. Пункты меню в
                     * меню "Character" имеют позиции 0,2,3 и 4.
                     */

                    if (lstrcmp(szItem, "Regular") == 0)
                        uItemPos = 0;
                    else if (lstrcmp(szItem, "Bold") == 0)
                        uItemPos = 2;
                    else if (lstrcmp(szItem, "Italic") == 0)
                        uItemPos = 3;
                    else if (lstrcmp(szItem, "Underline") == 0)
                        uItemPos = 4;

                    /*
                     * Получим строку символов, которая соответствует выбранному элементу.
                     */

                    GetMenuString(hmenu, uItemPos, szItem,
                        sizeof(szItem), MF_BYPOSITION);

                    /*
                     * Приобщим новый текст клавиши - ускорителя к
                     * тексту пункта меню.
                     */

                    for (pch = szItem; *pch != '\t'; pch++);
                    ++pch;

                    for (pch2 = szAccelText; *pch2 != '\0';
                            pch2++)
                        *pch++ = *pch2;
                    *pch = '\0';

                    /*
                     * Изменим пункт меню, чтобы отразить новый
                     * текст клавиши-ускорителя.
                     */

                    idItem = GetMenuItemID(hmenu, uItemPos);
                    ModifyMenu(hmenu, idItem, MF_BYCOMMAND |
                        MF_STRING, idItem, szItem);

                    /* Сбросим выбранные флажки. */

                    fItemSelected = FALSE;
                    fKeySelected = FALSE;

                    /* Сохраняем текущую таблицу клавиш ускорителей. */

                    haccelOld = haccel;

                    /*
                     * Сосчитаем число входов в текущей
                     * таблице, распределим буфер для таблицы, а,
                     * затем скопируем таблицу в буфер.
                     */

                    cAccelerators = CopyAcceleratorTable(haccelOld, NULL, 0);
                    lpaccelNew = (LPACCEL) LocalAlloc(LPTR, cAccelerators * sizeof(ACCEL));

                    if (lpaccelNew != NULL) CopyAcceleratorTable(haccel, lpaccelNew,cAccelerators);

                    /*
                     * Найдем клавишу - ускоритель, которую пользователь модифицировал
                     * и изменим ее флажки и код виртуальной клавиши
                     * в соответствии с этим.
                     */

                    for (i = 0; (lpaccelNew[i].cmd ==
                                (WORD) idItem)
                            && (i < (UINT) cAccelerators); i++) {

                        lpaccelNew[i].fVirt = fAccelFlags;
                        lpaccelNew[i].key = wVKCode;
                    }

                    /*
                     * Создадим новую таблицу клавиш-ускорителей, а
                     * старую разрушим.
                     */

                    DestroyAcceleratorTable(haccelOld);
                    haccel = CreateAcceleratorTable(lpaccelNew,cAccelerators);

                   /* Разрушим диалоговое окно. */

                    EndDialog(hwndDlg, TRUE);
                    return 0;

                case IDCANCEL:
                    EndDialog(hwndDlg, TRUE);
                    return TRUE;

                default:
                    break;
            }
        default:
            break;
    }
    return FALSE;
}


9.9 - Справочник по ускорителям клавиатуры

Следующие функции, структуры и сообщения связаны с ускорителями клавиатуры.


9.9.1 - Функции ускорителей клавиатуры

Следующее - функции, используются с клавишами - ускорителями.
CopyAcceleratorTable
CreateAcceleratorTable
DestroyAcceleratorTable
LoadAccelerators
TranslateAccelerator


9.9.1.1 - Фунция CopyAcceleratorTable

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

Синтаксис

int CopyAcceleratorTable
(
    HACCEL hAccelSrc,	// дескриптор копируемой таблицы клавиш-ускорителей
    LPACCEL lpAccelDst,	// указатель на структуру принимающую копию
    int cAccelEntries	// число вводов в копируемую таблицу
);

Параметры
hAccelSrc
Идентифицирует таблицу клавиш-ускорителей, которая копируется.
lpAccelDst
Указывает на массив структур ACCEL, куда информация о таблице клавиш-ускорителей должна быть скопирована.
cAccelEntries
Определяет число структур ACCEL для копирования в буфер, указанный параметром lpAccelDst.

Возвращаемые значения
Если lpAccelDst имеет значение ПУСТО (NULL), величина возвращаемого значения определяет число введенных таблиц клавиш-ускорителей в первоначальную таблицу. Иначе, он определяет число введенных таблиц клавиш-ускорителей, которые были скопированы.

Смотри также
ACCEL, CreateAcceleratorTable, DestroyAcceleratorTable, LoadAccelerators, TranslateAccelerator

Размещение и совместимость CopyAcceleratorTable

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


9.9.1.2 - Функция CreateAcceleratorTable

Функция CreateAcceleratorTable создает таблицу клавиш-ускорителей.

Синтаксис

HACCEL CreateAcceleratorTable
(
    LPACCEL lpaccl,	// указатель на массив структур с данными клавиши - ускорителя
    int cEntries 	// число структур в массиве
);

Параметры
lpaccl
Указывает на массив структур ACCEL, который описывает таблицу клавиш-ускорителей.
cEntries
Определяет число структур ACCEL в массиве.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - дескриптор к созданной таблице клавиш-ускорителей; иначе, это значение ПУСТО (NULL).

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

Смотри также
ACCEL, CopyAcceleratorTable, DestroyAcceleratorTable, LoadAccelerators, TranslateAccelerator

Размещение и совместимость CreateAcceleratorTable

Windows NT				Да
Win95					Да
Win32s					Нет
Импортируемая библиотека			user32.lib
Заголовочный файл				winuser.h
Unicode					WinNT
Замечания по платформе			Не имеется


9.9.1.3 - Функция DestroyAcceleratorTable

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

Синтаксис

BOOL DestroyAcceleratorTable
(
    HACCEL hAccel 	// дескриптор таблицы клавиш-ускорителей
);

Параметры
hAccel
Идентифицирует таблицу клавиш-ускорителей, которая уничтожается. Этот дескриптор, должен быть создан при помощи вызова функции CreateAcceleratorTable.

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

Смотри также
CopyAcceleratorTable, CreateAcceleratorTable, LoadAccelerators, TranslateAccelerator

Размещение и совместимость DestroyAcceleratorTable

Windows NT			Да
Win95				Да
Win32s				Нет
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


9.9.1.4 - Функция LoadAccelerators

Функция LoadAccelerators загружает заданную таблицу клавиш-ускорителей.

Синтаксис

HACCEL LoadAccelerators
(
    HINSTANCE hInstance,	// дескриптор экземпляра приложения
    LPCTSTR lpTableName 	// адрес строки с названием таблицы
);

Параметры
hInstance
Идентифицирует экземпляр модуля, чей исполняемый файл содержит таблицу клавиш-ускорителей для загрузки.
lpTableName
Указывает на строку с символом нуля в конце, которая именует таблицу клавиш-ускорителей для загрузки. Альтернативно, этот параметр может определять, что идентификатор ресурса таблицы клавиш-ускорителей в младшем слове и нуль в старшем слове. Может быть использована макрокоманда MAKEINTRESOURCE, чтобы создать это значение.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - дескриптор загруженной таблицы клавиш-ускорителей.
Если функция не выполняет задачу, величина возвращаемого значения - ПУСТО (NULL).

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

Смотри также
CopyAcceleratorTable, CreateAcceleratorTable, DestroyAcceleratorTable, MAKEINTRESOURCE

Размещение и совместимость LoadAccelerators

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


9.9.1.5 - Функция TranslateAccelerator

Функция TranslateAccelerator обрабатывает клавиши - ускорители для команд меню. Функция транслирует сообщение WM_KEYDOWN или WM_SYSKEYDOWN в сообщение WM_COMMAND или WM_SYSCOMMAND (если имеется элемент для клавиши в заданной таблице клавиш-ускорителей), а затем передает сообщение WM_COMMAND или WM_SYSCOMMAND непосредственно соответствующей оконной процедуре. TranslateAccelerator не возвращает значения до тех пор, пока оконная процедура не обработает сообщение.

Синтаксис

int TranslateAccelerator
(
    HWND hWnd,	// дескриптор окна назначения
    HACCEL hAccTable,	// дескриптор таблицы клавиш-ускорителей
    LPMSG lpMsg	// адрес структуры с сообщением
);

Параметры
hWnd
Идентифицирует окно, сообщения которого должны быть оттранслированы.
hAccTable
Идентифицирует таблицу клавиш-ускорителей. Таблица должна быть загружена при помощи вызова функции LoadAccelerators или создана вызовом функции CreateAcceleratorTable.
lpMsg
Указывает на структуру MSG, которая содержит информацию сообщения, извлеченного из очереди сообщений вызывающего потока при помощи использования функции GetMessage или PeekMessage.

Возвращаемые значения
Если функция завершается успешно, величина возвращаемого значения - ИСТИНА (TRUE).
Если функция не выполняет задачу, величина возвращаемого значения - ЛОЖЬ(FALSE). Чтобы получить дополнительные данные об ошибках, вызовите GetLastError.

Замечания
Чтобы отличить сообщение, которые эта функция посылает, от сообщений, отправленных меню или элементами управления, старшее слово параметра wParam сообщения WM_COMMAND или WM_SYSCOMMAND, содержит значение 1.
Комбинации клавиш - ускорителей, используемые для выбра пунктов из меню окна, транслируются в сообщение WM_SYSCOMMAND; все другие комбинации клавиш - ускорителей транслируются в сообщения WM_COMMAND.
Когда TranslateAccelerator возвращает значение отличное от нуля, а сообщение оттранслировано, прикладная программа не должна использовать функцию TranslateMessage для того, чтобы обработать сообщение снова.
Клавише - ускорителю не обязательно надо соответствовать команде меню.
Если команда клавиши - ускорителя соответствует пункту меню, прикладная программа посылает сообщения WM_INITMENU и WM_INITMENUPOPUP, как будто пользователь попытался показать меню. Однако, эти сообщения не посылаются, если встречается какое-либо из следующих условий:
Окно заблокировано.
Пункт меню заблокирован.
Комбинация клавиши - ускорителя не соответствует элементу в меню окна и окно свернуто.
Фактически был произведен захват мыши. За информацией о захвате мыши, обратитесь в функцию SetCapture.
Если определяемое окно - активное окно, и никакое другое окно не имеет фокус клавиатуры (это обычно является случаем, если окно свернуто), TranslateAccelerator транслирует сообщения WM_SYSKEYUP и WM_SYSKEYDOWN вместо сообщений WM_KEYDOWN и WM_KEYUP.
Если происходит нажатие клавиши - ускорителя, которое соответствует пункту меню, когда окно, которое владеет меню, свернуто, TranslateAccelerator не отправляет сообщение WM_COMMAND. Однако, если происходит нажатие клавиши - ускорителя, которое не соответствует никакому из пунктов меню или меню окна, функция отправляет сообщение WM_COMMAND, даже если окно свернуто.

Смотри также
CreateAcceleratorTable, GetMessage, LoadAccelerators, MSG, PeekMessage, SetCapture, TranslateMessage, WM_COMMAND, WM_INITMENU, WM_INITMENUPOPUP, WM_KEYDOWN, WM_SYSKEYDOWN, WM_SYSCOMMAND

Размещение и совместимость TranslateAccelerator

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		user32.lib
Заголовочный файл			winuser.h
Unicode				WinNT
Замечания по платформе		Не имеется


9.9.2 - Структуры ускорителя клавиатуры

Ниже следующая структура используется с клавишами - ускорителями.
ACCEL


9.9.2.1 - Структура ACCEL

Структура ACCEL определяет клавишу - ускоритель, использованную в таблице клавиш-ускорителей.

Синтаксис

typedef struct tagACCEL { // accl
    BYTE fVirt;
    WORD key;
    WORD cmd;
} ACCEL;

Члены структуры
fVirt
Устанавливает флажки клавиши - ускорителя. Этот член может быть комбинацией следующих значений:

  • FALT - Клавиша ALT должна удерживаться нажатой, когда нажимается клавиша - ускоритель.
  • FCONTROL - Клавиша CTRL должна удерживаться нажатой, когда нажимается клавиша - ускоритель.
  • FNOINVERT - Определяет, что никакой другой пункт меню верхнего уровня не выделяется, когда используется клавиша - ускоритель. Если этот флажок не установлен, пункт меню верхнего уровня будет выделен, если возможно, когда используется акселератор.
  • FSHIFT - Клавиша SHIFT должна удерживаться нажатой, когда нажимается клавиша - ускоритель.
  • FVIRTKEY - Член структуры key определяет код виртуальной клавиши. Если этот флажок не установлен, key воспринимает его, как определение кода буквы ASCII.

key
Определяет клавишу - ускоритель. Этот член может быть или код виртуальной клавиши или код буквы ASCII.
cmd
Определяет идентификатор клавиши - ускорителя. Это значение помещается в младшем слове параметра wParam сообщения WM_COMMAND или WM_SYSCOMMAND, когда нажимается клавиша - ускоритель.

Смотри также
WM_COMMAND, WM_SYSCOMMAND

Размещение и совместимость ACCEL

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


9.9.3 - Сообщения ускорителей клавиатуры

Нижеследующие сообщения, используются с клавишами - ускорителями.
WM_COMMAND
WM_INITMENU
WM_INITMENUPOPUP
WM_MENUCHAR
WM_MENUSELECT
WM_SYSCHAR
WM_SYSCOMMAND


9.9.3.1 - Сообщение WM_COMMAND

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

Синтаксис

WM_COMMAND
wNotifyCode = HIWORD(wParam);	// код уведомления
wID = LOWORD(wParam);		// идентификатор элемента меню, управления или
                // клавиши ускорителя
hwndCtl = (HWND) lParam;		// дескриптор элемента управления

Параметры
wNotifyCode
Значение старшего слова wParam. Определяет код уведомления, если сообщение из органа управления. Если сообщение от клавиши - ускорителя, этот параметр равен 1. Если сообщение от меню, этот параметр - 0.
wID
Значение младшего слова wParam. Определяет идентификатор пункта меню, органа управления или клавиши - ускорителя.
hwndCtl
Значение lParam. Идентифицирует орган управления, отправляющий сообщение, если сообщение от элемента управления. Иначе, этот параметр имеет значение ПУСТО (NULL).

Возвращаемые значения
Если приложение обрабатывает это сообщение, оно должно возвратить нуль.

Замечание
Нажатия клавиш - ускорителей, которые выбирают пункты меню окна, транслируются в сообщения WM_SYSCOMMAND.
Если происходит нажатие клавиши - ускорителя, которое соответствует пункту меню, когда окно, которое владеет меню, свернуто, сообщение WM_COMMAND не отправляется. Однако, если происходит нажатие клавиши - ускорителя, которое не соответствует какому-либо из пунктов меню или меню окна, сообщение WM_COMMAND отправляется, даже если окно свернуто.
Если прикладная программа включает разделитель меню, система отправляет сообщение WM_COMMAND с младшим словом параметра wParam установленным в нуль, когда пользователь выбирает разделитель.

Смотри также
WM_SYSCOMMAND

Размещение и совместимость WM_COMMAND

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


9.9.3.2 - Сообщение WM_INITMENU

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

Синтаксис

WM_INITMENU
hmenuInit = (HMENU) wParam; // дескриптор меню, которое инициализируется

Параметры
hmenuInit
Значение wParam. Идентифицирует меню, которое будет инициализировано.

Возвращаемые значения
Если приложение обрабатывает это сообщение, оно возвращает нуль.

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

Смотри также
WM_INITMENUPOPUP

Размещение и совместимость WM_INITMENU

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


9.9.3.3 - Сообщение WM_INITMENUPOPUP

Сообщение WM_INITMENUPOPUP отправляется тогда, когда выскакивающее меню или подменю собирается стать активным. Это позволяет прикладной программе модифицировать меню перед его показом на экране без изменения меню полностью.

Синтаксис

WM_INITMENUPOPUP
hmenuPopup = (HMENU) wParam;	// дескриптор подменю
uPos = (UINT) LOWORD(lParam);	// позиция пункта подменю
fSystemMenu = (BOOL) HIWORD(lParam);	// флажок окна меню

Параметры
hmenuPopup
Значение wParam. Идентифицирует выскакивающее меню или подменю.
uPos
Значение младшего слова lParam. Определяет отсчитываемое от нуля взаимное положение пункта меню, который открывает выскакивающее меню или подменю.
fSystemMenu
Значение старшего слова lParam. Определяет, является ли выскакивающее меню меню окна (также известное как Системное меню или меню Control (Управления)). Если это меню - меню окна, этот параметр - ИСТИНА (TRUE); иначе, он имеет значение ЛОЖЬ(FALSE).

Возвращаемые значения
Если приложение обрабатывает это сообщение, оно возвращает нуль.

Смотри также
WM_INITMENU

Размещение и совместимость WM_INITMENUPOPUP

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


9.9.3.4 - Сообщение WM_MENUCHAR

Сообщение WM_MENUCHAR отправляется тогда, когда меню активизируется, а пользователь, нажимает клавишу, которая не соответствует какому-либо символу или клавише - ускорителю. Это сообщение отправляется окну, которое владеет меню.

Синтаксис

WM_MENUCHAR
chUser = (char) LOWORD(wParam);	// символ ASCII
fuFlag = (UINT) HIWORD(wParam);	// флажок меню
hmenu = (HMENU) lParam;		// дескриптор меню

Параметры
chUser
Значение младшего слова wParam. Определяет символ ASCII, который соответствует клавише, нажатой пользователем.
fuFlag
Значение старшего слова wParam. Определяет тип активного меню. Этот параметр может быть одним из следующих значений:

  • MF_POPUP - Выскакивающее меню, подменю или контекстное меню
  • MF_SYSMENU - Меню окна (системное меню (System Menu) или меню Управления (Control menu)

hmenu
Значение lParam. Идентифицирует активное меню.

Возвращаемые значения
Прикладная программа, которая обрабатывает это сообщение, должна возвратить одно из следующих величин в старшем слове возвращаемого значения:

  • 0 - Сообщает Windows, что оперативная система должна сбросить символ нажатый пользователем и создать короткий гудок в системном динамике.
  • 1 - Сообщает Windows, что оперативная система должна закрыть активное меню.
  • 2 - Сообщает Windows, что младшее слово величины возвращаемого значения устанавливает отсчитываемое от нуля взаимное положение пункта меню. Этот элемент выбирается Windows.

Замечания
Младшее слово игнорируется, если старшее слово содержит 0 или 1. Прикладная программа должна обработать это сообщение, когда клавиша - ускоритель используется, чтобы выбрать пункт меню, который отображает точечный рисунок.

Размещение и совместимость WM_MENUCHAR

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


9.9.3.5 - Сообщение WM_MENUSELECT

Сообщение WM_MENUSELECT отправляется окну владельца меню, когда пользователь выбирает пункт меню.

Синтаксис

WM_MENUSELECT
uItem = (UINT) LOWORD(wParam);	// пункт меню или индекс подменю
fuFlags = (UINT) HIWORD(wParam);	// флажки меню
hmenu = (HMENU) lParam;		// дескриптор меню, по которому щелкнули мышью

Параметры
uItem
Значение младшего слова wParam. Если выбранный пункт - командный пункт, этот параметр содержит идентификатор пункта меню. Если выбранный пункт открывает выпрыгивающее меню или подменю, этот параметр содержит индекс меню выпрыгивающего меню или подменю, в главном меню, а параметр hMenu тогда содержит дескриптор главного (по которому щелкнули) меню; используйте функцию GetSubMenu, чтобы получить дескриптор меню выпрыгивающего меню или подменю.
fuFlags
Значение старшего слова wParam. Определяет один или несколько флажков меню. Этот параметр может быть комбинацией следующих значений:

  • MF_BITMAP - Пункт отображает точечный рисунок.
  • MF_CHECKED - Пункт проверяется.
  • MF_DISABLED - Пункт блокируется.
  • MF_GRAYED - Пункт становится недоступным.
  • MF_HILITE - Пункт выделяется.
  • MF_MOUSESELECT - Пункт выбирается при помощи мыши.
  • MF_OWNERDRAW - Пункт нарисованный пользователем.
  • MF_POPUP - Пункт открывает выскакивающее меню или подменю.
  • MF_SYSMENU - Пункт содержится в меню окна (известное также как Системное или Управляющее меню). Параметр hmenu идентифицирует меню окна, связанное с сообщением.

hmenu
Значение lParam. Идентифицирует меню, по которому щелкнули мышью.

Возвращаемые значения
Если приложение обрабатывает это сообщение, оно должно возвратить нуль.

Замечания
Если параметр fuFlags содержит 0xFFFF, а параметр hmenu содержит ПУСТО (NULL), значит Windows закрыла меню.
Не используйте для fuFlags значение –(минус)1. Это не делается потому, что fuFlags определяется как (UINT) HIWORD (wParam). Если бы HIWORD (wParam) было 0xFFFF, fuFlags (из-за приведения UINT) станет 0x0000FFFF, а не –(минус)1.

Смотри также
GetSubMenu

Размещение и совместимость WM_MENUSELECT

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


9.9.3.6 - Сообщение WM_SYSCHAR

Сообщение WM_SYSCHAR посылается окну с фокусом клавиатуры, когда транслируется сообщение WM_SYSKEYDOWN функцией TranslateMessage. Оно определяет код символа системы буквенных клавиш - то есть символ клавиши, которая была нажата, в то время, когда была нажата клавиша ALT.

Синтаксис

WM_SYSCHAR
chCharCode = (TCHAR) wParam;	// код символа
lKeyData = lParam;		// данные на клавишу

Параметры
chCharCode
Значение wParam. Определяет код символа клавиши меню окна.
lKeyData
Значение lParam. Определяет счет повторений, скэн-код, флажок дополнительной клавиши, контекстный код, флажок предыдущего состояния клавиши и флажок переходного состояния, как показано в следующей таблице:

  • 0-15 - Определяет счет повторений. Значение - число раз повторных нажатий клавиши в результате того, что пользователь удерживал клавишу нажатой.
  • 16-23 - Определяет скэн-код. Значение зависит от фирмы - изготовителя оборудования (OEM).
  • 24 - Определяет, является ли клавиша дополнительной клавишей, типа правосторонних клавиш ALT и CTRL, которые появились на усовершенствованных 101- или 102-клавишных клавиатурах. Значение равно 1, если это - клавиша расширения, иначе, это - 0.
  • 25-28 - Зарезервировано, не используется.
  • 29 - Определяет контекстный код. Значение 1, если клавиша ALT удерживалась нажатой, в то время когда нажималась клавиша; иначе, это значение 0.
  • 30 - Определяет предыдущее состояние клавиши. Значение 1, если клавиша внизу перед отправкой сообщения, или это - 0, если клавиша -не нажата.
  • 31 - Определяет переходное состояние. Значение 1, если клавишу освобождают, или это - 0, если клавишу нажимают.

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

Замечания
Когда контекстный код нулевой, сообщение может быть передано в функцию TranslateAccelerator, которая обработает его, как если бы это было стандартное клавишное сообщение вместо системного сообщения символьной клавиши. Это позволяет клавишам - ускорителям быть использованными активным окном, даже если активное окно не имеет фокуса клавиатуры.
Для усовершенствованных 101- и 102-клавишных клавиатур, дополнительными клавишами являются клавиши ALT и CTRL справа на главном разделе клавиатуры; INS, DEL, HOME, END, PAGE UP, PAGE DOWN и клавиши курсора в группах слева от цифровой клавиатуры; клавиша PRINT SCRN; клавиша BREAK; клавиша NUMLOCK; а также клавиши делитель (/) и ENTER в цифровой клавиатуре. Другие клавиатуры могут поддерживать бит дополнительных клавиш в параметре lKeyData.

Смотри также
TranslateAccelerator, TranslateMessage, WM_SYSKEYDOWN

Размещение и совместимость WM_SYSCHAR

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется


9.9.3.7 - Сообщение WM_SYSCOMMAND

Окно получает это сообщение, когда пользователь выбирает команду из меню окна (известное также как Системное меню или Меню управления) или когда пользователь выбирает кнопку Развернуть (Maximize) или кнопку Свернуть (Minimize).

Синтаксис

WM_SYSCOMMAND
uCmdType = wParam;        		// затребованный тип системной команды
xPos = LOWORD(lParam); 		// горизонтальная позиция, в экранных координатах
yPos = HIWORD(lParam); 		// вертикальная позиция, в экранных координатах

Параметры
uCmdType
Определяет тип запрошенной системной команды. Он может быть одним из этих значений:

  • SC_CLOSE - Закрывает окно.
  • SC_CONTEXTHELP - Изменяет курсор на указатель с вопросительным знаком. Если пользователь затем щелкает кнопкой мыши по органу управления в диалоговом окне, элемент управления получает сообщение WM_HELP.
  • SC_DEFAULT - Выбирает заданный по умолчанию пункт; пользователь дважды щелкнул мышью по меню окна.
  • SC_HOTKEY - Активизирует окно, связанное с определяемой прикладной программой последовательностью клавиш-ускорителей "hot key". Младшее слово lParam идентифицирует окно, которое активизируется.
  • SC_HSCROLL - Прокрутка содержимого окна по горизонтали.
  • SC_KEYMENU - Извлекает данные о меню окна в результате нажатия клавиши.
  • SC_MAXIMIZE (или SC_ZOOM) - Развертывает окно.
  • SC_MINIMIZE (или SC_ICON) - Свертывает окно.
  • SC_MONITORPOWER - Только для Windows 95: Устанавливает состояние дисплея. Эта команда поддерживает устройства, которые имеют энергосберегающие функции, типа персонального компьютера с батарейным питанием.
  • SC_MOUSEMENU - Извлекает данные о меню окна в результате щелчка клавиши мыши.
  • SC_MOVE - Перемещает окно.
  • SC_NEXTWINDOW - Перемещает в следующее окно.
  • SC_PREVWINDOW - Перемещает в предыдущее окно.
  • SC_RESTORE - Восстанавливает окно в обычной позиции и размере.
  • SC_SCREENSAVE - Запускает программу-заставку приложения, определяемую в разделе [boot] (начальной загрузки) файла SYSTEM.INI.
  • SC_SIZE - Изменяет размеры окна.
  • SC_TASKLIST - Запускает или активизирует Windows Task Manager (Диспетчер задач).
  • SC_VSCROLL - Прокрутка содержимого окна по вертикали.

xPos
Определяет горизонтальную позицию курсора, в экранной системе координат, если команда меню окна выбрана при помощи мыши. Иначе, xPos параметр не используется.
yPos
Определяет вертикальную позицию курсора, в экранной системе координат, если команда меню окна выбрана при помощи мыши. Этот параметр является – (минус) 1, если команда выбрана, с использованием клавиши - ускорителя системы, или нуль, если использовалась мнемоника.

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

Замечания
Функция DefWindowProc завершает запрос меню окна о предопределенных действиях, перечисленных в предыдущей таблице.
В сообщениях WM_SYSCOMMAND, четыре младших бита параметра uCmdType используются для внутренних потребностей Windows. Чтобы получить правильный результат при проверке значения uCmdType, прикладная программа должна объединить значение 0xFFF0 со значением uCmdType при помощи использования побитового оператора AND.
Пункты в меню окна могут быть изменены при помощи использования функций GetSystemMenu, AppendMenu, InsertMenu, ModifyMenu, InsertMenuItem и SetMenuItem. Прикладные программы, которые изменяют меню окна, должны обрабатывать сообщения WM_SYSCOMMAND.
Прикладная программа может выполнить любую команду системы в любое время, передавая сообщение WM_SYSCOMMAND в DefWindowProc. Любые сообщения WM_SYSCOMMAND, не обработанные программой должны быть переданы в DefWindowProc. Любые значения команд, добавленные приложением, должны быть обработаны прикладной программой и не могут быть переданы в DefWindowProc.
Клавиши-ускорители, которые определены для выбора пунктов из меню окна, транслируются в сообщения WM_SYSCOMMAND; все другие нажатия клавиш - ускорителей транслируются в сообщения WM_COMMAND.

Смотри также
AppendMenu, DefWindowProc, GetSystemMenu, InsertMenu, ModifyMenu, WM_COMMAND

Размещение и совместимость WM_SYSCOMMAND

Windows NT			Да
Win95				Да
Win32s				Да
Импортируемая библиотека		-
Заголовочный файл			winuser.h
Unicode				Нет
Замечания по платформе		Не имеется
Предыдущий Шаг