Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

Программирование для Windows NT

© Александр Фролов, Григорий Фролов
Том 26, часть 1, М.: Диалог-МИФИ, 1996, 272 стр.
Рецензия PC WEEK

[Назад] [Содеожание] [Дальше]

Приложение PSTART

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

Главное окно приложения PSTART показано на рис. 3.1.

Рис. 3.1. Главное окно приложения PSTART

Выбрав из меню File строку Start process, вы можете выбрать в диалоговой панели Start Process программный файл запускаемого приложения (рис. 3.2).

Рис. 3.2. Диалоговая панель Start Process

Для выбора параметров запуска воспользуйтесь диалоговой панелью Start Options (рис. 3.3), которая появится на экране при выборе из меню File строки Options.

Рис. 3.3. Диалоговая панель Start Options

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

Исходные тексты приложения

Главный файл исходных текстов приложения PSTART представлены в листинге 3.1.

Листинг 3.1. Файл pstart/pstart.c


#define STRICT
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <stdio.h>
#include <memory.h>
#include "resource.h"
#include "afxres.h"
#include "pstart.h"

HINSTANCE hInst;
char szAppName[]  = "PStartApp";
char szAppTitle[] = "Process Starter";

// Параметры запуска процессов
DWORD dwCreationFlags;

// Флаг ожидания завершения процессов
BOOL  fWaitTermination;

// -----------------------------------------------------
// Функция WinMain
// -----------------------------------------------------
int APIENTRY 
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
        LPSTR lpCmdLine, int nCmdShow)
{
  WNDCLASSEX wc;
  HWND hWnd;
  MSG msg;
  
  // Сохраняем идентификатор приложения
  hInst = hInstance;

  // Преверяем, не было ли это приложение запущено ранее
  hWnd = FindWindow(szAppName, NULL);
  if(hWnd)
  {
    // Если было, выдвигаем окно приложения на
    // передний план
    if(IsIconic(hWnd))
      ShowWindow(hWnd, SW_RESTORE);
    SetForegroundWindow(hWnd);
    return FALSE;
  }

  // Регистрируем класс окна
  memset(&wc, 0, sizeof(wc));
  wc.cbSize = sizeof(WNDCLASSEX);
  wc.hIconSm = LoadImage(hInst,
    MAKEINTRESOURCE(IDI_APPICONSM), 
    IMAGE_ICON, 16, 16, 0);
  wc.style = 0;
  wc.lpfnWndProc = (WNDPROC)WndProc;
  wc.cbClsExtra  = 0;
  wc.cbWndExtra  = 0;
  wc.hInstance = hInst;
  wc.hIcon = LoadImage(hInst,
    MAKEINTRESOURCE(IDI_APPICON), 
    IMAGE_ICON, 32, 32, 0);
  wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
  wc.lpszMenuName = MAKEINTRESOURCE(IDR_APPMENU);
  wc.lpszClassName = szAppName;
  if(!RegisterClassEx(&wc))
    if(!RegisterClass((LPWNDCLASS)&wc.style))
	  return FALSE;
    
  // Создаем главное окно приложения
  hWnd = CreateWindow(szAppName, szAppTitle, 
     WS_OVERLAPPEDWINDOW, 
     CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 
     NULL, NULL, hInst, NULL);
  if(!hWnd) return(FALSE);

  // Отображаем окно и запускаем цикл 
  // обработки сообщений
  ShowWindow(hWnd, nCmdShow);
  UpdateWindow(hWnd);
  while(GetMessage(&msg, NULL, 0, 0))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  return msg.wParam;
}

// -----------------------------------------------------
// Функция WndProc
// -----------------------------------------------------
LRESULT WINAPI
WndProc(HWND hWnd, UINT msg, WPARAM wParam, 
        LPARAM lParam)
{
  switch(msg)
  {
    HANDLE_MSG(hWnd, WM_COMMAND, WndProc_OnCommand);
    default:
      return(DefWindowProc(hWnd, msg, wParam, lParam));
  }
}

