Программирование для Windows NT (том 2)

       

Приложение Fmap/Client


Исходные тексты приложения Fmap/Client, предназначенного для совместной работы с приложением Fmap/Server, представлены в листинге2.2.

Листинг 2.2. Файл fmap/client/client.c

#include <windows.h>

#include <stdio.h>

#include <conio.h>

// Идентификаторы объектов-событий, которые используются

// для синхронизации задач, принадлежащих разным процессам

HANDLE hEvent;

HANDLE hEventTermination;

// Имя объекта-события для синхронизации ввода и отображения

CHAR lpEventName[] =

  "$MyVerySpecialEventName$";

// Имя объекта-события для завершения процесса

CHAR lpEventTerminationName[] =

  "$MyVerySpecialEventTerminationName$";

// Имя отображния файла на память

CHAR lpFileShareName[] =

  "$MyVerySpecialFileShareName$";

// Идентификатор отображения файла на память

HANDLE hFileMapping;

// Указатель на отображенную область памяти

LPVOID lpFileMap;

int main()

{

  CHAR chr;

  printf("Mapped and shared file, client process\n"

    "(C) A. Frolov, 1996, Email: frolov@glas.apc.org\n"

    "\n\nPress <ESC> to terminate...\n");

 

  // Открываем объект-событие для синхронизации

  // ввода и отображения

  hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, lpEventName);

 

  if(hEvent == NULL)

  {

    fprintf(stdout,"OpenEvent: Error %ld\n",

      GetLastError());

    getch();

    return 0;

  }

  // Открываем объект-событие для сигнализации о

  // завершении процесса ввода

  hEventTermination = OpenEvent(EVENT_ALL_ACCESS,

    FALSE, lpEventTerminationName);

 

  if(hEventTermination == NULL)

  {

    fprintf(stdout,"OpenEvent (Termination): Error %ld\n",

      GetLastError());

    getch();

    return 0;

  }

  // Открываем объект-отображение

  hFileMapping = OpenFileMapping(

    FILE_MAP_READ | FILE_MAP_WRITE, FALSE, lpFileShareName);

  // Если открыть не удалось, выводим код ошибки


  if(hFileMapping == NULL)

  {

    fprintf(stdout,"OpenFileMapping: Error %ld\n",

      GetLastError());

    getch();

    return 0;

  }

  // Выполняем отображение файла на память.

  // В переменную lpFileMap будет записан указатель на

  // отображаемую область памяти

  lpFileMap = MapViewOfFile(hFileMapping,

    FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);

  // Если выполнить отображение не удалось,

  // выводим код ошибки

  if(lpFileMap == 0)

  {

    fprintf(stdout,"MapViewOfFile: Error %ld\n",

      GetLastError());

    getch();

    return 0;

  }

  // Цикл ввода. Этот цикл завершает свою работу,

  // когда пользователь нажимает клавишу <ESC>,

  // имеющую код 27

  while(TRUE)

  {

    // Проверяем код введенной клавиши

    chr = getche();

   

    // Если нажали клавишу <ESC>, прерываем цикл

    if(chr == 27)

      break;

    // Записываем символ в отображенную память,

    // доступную серверному процессу

    *((LPSTR)lpFileMap) = chr;

    // Устанавливаем объект-событие в отмеченное

    // состояние

    SetEvent(hEvent);

  }

 

  // После завершения цикла переключаем оба события

  // в отмеченное состояние для отмены ожидания в

  // процессе отображения и для завершения этого процесса

  SetEvent(hEvent);

  SetEvent(hEventTermination);

 

  // Закрываем идентификаторы объектов-событий

  CloseHandle(hEvent);

  CloseHandle(hEventTermination);

  // Отменяем отображение файла

  UnmapViewOfFile(lpFileMap);

  // Освобождаем идентификатор созданного

  // объекта-отображения

  CloseHandle(hFileMapping);

  return 0;

}

После создания объектов-событий, предназначенных для синхронизации работы с приложением Fmap/Server, функция main приложения Fmap/Client открывает отображение при помощи функции OpenFileMapping, как это показано ниже:

hFileMapping = OpenFileMapping(

  FILE_MAP_READ | FILE_MAP_WRITE, FALSE, lpFileShareName);



В качестве имени отображения здесь указывается строка $MyVerySpecialFileShareName$ - точно такая же, что и в приложении Fmap/Server.

Далее в случае успеха выполняется отображение в память:

lpFileMap = MapViewOfFile(hFileMapping,

    FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);

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

Символы вводятся при помощи функции консольного ввода getche. Результат сохраняется в первом байте отображенной области памяти, откуда его будет брать для вывода приложение Fmap/Server:

chr = getche();

if(chr == 27)

   break;

*((LPSTR)lpFileMap) = chr;

После выполнения записи функция main устанавливает в отмеченное состояние объект-событие, предназначенное для работы с клавиатурой.

Если пользователь нажимает в окне приложения Fmap/Client клавишу <Esc>, имеющую код 27, цикл прерывается. Оба объекта-события переводятся в отмеченное состояние, после чего идентификаторы этих объектов освобождаются.

Перед завершением работы функция main отменяет отображение файла и освобождает идентификатор объекта-отображения.


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