Windows для профессионалов


Параметр psiStartlnfo


Этот параметр указывает на структуру STARTUPINFO:

typedef struct _STARTUPINFO {
DWORD cb;
PSTH lpReserved;
PSTR lpDesktop;
PSTR lpTitle;
DWORD dwX;
DWORD dwY;

DWORD dwXSize;
DWORD dwYSize;
DWORD dwXCountChars;
DWORD dwYCountChars;
DWORD dwFillAttribute;
DWORD dwFlags;
WORD wShowWindOw;
WORD cbReserved2;
PBYTE lpReserved2;
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;
} STARTUPINFO, *LPSTARTUPINFO;

Элементы структуры STARTUPINFO используются Windows-функциями при созда нии нового процесса. Надо сказать, что большинство приложений порождает процес сы с атрибутами по умолчанию Но и в этом случае Вы должны инициализировать все элементы структуры STARTUPINFO хотя бы нулевыми значениями, а в элемент сb — заносить размер этой структуры:

STARTUPINFO si = { sizeof(si) }; CreateProcess(.. , &si, ...};

К сожалению, разработчики приложений часто забывают о необходимости ини циализации этой структуры. Если Вы не обнулите ее элементы, в них будет содержать ся мусор, оставшийся в стеке вызывающего потока. Функция CreateProcess, получив такую структуру данных, либо создаст новый процесс, либо нет — все зависит от того, что именно окажется в этом мусоре.

Когда Вам понадобится изменить какие-то элементы структуры, делайте это пе ред вызовом CreateProcess. Все элементы зтой структуры подробно рассматриваются в таблице 4-3- Но заметьте, что некоторые элементы имеют смысл, только если до чернее приложение создает перекрываемое (overlapped) окно, а другие — если это приложение осуществляет ввод-вывод на консоль

Элемент

Окно или консоль



Описание

cb

То и другое

Содержит количество байтов, занимаемых структу рой STARTUPINFO. Служит для контроля версий — на тот случай, если Microsoft расширит эту структуру в будущем Программа должна инициализировать cb как sizeof(STARTUPINFO)

lpReserved

То и другое

Зарезервирован Инициализируйте как NULL.

IpDesktop

То и другое

Идентифицирует имя рабочего стола, на котором за пускается приложение Если указанный рабочий стол существует, новый процесс сразу же связывается с ним. В ином случае система сначала создает рабочий стол с атрибутами по умолчанию, присваивает ему имя, указанное в данном элементе структуры, и свя зываем его с новым процессом. Если IpDesktop равен NULL (что чаще всего и бывает), процесс связывается с текущим рабочим столом.

IpTitle

Консоль

Определяет заголовок консольного окна. Если IpTitle — NULL, в заголовок выводится имя исполняе мого файла.

<
Таблица 4-3. Элементы структуры STARTUPINFO












Элемент

Окно или консоль

Описание

dwX
dwY

То и другое

Указывают х- и j'-координаты ( в пикселах) окна приложения Эти координаты используются, только если дочерний процесс создаст свое первое перекры ваемое окно с идентификатором CW_USEDEFAULT в параметре х функции CreateWindow. В приложениях, создающих консольные окна, данные элементы опре деляют верхний левый угол консольною окна.

dwXSize
dwYSize

То и другое

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

dwXCountChars dwYCountChars

Консоль

Определяют ширину и высоту (в символах) консольных окон дочернего процесса

dwFillAttnbute

Консоль

Задает цвет текста и фона в консольных окнах дочернего процесса

dwFlags

То и другое

См ниже и следующую таблицу

wSbowWtndow

Окно

Определяет, как именно должно выглядеть первое перекрываемое окно дочернего процесса, если приложение при первом вызове функции ShowWindow передает в параметре nCmdSbow идентификаюр SW_SHOWDEFAULT. В этот элеменn можно записать любой из идентификаторов типа SW_*, обычно используемых при вызове SbowWindoiv.

cbReserved2

То и друюс

Зарезервирован Инициализируйте как 0.

lpReserved2

То и друюс

Зарезервирован. Инициализируйте как NULL.

hStdlnput
hStdOutlput
bStdError

Консоль

Определяют описатели буферов для консольного ввода-вывода. По умолчанию bStdlnpitt идентифицирует буфер клавиатуры, a bStdOutput и bStdError — буфер консольного окна

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


Список допустимых флагов приведен в следующей таблице.