// -----------------------------------------------------
// Функция WndProc_OnCommand
// -----------------------------------------------------
#pragma warning(disable: 4098)
void WndProc_OnCommand(HWND hWnd, int id, 
  HWND hwndCtl, UINT codeNotify)
{
  switch (id)
  {
    // Отображаем диалоговую панель для выбора
    // программного файла и запускаем процесс
    case ID_FILE_STARTPROCESS:
    {
      StartProcess(hWnd);
      break;
    }

    case ID_FILE_OPTIONS:
    {
      // Отображаем диалоговую панель, предназначенную
      // для настройки параметров запуска процессов
      DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), 
        hWnd, DlgProc);
      break;
    }
    
    case ID_FILE_EXIT:  
    {
      // Завершаем работу приложения
      PostQuitMessage(0);
      return 0L;
      break;
    }
	  
    case ID_HELP_ABOUT:
    {
      MessageBox(hWnd, 
        "Process Starter\n"
        "(C) Alexandr Frolov, 1996\n"
        "Email: frolov@glas.apc.org",
        szAppTitle, MB_OK | MB_ICONINFORMATION);
      return 0L;
      break;
    }

    default:
      break;
  }
  return FORWARD_WM_COMMAND(hWnd, id, hwndCtl, codeNotify,
    DefWindowProc);
}

// -----------------------------------------------------
// Функция StartProcess
// -----------------------------------------------------
void StartProcess(HWND hwnd)
{
  OPENFILENAME ofn;
  STARTUPINFO si;
  PROCESS_INFORMATION pi;
  char szBuf[256];
  DWORD dwExitCode;

  char szFile[256];
  char szDirName[256];
  char szFileTitle[256];
  char szFilter[256] = "Programs\0*.exe\0Any Files\0*.*\0";
  char szDlgTitle[] = "Start Process";


  memset(&si, 0, sizeof(STARTUPINFO));
  si.cb = sizeof(si);
  
  memset(&ofn, 0, sizeof(OPENFILENAME));
  GetCurrentDirectory(sizeof(szDirName), szDirName);
  szFile[0] = '\0';

  // Подготавливаем структуру для выбора файла
  ofn.lStructSize     = sizeof(OPENFILENAME);
  ofn.hwndOwner       = hwnd;
  ofn.lpstrFilter     = szFilter;
  ofn.lpstrInitialDir = szDirName;
  ofn.nFilterIndex    = 1;
  ofn.lpstrFile       = szFile;
  ofn.nMaxFile        = sizeof(szFile);
  ofn.lpstrFileTitle  = szFileTitle;
  ofn.nMaxFileTitle   = sizeof(szFileTitle);
  ofn.lpstrTitle      = szDlgTitle;
  ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST
    | OFN_HIDEREADONLY;

  // Выводим на экран диалоговую панель, предназначенную
  // для выбора файла
  if(GetOpenFileName(&ofn))
  {
    // Если файл выбран, запускаем его на выполнение
    if (*ofn.lpstrFile)
    {
      // Создаем процесс
      if(CreateProcess(NULL, ofn.lpstrFile, NULL, NULL,
        FALSE, dwCreationFlags, NULL, NULL, &si, &pi))
      {
        // Если было указано, что нужно ждать завершение 
        // процесса, выполняем такое ожидание
        if(fWaitTermination)
        {
          // Освобождаем идентификатор задачи запущенного
          // процесса, так как он нам не нужен
          CloseHandle(pi.hThread);
          
          // Выполняем ожидание завершения процесса
          if(WaitForSingleObject(pi.hProcess, 
            INFINITE) != WAIT_FAILED)
          {
            // Получаем и отображаем код завершения процесса
            GetExitCodeProcess(pi.hProcess, &dwExitCode);

            sprintf(szBuf, "Process terminated\n"
              "Exit Code = %lX", dwExitCode);
      
            MessageBox(hwnd, szBuf, 
              szAppTitle, MB_OK | MB_ICONINFORMATION);
          }

          // Освобождаем идентификатор процесса
          CloseHandle(pi.hProcess);
        }

        // Если процесс был запущен без ожидания,
        // освобождаем идентификаторы задачи и процесса
        else
        {
          CloseHandle(pi.hProcess);
          CloseHandle(pi.hThread);
        }
      }
      
      // Если про запуске процесса произошла ошибка,
      // получаем и отображаем ее код
      else
      {
        sprintf(szBuf, "CreateProcess: error %ld", 
          GetLastError());
      
        MessageBox(hwnd, szBuf, 
          szAppTitle, MB_OK | MB_ICONEXCLAMATION);
      }
    }
  }
}

// -----------------------------------------------------
// Функция DlgProc
// -----------------------------------------------------
LRESULT WINAPI
DlgProc(HWND hdlg, UINT msg, WPARAM wParam, 
        LPARAM lParam)
{
  switch(msg)
  {
    HANDLE_MSG(hdlg, WM_INITDIALOG, DlgProc_OnInitDialog);
    HANDLE_MSG(hdlg, WM_COMMAND,    DlgProc_OnCommand);

    default:
      return FALSE;
  }
}

// -----------------------------------------------------
// Функция DlgProc_OnInitDialog
// -----------------------------------------------------

BOOL DlgProc_OnInitDialog(HWND hdlg, HWND hwndFocus, 
                          LPARAM lParam)
{
  // По умолчанию мы будем запускать процессы
  // с нормальным приоритетом без ожидания
  // их завершения
  CheckDlgButton(hdlg, IDC_NORMAL, 1);
  return TRUE;
}

// -----------------------------------------------------
// Функция DlgProc_OnCommand
// -----------------------------------------------------
#pragma warning(disable: 4098)
void DlgProc_OnCommand(HWND hdlg, int id, 
  HWND hwndCtl, UINT codeNotify)
{
  switch (id)
  {
    case IDOK:
    {
      dwCreationFlags = 0;
      fWaitTermination = FALSE;  

      // Устанавливаем класс приоритета
      if(IsDlgButtonChecked(hdlg, IDC_Realtime))
      {
        dwCreationFlags = REALTIME_PRIORITY_CLASS;  
      }
      else if(IsDlgButtonChecked(hdlg, IDC_HIGH))
      {
        dwCreationFlags = HIGH_PRIORITY_CLASS;  
      }
      else if(IsDlgButtonChecked(hdlg, IDC_NORMAL))
      {
        dwCreationFlags = NORMAL_PRIORITY_CLASS;  
      }
      else if(IsDlgButtonChecked(hdlg, IDC_IDLE))
      {
        dwCreationFlags = IDLE_PRIORITY_CLASS;  
      }

      // Проверяем и устанавливаем режим ожидания
      if(IsDlgButtonChecked(hdlg, IDC_TERMINATION))
      {
        fWaitTermination = TRUE;
      }
      
      EndDialog(hdlg, 0);
      return TRUE;
    }

    case IDCANCEL:
    {
      EndDialog(hdlg, 0);
      return TRUE;
    }

    default:
      break;
  }
  return FALSE;
}

Файл pstart.h (листинг 3.2) содержит прототипы функций, определенных в приложении PSTART.

Листинг 3.2. Файл pstart/pstart.h


// -----------------------------------------------------
// Описание функций
// -----------------------------------------------------
LRESULT WINAPI
WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void WndProc_OnCommand(HWND hWnd, int id, 
  HWND hwndCtl, UINT codeNotify);
void StartProcess(HWND hwnd);

LRESULT WINAPI
DlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam);
BOOL DlgProc_OnInitDialog(HWND hwnd, HWND hwndFocus, 
                          LPARAM lParam);
void DlgProc_OnCommand(HWND hdlg, int id, 
  HWND hwndCtl, UINT codeNotify);

Файл resource.h (листинг 3.3) создается автоматически и содержит определения констант для файла описания ресурсов приложения PSTART.

Листинг 3.3. Файл pstart/resource.h


//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by PStart.rc
//
#define IDR_MENU1                       102
#define IDR_APPMENU                     102
#define IDI_APPICON                     103
#define IDI_APPICONSM                   104
#define IDD_DIALOG1                     105
#define IDC_Realtime                    1004
#define IDC_HIGH                        1005
#define IDC_NORMAL                      1006
#define IDC_IDLE                        1007
#define IDC_TERMINATION                 1008
#define IDC_DETACHED                    1009
#define ID_FILE_EXIT                    40001
#define ID_HELP_ABOUT                   40002
#define ID_FILE_STARTPROCESS            40003
#define ID_FILE_OPTIONS                 40004

// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        106
#define _APS_NEXT_COMMAND_VALUE         40005
#define _APS_NEXT_CONTROL_VALUE         1010
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

В файле определения ресурсов приложения PSTART (листинг 3.4), который создается автоматически системой разработки Microsoft Visual C++, определены главное меню приложения, диалоговая панель для изменения параметров запуска процессов, пиктограммы и текстовые строки.

Листинг 3.4. Файл pstart/pstart.rc


//Microsoft Developer Studio generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
//////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

//////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

//////////////////////////////////////////////////////////////
// English (U.S.) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32

#ifdef APSTUDIO_INVOKED
//////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE DISCARDABLE 
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE DISCARDABLE 
BEGIN
    "#include ""afxres.h""\r\n"
    "\0"
END

3 TEXTINCLUDE DISCARDABLE 
BEGIN
    "\r\n"
    "\0"
END
#endif    // APSTUDIO_INVOKED

//////////////////////////////////////////////////////////////
//
// Menu
//

IDR_APPMENU MENU DISCARDABLE 
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "&Start process",              ID_FILE_STARTPROCESS
        MENUITEM "&Options...",                 ID_FILE_OPTIONS
        MENUITEM SEPARATOR
        MENUITEM "&Exit",                       ID_FILE_EXIT
    END
    POPUP "&Help"
    BEGIN
        MENUITEM "&About",                      ID_HELP_ABOUT
    END
END

//////////////////////////////////////////////////////////////
//
// Icon
//

// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_APPICON             ICON    DISCARDABLE     "PSTART.ICO"
IDI_APPICONSM           ICON    DISCARDABLE     "PSTARTSM.ICO"

//////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_DIALOG1 DIALOG DISCARDABLE  0, 0, 163, 97
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Start Options"
FONT 8, "MS Sans Serif"
BEGIN
    DEFPUSHBUTTON   "OK",IDOK,103,9,50,14
    PUSHBUTTON      "Cancel",IDCANCEL,103,26,50,14
    GROUPBOX        "Priority class",IDC_STATIC,9,4,57,69
    CONTROL         "Realtime",IDC_Realtime,"Button", 
                     BS_AUTORADIOBUTTON | WS_GROUP,15,18,43,10
    CONTROL         "High",IDC_HIGH,"Button",
                     BS_AUTORADIOBUTTON,15,32,31,10
    CONTROL         "Normal",IDC_NORMAL,"Button",
                     BS_AUTORADIOBUTTON,15,45,38,10
    CONTROL         "Idle",IDC_IDLE,"Button",
                     BS_AUTORADIOBUTTON,15,58,27,10
    CONTROL         "Wait process termination",
                     IDC_TERMINATION,"Button",
                     BS_AUTOCHECKBOX | WS_TABSTOP,15,81,93,10
END

//////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE 
BEGIN
    IDD_DIALOG1, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 156
        TOPMARGIN, 7
        BOTTOMMARGIN, 90
    END
END
#endif    // APSTUDIO_INVOKED

#endif    // English (U.S.) resources
//////////////////////////////////////////////////////////////

#ifndef APSTUDIO_INVOKED
//////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
//////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED

Определения и глобальные переменные

Для работы со стандартной диалоговой панелью, с помощью которой выбирается запускаемый программный файл, в исходный текст приложения включается файл commctrl.h.

В области глобальных переменных нашего приложения определены переменные dwCreationFlags и fWaitTermination. Первая из них содержит флаги создания процессов, которые настраиваются при помощи диалоговой панели Start Options и используются при запуске процессов функцией CreateProcess XE "CreateProcess" . Во второй переменной хранится признак необходимости ожидания завершения процессов. Содержимое этой переменной изменяется также при помощи диалоговой панели Start Options.

Описание функций

Приведем краткое описание наиболее важных функций, определенных в нашем приложении.

Функция WinMain

Функция WinMain выполняет обычные действия, создавая главное окно приложения и запуская цикл обработки сообщений.

Функция WndProc

В задачу функции WndProc входит обработка сообщения WM_COMMAND, которая выполняется с помощью функции WndProc_OnCommand. Все остальные сообщения передаются функции DefWindowProc.

Функция WndProc_OnCommand

Эта функция обрабатывает сообщение WM_COMMAND, поступающее в главное окно приложения от меню. Когда пользователь выбирает из меню File строку Start process, функция WndProc_OnCommand вызывает функцию StartProcess, определенную в нашем приложении. Последняя отображает на экране стандартную панель выбора программного файла и в случае успешного выбора запускает этот файл на выполнение как отдельный процесс. При этом используются параметры запуска, установленные при помощи диалоговой панели Start Options.

В том случае когда пользователь выбирает из меню File строку Options, на экране отображается модальная диалоговая панель Start Options, имеющая идентификатор MAKEINTRESOURCE XE "MAKEINTRESOURCE" (IDD_DIALOG1).

Отображение диалоговой панели выполняется с помощью функции DialogBox:


DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, DlgProc);

Эта функция, а также все, что относится к диалоговым панелям, мы описали в главе “Диалоговые панели” 12 тома “Библиотеки системного программиста”.

Заметим, что в среде 32-разрядных операционных систем Microsoft Windows 95 и Microsoft Windows NT в качестве последнего параметра функции DialogBox можно указывать имя функции диалога. При этом вам не требуется создавать переходник диалоговой функции, вызывая функцию MakeProcInstance. Функция MakeProcInstance не используется 32-разрядными приложениями.

Функция StartProcess

Функция StartProcess выполняет запуск программного файла, выбранного пользователем.

Для выбора программного файла используется функция GetOpenFileName, которую мы подробно описали в разделе “Стандартные диалоговые панели для открытия файлов” 13 тома “Библиотеки системного программиста”. Путь к выбранному файлу записывается в поле lpstrFile структуры ofn.

Запуск процесса выполняется функцией CreateProcess, которая вызывается следующим образом:


if(CreateProcess(NULL, ofn.lpstrFile, NULL, NULL,
        FALSE, dwCreationFlags, NULL, NULL, &si, &pi))
{
   . . .
}

Первый параметр функции CreateProcess указан как NULL, поэтому адрес символьной строки, содержащей путь к программному файлу, передается через второй параметр. Напомним, что с помощью этого параметра можно передать функции CreateProcess командную строку (с параметрами) для запуска приложения.

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

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

Через шестой параметр функции CreateProcess передаются флаги создания процесса. Здесь мы используем глобальную переменную dwCreationFlags, содержимое которой устанавливается функцией диалога диалоговой панели Create Options. Эта функция будет описана ниже.

Седьмой и восьмой параметры функции CreateProcess, задают, соответственно, адрес блока среды и путь к рабочему каталогу. Так как оба этих параметра указаны как NULL, создаваемый дочерний процесс пользуется родительской средой и родительским рабочим каталогом.

Через девятый параметр функции CreateProcess передается адрес структуры si типа STARTUPINFO XE "STARTUPINFO" . Ни одно из полей этой структуры, кроме поля cb, не используется, поэтому инициализация структуры выполняется очень просто:


