Параметр 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)WtnMam получаст SW_SIHOWMINNOACTIVE в параметре nCmdSbow,
Таким образом, пользователь может легко выбирать, в каком окне запускать про грамму — нормальном, свернутом или развернутом.
Рис. 4-3. Окно свойств для ярлыка Notepad
Наконец, чтобы получить копию структуры STARTUPINFO, инициализированной родительским процессом, приложение может вызвать:
VOID GetStartupInfo(PSTARTUPINFO pStartupInfo);
Анализируя эту структуру, дочерний процесс может изменять свое поведение в зависимости oi значений ее элементов
NOTE
Хотя в документации на Windows об этом четко не сказано, перед вызовом GetStartupInfo нужно инициализировать элемент cb структуры STARTUPINFO:
STARTUPINFO si = { sizeof(si) }, GetStartupInfo(&si)