Флаг

Описание

STARTF_USESIZE

Заставляет использовать элементы divSize и dwYSize

STARTF_USESHOWWINDOW

Заставляет использовать элемент wShowWindow

STARTF_USEPOSITION

Заставляет использовать элементы dwX и dwY

STARTF_USECOTUNTCHARS

Заставляет использовать элементы dwXCountChars и dwYCountCbars

STARTF_USEFILLATTRIBUTE

Заставляет использовать элемент dwFillAttnbute

STARTF_USESTDHANDLES

Заставляет использовать элементы hStdlnput, hStdOutput и bStdError





Флаг

Описание

STARTF_RUN_FULLSCREEN

Приводит к тому, что консольное приложение на компью тере с процессором типа х86 запускается в полноэкран ном режиме

Два дополнительных флага — STARTF_FORCEONFEEDBACK и STARTF_FORCEOFF FEEDBACK — позволяют контролировать форму курсора мыши в момент запуска но вого процесса. Поскольку Windows поддерживает истинную вытесняющую многоза дачность, можно запустить одно приложение и, пока оно инициализируется, пора ботать с другой программой. Для визуальной обратной связи с пользователем функ ция CreateProcess временно изменяет форму системного курсора мыши:
Курсор такой формы подсказывает: можно либо подождать чего-нибудь, что вот вот случится, либо продолжить работу в системе. Если же Вы укажете флаг STARTF_ FORCEOFFFEEDBACK, CreateProcess не станет добавлять "песочные часы" к стандарт ной стрелке.
Флаг START_FFORCEONFEEDBACK заставляет CreateProcess отслеживать инициали зацию нового процесса и в зависимости от результата проверки изменять форму кур сора. Когда функция CreateProcess вызывается с этим флагом, курсор преобразуется в "песочные часы" Если спустя две секунды от нового процесса не поступает GUI-вы зов, она восстанавливает исходную форму курсора
Если же в течение двух секунд процесс все же делает GUI-вызов, CreateProcess ждет, когда приложение откроет свое окно. Это должно произойти в течение пяти секунд после GUI-вызова Если окно не появилось, CreateProcess восстанавливает курсор, а появилось — сохраняет его в виде "песочных часов" еще на пять секунд Как только приложение вызовет функцию GetMessage, сообщая тeм самым, что оно закончило инициализацию, CreateProcess немедленно сменит курсор на стандартный и прекра тит мониторинг нового процесса.


В заключение раздела — несколько слов об элементе wShowWindow структуры STARTUPINFO. Этот элемент инициализируется значением, которое Вы передаете в (w)WinMain через ее последний параметр, nCmdShoiv. Он позволяет указать, в каком виде должно появиться главное окно Вашею приложения В качестве значения ис пользуется один из идентификаторов, обычно передаваемых в ShowWindow (чаще всего SW_SHOWNORMAL или SW_SHOWMINNOACTIVE, но иногда и SW_SHOW DEFAULT).
После запуска программы из Explorer ее функция (w)WinMain вызывается с SW_SHOWNORMAL в параметре nCmdShow Если же Вы создаете для нее ярлык, то можете указать в его свойствах, в каком виде должно появляться ее главное окно. На рис. 4-3 показано окно свойств для ярлыка Notepad. Обратите внимание на список Run, в котором выбирается начальное состояние окна Notepad.
Когда Вы активизируете этот ярлык из Explorer, последний создает и инициализирует структуру STARTUPINFO, a затем вызывает CreateProcess. Это приводит к запуску Notepad, а его функция (w)WinMam получает SW_SIHOWMINNOACTIVE в параметре nCmdSbow.
Таким образом, пользователь может легко выбирать, в каком окне запускать программу — нормальном, свернутом или развернутом.

Рис. 4-3. Окно свойств для ярлыка Notepad
Наконец, чтобы получить копию структуры STARTUPINFO, инициализированной родительским процессом, приложение может вызвать:
VOID GetStartupInfo(PSTARTUPINFO pStartupInfo);
Анализируя эту структуру, дочерний процесс может изменять свое поведение в зависимости oт значений ее элементов:
NOTE
Хотя в документации на Windows об этом четко не сказано, перед вызовом GetStartupInfo нужно инициализировать элемент cb структуры STARTUPINFO:
STARTUPINFO si = { sizeof(si) }, GetStartupInfo(&si)

Содержание раздела