Разрешенные значения поля dwFlags




 

Макрос Разрешаемые значения
  START_USESHOWWINDOW dwShowWindow
  STARTF_USESIZE dwXSize и dwYSize
  STARTF_USEPOSITION dwX и dwY
  STARTF_USECOUNTCHARS dwXCountChars и dwYCount-Chars
  STARTF_USEFILLATTRIBUTE dwFillAttribute
  STARTF_USESTDHANDLES hStdInput
  STARTF_FORCEONFEEDBACK Включает возврат курсора
  STARTF_FORCEOFFFEEDBACK Выключает возврат курсора
  STARTF_SCREENSAVER Процесс является «хранителем экрана» (screen saver)

 

Большинство полей структуры STARTUPINFO обычно не используется, и Вы можете их игнорировать. Однако задавать значение поля cb, содержащего размер структуры, обязательно, и, кроме того, некоторые другие поля должны иметь значение NULL. В примере этой главы информация о новом процессе в структуре STARTUPINFO задается следующим образом:

 

STARTUPINFO startin;

//

// Порождение нового процесса

//

startin.cb = sizeof(STARTUPINFO);

startin.lpReserved = NULL;

startin.lpDesktop = NULL;

startin.lpTitle = NULL;

startin.dwFlags = STARTF_USESHOWWINDOW;

startin.cbReserved2 = 0;

startin.lpReserved2 = NULL;

startin. wShowWindow = SW_SHOWMINIMIZED;

 

Таким образом, новый процесс будет начинаться с минимизированным окном, поскольку значение dwFlags установлено в STARTF_USESHOW-WINDOW, что позво­ляет использовать поле wShowWindow (по умолчанию размеры окна нового процесса Windows определяет самостоятельно).

Последним параметром функции CreateProcess() является lpPInfo – указатель на структуру типа PROCESS_INFORMATION, которая определяется следующим образом:

 

typedef struct _PROCESS_INFORMATION

{

HANDLE hProcess; // Дескриптор нового процесса

HANDLE hThread; // Дескриптор главного потока

DWORD dwProcessId;// Идентификатор нового процесса

DWORD dwThreadId; // Идентификатор нового потока

}

PROCESS_INFORMATION;

 

Дескрипторы нового процесса и его главного потока передаются в порождающий процесс в полях hProcess и hThread, а идентификаторы нового процесса и потока – в полях dwProcessId и dwThreadId. Программа может использовать или игнорировать эти значения по своему усмотрению.

Функция CreateProcess() возвращает ненулевое значение при успешном завер­шении и нуль в противном случае.

Вновь созданный процесс практически полностью независим от создавшего его процесса. Вместе с тем родительский процесс может принудительно завершить порожденный процесс. Для этого используется функция API TerminateProcess():

 

BOOL TerminateProcess(HANDLE hProcess, UINT status);

 

Параметр hProcess задает дескриптор порожденного процесса. Это дескриптор из поля hProcess информационной структуры, указатель на которую lpPInfo используется в качестве параметра в функции создания процесса CreateProcess(). Значение параметра status задает код возврата завершаемого процесса. Функция возвращает ненулевое значение при успешном завершении и нуль при возникновении ошибки.

 

Пример 12-1. Программа порождения процессов

 

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

В приведенной ниже программе, как и в других примерах главы, используется техно­логия виртуального окна для отображения и обновления содержимого реального окна.

 

// Демонстрация процессной многозадачности,

// с использованием виртуального окна

#include <Windows.h>

#include <String.h>

#include <Stdio.h>

#include "Proc.h"

#define Procmax 5

 

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

char szWinName[] = "МоеОкно"; // Имя класса окна

char str[255]; // Буфер строки вывода

int X=0, Y=0; // Текущие координаты строки

int procnum=0; // Количество активных процессов

int maxX, maxY; // Размеры экрана

HDC memdc; // DC виртуального окна

HBITMAP hbit; // Растр - это виртуальное окно

HBRUSH hbrush; // Дескриптор кисти

 

PROCESS_INFORMATION pinfo[Procmax];

 

int WINAPI WinMain (HINSTANCE hThisInst,

HINSTANCE hPrevInst,

LPSTR lpszArgs,

int nWinMode)

{

HWND hwnd;

MSG msg;

WNDCLASS wcl;

HACCEL hAccel;

// Определить класс окна

wcl.hInstance=hThisInst; // Дескриптор приложения

wcl.lpszClassName=szWinName; // Имя класса окна

wcl.lpfnWndProc=WindowFunc; // Функция окна

wcl.style=0; // Стиль по умолчанию

wcl.hIcon=LoadIcon(NULL,IDI_APPLICATION); // Иконка

wcl.hCursor=LoadCursor(NULL,IDC_ARROW); // Курсор

wcl.lpszMenuName="MYMENU"; // Меню

wcl.cbClsExtra=0; // Без дополнительной

wcl.cbWndExtra=0; // информации

// Определить заполнение окна белым цветом

wcl.hbrBackground=

(HBRUSH)GetStockObject(WHITE_BRUSH);

if(!RegisterClass(&wcl)) // Зарегистр. класс окна

return 0;

// Создать окно

hwnd=CreateWindow(szWinName, // Имя класса

"Порождение новых процессов",

WS_OVERLAPPEDWINDOW,// Стиль окна

CW_USEDEFAULT, // Х-координата

CW_USEDEFAULT, // Y-координата

CW_USEDEFAULT, // Ширина окна

CW_USEDEFAULT, // Высота окна

HWND_DESKTOP, // Нет родит. окна

NULL, // Нет меню

hThisInst, // Дескрип. приложения

NULL); // Без дополит. аргументов

// Загрузить акселераторы

hAccel=LoadAccelerators(hThisInst,"MYMENU");

ShowWindow(hwnd,nWinMode); // Показать окно и

UpdateWindow(hwnd); // перерисовать содержимое

// Запустить цикл обработки сообщений

while(GetMessage (&msg,NULL,0,0))

if(!TranslateAccelerator(hwnd,hAccel,&msg))

{

TranslateMessage(&msg); // Использ.Клавиатуры

DispatchMessage (&msg); // Возврат к Windows

}

return msg. wParam;

}

 