memset(&si, 0, sizeof(STARTUPINFO));
si.cb = sizeof(si);

И, наконец, через последний, десятый параметр функции CreateProcess передается адрес структуры pi типа PROCESS_INFORMATION. Напомним, что после удачного запуска процесса в эту структуру записываются идентификаторы, а также системные номера процесса и его главной задачи.

В случае успешного запуска процесса функция StartProcess проверяет необходимость ожидания его завершения. По умолчанию ожидание не выполняется, однако если пользователь включил в диалоговой панели Start Options переключатель Wait process termination, функция этой диалоговой панели записывает в глобальную переменную fWaitTermination значение TRUE. При этом функция StartProcess будет ожидать завершение запущенного процесса.

В режиме ожидания функция StartProcess вначале закрывает ненужный ей больше идентификатор главной задачи процесса pi.hThread, а затем вызывает функцию WaitForSingleObject XE "WaitForSingleObject" , передавая ей в качестве первого параметра идентификатор процесса pi.hProcess, завершение которого необходимо дождаться. Второй параметр задает ожилание в течении неограниченного времени:


if(WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_FAILED)
{
  . . .
}

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

После того как запущенный процесс завершит свою работу, функция WaitForSingleObject вернет управление вызвавшей ее функции StartProcess. Вслед за этим приложение получит и отобразит код завершения процесса.

Для получения кода завершения процесса мы воспользовались функцией GetExitCodeProcess:


GetExitCodeProcess(pi.hProcess, &dwExitCode);

Через первый параметр этой функции передается идентификатор завершившегося процесса, а через второй - адрес переменной типа DWORD, в которую будет записан код завершения.

После отображения кода завершения идентификатор процесса освобождается функцией CloseHandle XE "CloseHandle" .

В том случае, когда процесс был запущен без ожидания его завершения, сразу после запуска функция StartProcess закрывает идентификаторы процесса и его главной задачи:


CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);

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

Функция DlgProc

Функция диалога DlgProc обарбатывает сообщения WM_INITDIALOG и WM_COMMAND, поступающие от диалоговой панели Start Options. Для обработки этих сообщений она вызывает, соответственно, функции DlgProc_OnInitDialog и DlgProc_OnCommand.

Функция DlgProc_OnInitDialog

Эта функция обрфабатывает сообщение WM_INITDIALOG XE "WM_INITDIALOG" , поступающее в функцию диалога при инициализации последнего. Задачей обработчика сообщения WM_INITDIALOG является установка органов управления, расположенных в диалоговой панели, в начальное состояние. Мы устанавливаем во включенное состояние переключатель Normal, который определяет нормальный класс приоритета для запускаемых процессов.

Установка переключателей выполняется макрокомандой CheckDlgButton XE "CheckDlgButton" , подробно описанной в 12 томе “Библиотеки системного программиста”:


CheckDlgButton(hdlg, IDC_NORMAL, 1);

Функция DlgProc_OnCommand

Задачей функции DlgProc_OnCommand является обработка сообщения WM_COMMAND, поступающего в функцию диалогоа от органов управления, расположенных в диалоговой панели Start Options.

Когда пользователь нажимает кнопку OK, функция DlgProc_OnCommand определяет текущее состояние органов управления и устанавливает соответствующим образом содержимое двух глобальных переменных с именами dwCreationFlags и fWaitTermination.

В переменную dwCreationFlags записывается выбранный класс приоритета запускаемого процесса. Состояние переключателя с зависимой фиксацией, отвечающего за выбор класса приоритета, определяется с помощью макрокоманды IsDlgButtonChecked XE "IsDlgButtonChecked" .

Что же касается глобальной переменной fWaitTermination, то ее значение устанавливается в соответствии с сотоянием переключателя с независимой фиксацией Wait process termination.

После того как содержимое глобальных переменных будет установлено, диалоговая панель удаляется функцией EndDialog XE "EndDialog" .

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

[Назад] [Содеожание] [Дальше]