// Следующая функция вызывается операционной системой

// Windows и получает в качестве параметров сообщения

// из очереди сообщений данного приложения

 

LRESULT CALLBACK WindowFunc(HWND hwnd,

UINT message,

WPARAM wParam,

LPARAM lParam)

{

HDC hdc;

PAINTSTRUCT paintstruct;

TEXTMETRIC tm;

STARTUPINFO startin;

switch(message)

{

case WM_CREATE: // Получаем размеры экрана

maxX=GetSystemMetrics(SM_CXSCREEN);

maxY=GetSystemMetrics(SM_CYSCREEN);

hdc=GetDC(hwnd); // Совмест. с окном растр

memdc=CreateCompatibleDC(hdc);

hbit=CreateCompatibleBitmap(hdc,maxX,maxY);

SelectObject(memdc,hbit);

hbrush=(HBRUSH)GetStockObject(WHITE_BRUSH);

SelectObject(memdc,hbrush);

PatBlt(memdc,0,0,maxX,maxY,PATCOPY);

ReleaseDC(hwnd,hdc);

break;

case WM_COMMAND:

switch(LOWORD(wParam))

{

case ID_PROCESS:

if(procnum == Procmax)

{

MessageBox(hwnd,

"Нельзя создать больше",

"Ошибка", MB_OK);

break;

} // Не более чем Procmax

// Получить метрики текста */

GetTextMetrics(memdc, &tm);

sprintf(str, "Порождается процесс %d",

procnum);

TextOut(memdc, X, Y, str, strlen(str));

Y = Y+tm.tmHeight+tm.tmExternalLeading;

InvalidateRect(hwnd,NULL,1); //Сообщить

// Порождение нового процесса

startin.cb=sizeof(STARTUPINFO);

startin.lpReserved = NULL;

startin.lpDesktop = NULL;

startin.lpTitle = NULL;

startin.dwFlags =STARTF_USESHOWWINDOW;

startin.cbReserved2 = 0;

startin.lpReserved2 = NULL;

startin.wShowWindow = SW_SHOWMINIMIZED;

CreateProcess(NULL, "Test.exe", NULL,

NULL, FALSE, 0, NULL,

NULL, &startin,

&(pinfo[procnum]));

procnum++;

break;

case ID_KILLPROC:

if(procnum)

procnum--;

else

{

MessageBox(hwnd,

"Больше процессов нет",

"Ошибка", MB_OK);

break;

}

// Получить метрики текста

GetTextMetrics(memdc, &tm);

TerminateProcess

(pinfo[procnum].hProcess, 0);

sprintf(str, "Процесс %d завершен",

procnum);

TextOut(memdc, X, Y, str, strlen(str));

Y = Y+tm.tmHeight+tm.tmExternalLeading;

InvalidateRect(hwnd,NULL,1); //Сообщить

break;

case ID_HELP:

MessageBox(hwnd,

"F2: Новый процесс\n"

"F3: Завершить процесс",

"Помощь:", MB_OK);

InvalidateRect(hwnd,NULL,1); //Сообщить

break;

}

break;

case WM_PAINT: // Перерисовка окна

hdc=BeginPaint(hwnd,&paintstruct); // Пол. DC

// Теперь копируем растр из памяти на экран

BitBlt(hdc,0,0,maxX,maxY,memdc,0,0,SRCCOPY);

EndPaint(hwnd,&paintstruct); // Освободить DC

break;

case WM_DESTROY: // Завершение программы

DeleteDC(memdc); // Удалить виртуальное окно

PostQuitMessage(0);

break;

default:

// Все сообщения, не обрабатываемые в данной

// функции, направляются на обработку по

// умолчанию

return DefWindowProc(hwnd,message,

wParam,lParam);

}

return 0;

}

 

Прежде чем компилировать эту программу, нужно создать файл определений Proc.h, приведенный ниже.

 

#define ID_PROCESS 100

#define ID_KILLPROC 101

#define ID_HELP 103

 

Кроме того, придется создать следующий файл ресурсов Process.rc:

 

#include <Windows.h>

#include "Proc.h"

MYMENU MENU

{

POPUP "Процессы"

{

MENUITEM "Новый процесс", ID_PROCESS

MENUITEM "Завершить процесс", ID_KILLPROC

}

MENUITEM "Помощь", ID_HELP

}

MYMENU ACCELERATORS

{

VK_F2, ID_PROCESS, VIRTKEY

VK_F3, ID_KILLPROC, VIRTKEY

VK_F1, ID_HELP, VIRTKEY

}

 

 

Рис. 12.1. Индикация создания и завершения процессов

 

Пример окна этой программы представлен на рис. 12.1.

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2017-03-31 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: