Разработка программных дополнений по технологии «клиент — сервер». Метод коммуникации — отображение файла в память
Рисунок 2.2.1 — Схема алгоритма процедуры отправки сообщения серверу Проверка подключения клиента к серверу выполняется блоком 2 (рис. 2.2.1) и оператором 175 приложения Б. В случае отсутствия подключения пользователю выводится сообщение о необходимости установления подключения (блок 3, рис. 2.2.1 и операторы 183−185 приложения Б). В случае установленного подключения выполняется очистка буфера… Читать ещё >
Разработка программных дополнений по технологии «клиент — сервер». Метод коммуникации — отображение файла в память (реферат, курсовая, диплом, контрольная)
Кафедра компьютерной инженирии Курсовая работа По системному программному обеспечению на тему:
" Разработка программных дополнений по технологии «клиент — сервер». Метод коммуникации — отображение файла в память"
Реферат
Пояснительная записка к курсовой работе содержит: ___ с., 9 рис., 3 табл., 2 приложения, 20 источников.
Цель работы: разработка приложений на платформе Win32 для исследования взаимодействия между процессами через отображение файла в память.
Объект разработки — программное обеспечение, в состав которого входят: программа, выполняющая функции сервера и две программы, выполняющие функции клиентов.
В курсовой работе применяются метод проектирования «сверху — вниз» и событийное программирование. Разработка программных приложений выполняется на платформе Win32 в среде Microsoft Visual Studio, с использованием для межпроцессного взаимодействия метода отображения файла в память.
Приложения архитектуры «клиент-сервер» применяются для организации обмена информацией между двумя объектами.
В результате разработки курсового проекта выполнено определение достоинств и недостатков архитектуры «клиент-сервер»; сделан обзор системных средств коммуникации и синхронизации процессов. Разработан менюориентированный пользовательский интерфейс. Выполнена отладка приложения.
WIN32 API, ОТОБРАЖЕНИЕ ФАЙЛА, ПАМЯТЬ, МЬЮТЕКС, БУФЕР, ПРОЦЕССЫ, СОБЫТИЯ, СИНХРОНИЗАЦИЯ ПРОЦЕССОВ, АЛГОРИТМ, ПРОГРАММА.
- Введение
- 1. Теоретическая часть
- Модель приложений «клиент-сервер»
- Метод отображения файла в память
- 2. Практическая часть
- Постановка задачи
- Описание алгоритма работы программы-клиента
- Описание алгоритма работы программы-сервера
- Результаты работы приложений
- Выводы
- Перечень ссылок
- Приложения
Приобретение навыков в написании приложений клиент-сервер очень актуально. Использование приложений архитектуры «клиент-сервер» является неотъемлемой частью программирования. Приложения такого типа обеспечивают простой обмен информацией между сервером и клиентом (клиентами). Причем сервер и клиент могут располагаться как на одном компьютере, так и на разных источниках.
Технология «клиент-сервер» является полезной в условиях необходимости обработки различных данных, предоставляемых многими приложениями, с помощью одного устройства [1; 3]. Данная технология основывается на том, что существует приложение-сервер, которое принимает информацию и определенное количество приложений-клиентов, которые получают, обрабатывают информацию и предоставляют ее серверу для дальнейшей обработки или реализации. [2]
Приложения технологии клиент-сервер имеют ряд преимуществ, среди которых можно выделить основные:
Отсутствие дублирования кода программы-сервера программами-клиентами.
Так как все вычисления выполняются на сервере, то требования к приложениям-клиентам снижаются.
Все данные хранятся на сервере, который, как правило, защищён гораздо лучше большинства клиентов. На сервере проще обеспечить контроль полномочий, чтобы разрешать доступ к данным только клиентам с соответствующими правами доступа.
Также данная технология имеет свои недостатки. В качестве основного недостатка можно выделить то, что неработоспособность сервера может сделать неработоспособной всю вычислительную сеть. Неработоспособным сервером следует считать сервер, производительности которого не хватает на обслуживание всех клиентов, а также сервер, находящийся на ремонте, профилактике и т. п. [10]
В соответствии с поставленным заданием, необходимо разработать программу-сервер и программу-клиента. Целью программы-сервера является реализация соединения с программой-клиентом, передача и прием сообщений от программы-клиента, и вывод их в рабочее окно. Целью программы-клиента является выполнение функций, которые позволяют обеспечить соединение с программой-сервером, подготовить необходимую информацию и передать ее программе-серверу.
В итоге выполнения данной курсовой работы должно быть выполнено: разработка и отладка приложения-сервера и двух приложений-клиентов; составление схем алгоритмов к основным модулям программы; анализ работы разработанных приложений; написание пояснительной записки к курсовой работе.
Цель выполнения данной курсовой работы — разработка программного обеспечения, в состав которого входят: программа, выполняющая функции сервера и две программы, выполняющие функции клиентов. Задачей клиентов является подготовка информации в соответствии с заданием и передача ее серверу. Задачей сервера является вывод этой информации в окне приложения.
клиент сервер программа приложение
1. Теоретическая часть
Модель приложений «клиент-сервер»
Процессы, участвующие в межпроцессном взаимодействии, могут быть разделены на клиентов и серверов.
Клиент (client) — процесс, который запрашивает системную службу от какого-либо другого процесса.
Сервер (server) — процесс, который отвечает на клиентский запрос. [12; 14]
Модель клиент-сервер — это взаимодействия между одновременно выполняемыми программными процессами. Клиентские процессы посылают запросы серверному процессу, посылающему обратно результаты этих запросов. Взаимодействие между клиентским и серверным процессами представляет собой совместный транзакционный обмен, в котором активность исходит от клиента, а сервер реагирует на эту активность.
Под приложением клиент-сервер понимается любое приложение, в котором инициатор действия находится в одной системе, а исполнитель действия — в другой. Кроме того, в большинстве приложений клиент-сервер один сервер обслуживает запросы нескольких клиентов. Взаимодействие клиента и сервера обеспечивается коммуникационным программным обеспечением. Примерами такого программного обеспечения являются набор протоколов TCP/IP, — протоколы OSI.
Таблица 1. 1.1 — Достоинства и недостатки архитектуры клиент-сервер
Системная характеристика | Значение | |
Достоинства | ||
Сеть небольших мощных машин | Если одна машина выйдет из строя, компания все равно сможет продолжать работу | |
Мощные объединения компьютеров | Система предоставляет мощность, позволяющую выполнять работу без монополизации ресурсов. У конечных пользователей достаточно мощностей для локальной работы | |
Некоторые рабочие станции столь же мощны, как мэйнфреймы, но их стоимость на порядок ниже | Предоставляя вычислительные мощности за меньшие деньги, система позволяет тратить сэкономленные средства на другие приобретения или на увеличение доходов | |
Открытые системы | Аппаратуру, программы и услуги можно приобретать у разных поставщиков | |
Легкость наращивания системы | Систему нетрудно модернизировать, как только потребности изменятся | |
Индивидуальная рабочая среда клиента | Можно объединять компьютерные платформы, подбирая их под конкретные нужды подразделений и пользователей | |
Недостатки | ||
Слабая поддержка | Отдельные части системы не всегда корректно работают вместе. Бывает трудно найти причину неисправности | |
Недостаток инструментальных средств обслуживания | При использовании архитектуры клиент-сервер приходится искать инструментальные средства на рынке или разрабатывать их самостоятельно | |
Необходимость переобучения | Философия программирования для Маc или Windows отличается от философии программирования на языке COBOL | |
Метод отображения файла в память
Механизмы использования межпроцессного взаимодействия (IPC), которые поддерживаются Windows:
буфер обмена;
модель компонентных объектов (com);
копирование данных (data copy);
динамический обмен данными (dde);
отображение (проекция) файла в память;
почтовые слоты (mailslots);
каналы (pipes);
вызов удаленной процедуры (rpc);
сокеты windows (windows sockets);
Использование отображения файла в памяти (разделяемая память).
Система виртуальной памяти в Win32 использует файл подкачки pagefile. sys и может преобразовывать страницы оперативной памяти в страницы файла на диске и наоборот. Система может проецировать на оперативную память не только файл размещения, но и любой другой файл. Это может использоваться для совместного использования памяти несколькими процессами. Механизм отображения файлов может быть использован процессами, работающими только на локальном компьютере; он не используется для передачи данных по сети.
Функция CreateFileMapping создает именованный или неименованный объект-отображение файла:
HANDLE CreateFileMapping (
HANDLE hFile, // дескриптор файла для отображения
LPSECURITY_ATTRIBUTES lpAttributes, // атрибуты безопасности
DWORD flProtect, // флаги защиты
DWORD dwMaximumSizeHigh, // старшие DWORD максимального размера
DWORD dwMaximumSizeLow, // младшие DWORD максимального размера
LPCTSTR lpName // имя объекта-отображения файла
);
Рисунок 0.2. 1 — Схема использования разделяемой памяти
Отображение создается в приложении-сервере:
hMapFile = CreateFileMapping (
INVALID_HANDLE_VALUE, // использование файла подкачки
NULL, // защита по умолчанию
PAGE_READWRITE, // доступ к чтению/записи
0, // макс. размер объекта
1024, // размер буфера
" myFileMapping"); // имя отраженного в памяти объекта
lpD = (D*) MapViewOfFile (hMapFile, // дескриптор отраженного объекта
FILE_MAP_ALL_ACCESS, // разрешение чтения/записи
0, // старший DWORD смещения
0, // младший DWORD смещения
1024); // количество байт для сопоставления
Процесс-клиент вызывает функцию OpenFileMapping с именем «myFileMapping», чтобы использовать тот же объект-отображение файла, что и процесс-сервер. Функция MapViewOfFile используется для сопоставления области памяти процесса отображаемому файлу. [7]
hMapFile = OpenFileMapping (
FILE_MAP_ALL_ACCESS, // доступ к чтению/записи
FALSE, // имя не наследуется
" myFileMapping"); // имя «проецируемого «объекта
lpD= (D*) MapViewOfFile (hMapFile, // дескриптор отраженного в памяти объекта
FILE_MAP_ALL_ACCESS, // разрешение чтения/записи
0, // старший DWORD смещения
0, // младший DWORD смещения
1024); // количество байт для сопоставления
2. Практическая часть
Постановка задачи
Задачей данной курсовой работы является разработка приложения по технологии «клиент-сервер». Метод коммуникации между процессами, который необходимо использовать при выполнении работы — отображение файла в память. [17]
В состав программного обеспечения, разработанного в соответствии с заданием, должны входить:
программа, выполняющая функции сервера;
две программы, выполняющие функции клиентов.
Программа-сервер должна выполнять следующие функции:
а) создание отображения на страницу подкачки системы;
б) получение данных от приложений-клиентов;
в) вывод на экран полученных данных.
Программа-клиент 1 должна выполнять следующие функции:
а) открыть отображение файла;
б) подготовить и передать серверу такие данные: ширину полосы меню, наличие мыши в системе.
Программа-клиент 2 должна выполнять следующие функции:
а) открыть отображение файла
б) подготовить и передать серверу такие данные: ширина и высота иконки приложения, ширина и высота вертикальной полосы прокрутки.
Описание алгоритма работы программы-клиента
В результате выполнения курсовой работы было разработано приложение-сервер и два приложения-клиента.
В составе приложений-клиентов можно выделить следующие процедуры:
· Процедура отправки сообщения серверу,
· Процедуры подготовки клиентами информации в соответствии с заданием,
· Процедура подключения к серверу,
· Оконная процедура программы-клиента.
Описание переменных, которые используются в программе, дано в таблице 2.2.1:
Таблица 2.2.1 — Описание переменных программы-клиента
Исходный текст | Описание | |
char szBuf [512]; | Буфер для обмена информацией | |
DWORD cbWritten; | Количество байтов, записанных в буфер | |
static HWND hwndEdit; | Дескриптор поля редактирования | |
TCHAR mess [2048]; | Буфер формирования сообщений на экран | |
TCHAR* m_mess = mess; | Ссылка на буфер | |
TCHAR Buf [1024]; | Буфер для данных | |
struct D | Структура для буфера | |
HANDLE hServerMutex | Дескриптор мьютекса на доступ к буферу памяти | |
HANDLE hMapFile | Дескриптор отображения файла | |
HANDLE hEventVvod | Дескриптор события «Данные готовы» | |
TCHAR szWindowClass [MAX_LOADSTRING] | Имя класса главного окна | |
HINSTANCE hInst | Текущий экземпляр | |
LPCSTR nameMutex | Имя мьютекса для отображения | |
LPTSTR nameEvent | Имя события для отображения | |
bool Podkluchen | Переменная для проверки статуса подключения клиента к серверу | |
int menuW | Переменная для размеров полосы меню | |
bool fMouse | Переменная для определения наличия мыши в системе | |
int scr | Переменная для размеров кнопки полосы прокрутки | |
Процедура отправки сообщения серверу — содержит инструкции, которые позволяют организовать передачу приложением-клиентом подготовленной информации приложению-серверу. Схема алгоритма работы процедуры представлена на рисунке 2.2.1:
Рисунок 2.2.1 — Схема алгоритма процедуры отправки сообщения серверу Проверка подключения клиента к серверу выполняется блоком 2 (рис. 2.2.1) и оператором 175 приложения Б. В случае отсутствия подключения пользователю выводится сообщение о необходимости установления подключения (блок 3, рис. 2.2.1 и операторы 183−185 приложения Б). В случае установленного подключения выполняется очистка буфера (блок 4, рис. 2.2.1), вызов рабочей функции function_kl (блок 5, рис. 2.2.1) и пересылка сообщения (блоки 6−8, рис. 2.2.1). Эти действия реализованы операторами 176−182 приложения Б.
Функции для подготовки клиентами информации в соответствии с заданием — содержат инструкции для подготовки необходимой информации и имеют похожую структуру. Схема алгоритма функции клиента № 1 приведена на рисунке 2.2.2, клиента № 2 — на рисунке 2.2.3.
Рисунок 2.2.2 — Схема алгоритма функции function_kl программы-клиента № 1
В начале функций выполняется определение длины текста в поле редактирования окна приложения-клиента (блок 2, рис. 2.2.2 и рис. 2.2.3). С помощью функции SendMessage подготовленное сообщение пересылается в буфер szBuf (блок 3, рис. 2.2.2 и рис. 2.2.3). После символов в конец строки добавляется нулевой код — признак конца строки. С помощью функции sprintf содержимое буфера передается в символьный массив. Эти действия реализованы операторами 28−33 приложения Б для программы-клиента 1 и операторами 227−232 приложения Б для программы-клиента 2.
Далее в клиенте № 1 вызывается функция GetSystemMetrics для получения ширины полосы меню (блок 4, рис. 2.2.2 и оператор 34 приложения Б). Затем формируется сообщение с полученным значением (блок 5, рис. 2.2.2 и оператор 35 приложения Б). Следующим пунктом выполняется проверка на наличие мыши в системе (блоки 6−7, рис. 2.2.2 и операторы 36−37 приложения Б) и формируется соответствующее сообщение (блок 8 или 9, рис. 2.2.2 и операторы 38−40 приложения Б).
Рисунок 2.2.3 — Схема алгоритма функции function_kl программы-клиента № 2
В клиенте № 2 вызывается функция GetSystemMetrics для получения ширины и высоты кнопки вертикальной полосы прокрутки (блок 4, рис. 2.2.3 и операторы 233−236 приложения Б). Затем формируется сообщение с полученными значениями (блок 5, рис. 2.2.3 и операторы 237−238 приложения Б). Следующим пунктом выполняется определение размеров иконки приложения (блок 6, рис. 2.2.3 и операторы 239−242 приложения Б) и формируется соответствующее сообщение (блок 7, рис. 2.2.3 и оператор 243 приложения Б).
Процедура подключения приложения-клиента к приложению-серверу - схема алгоритма представлена на рисунке 2.2.4 В начале блоком 2 (рис. 2.2.4) выполняется проверка установленного подключения (оператор 144 приложения Б). Если подключение не было установлено ранее, производится выполнение следующих функций:
· открытие проекции файла (блок 3, рис. 2.2.4 и операторы 145−148 приложения Б);
· представление проецированного файла (блок 6, рис. 2.2.4 и операторы 157−159 приложения Б);
· создание мьютекса (блок 9, рис. 2.2.4 и оператор 167 приложения Б);
· открытие события с автосбросом, со сброшенным начальным состоянием (блок 13, рис. 2.2.4 и оператор 171 приложения Б).
Оконная процедура программы-клиента — схема алгоритма представлена на рисунке 2.2.5 В начале выполняется анализ кода сообщения (блок 2, рис. 2.2.5 и оператор 127 приложения Б). В зависимости от кода выполняются инструкции, отображенные блоками 3, 7 или 10 (рис. 2.2.5).
При обработке сообщения WM_DESTROY (блок 3) о закрытии окна приложения-клиента особенностью является то, что предварительно необходимо освободить мьютекс, отменить отображение представления файла и закрыть отображение (блоки 3−6, рис. 2.2.5 и операторы 199−204 приложения Б).
При обработке сообщения WM_CREATE (блок 10) выполняется создание окна приложения-клиента с полем ввода, редактирования и отображения текста (операторы 128−134 приложения Б).
При получении сообщения WM_COMMAND (блок 7) о поступлении команды выполняется ее декодирование и организовывается переключатель для выбора процедуры обработки в зависимости от кода команды (блоки 8 или 9, рис. 2.2.5 и операторы 143−186 приложения Б). Процедура с кодом ID_32 771 соответствует процедуре подключения клиента к серверу (рис. 2.2.4), а процедура с кодом ID_32 772 — процедуре отправки сообщения серверу (рис. 2.2.1).
Рисунок 2.2.4 — Схема алгоритма процедуры подключения клиента к серверу Рисунок 2.2.5 — Схема алгоритма оконной процедуры программы-клиента
Описание алгоритма работы программы-сервера
В реализации программы-сервера в качестве основной можно выделить оконную процедуру. Ее схема алгоритма представлена на рисунке 2.3.1 Описание переменных, которые используются в программе, приведено в таблице 2.3.1:
Таблица 2.3.1 — Описание переменных и констант программы-сервера
Исходный текст | Описание | |
TCHAR Buf [1024]; | Буфер для данных | |
static HWND hwndEdit; | Дескриптор поля редактирования текста | |
#define MAX_LOADSTRING 100 | Строка заголовка | |
#define BUF_SIZE 1024 | Размерность буфера | |
struct D | Структура для буфера | |
HANDLE hThreads [2] | Дескриптор потока | |
HANDLE hMapFile | Дескриптор отображения файла | |
HANDLE hEventVvod | Дескриптор события «Данные готовы» | |
TCHAR szWindowClass [MAX_LOADSTRING] | Имя класса главного окна | |
HINSTANCE hInst | Текущий экземпляр | |
Оконная процедура программы-сервера. В начале выполняется анализ кода сообщения (блок 2, рис. 2.3.1 и оператор 120 приложения А). В зависимости от кода выполняются инструкции, отображенные блоками 3 или 4 (рис. 2.3.1).
При обработке сообщения WM_DESTROY (блок 4) о закрытии окна приложения-сервера особенностью является то, что предварительно необходимо завершить выполнение потока, отменить отображение представления файла и закрыть отображение (блоки 4−7, рис. 2.3.1 и операторы 175−180 приложения А).
При обработке сообщения WM_CREATE в начале блоком 3 выполняется создание отображение объекта (операторы 122−128 приложения А). Далее выполняется представление проецированного файла (блок 11, рис. 2.3.1 и операторы 135−137 приложения А). Затем блоком 14 (рис. 2.3.1) выполняется создание мьютекса (реализовано операторами 144−145 приложения А). С помощью блока 18 (рис. 2.3.1) выполняется создание окна приложения-сервера с полем ввода, редактирования и отображения текста (операторы 148−151 приложения А). Задаются необходимые параметры размеров и расположения на экране окна приложения-сервера. Далее блоком 19 (рис. 2.3.1) выполняется создание потока для получения сообщения от приложения-клиента (оператор 153 приложения А).
Рисунок 2.3.1 — Схема алгоритма оконной процедуры программы-сервера Для отладки программ необходимо размещать и серверную, и клиентскую программы на одном локальном компьютере. Это объясняется тем, что используемый метод отображения файла в память применяется на одном локальном компьютере.
Результаты работы приложений
Разработка и отладка программы выполнялась в среде Microsoft Visual Studio. В итоге было разработано одно приложение-сервер и два приложения клиента, которые были проверены на практике и выполняют необходимые требования. В результате выполнения программы от клиентов 1 и 2 по выбору пользователя передаются данные серверу. Первый клиент передает данные о ширине полосы меню и о наличии мыши в системе. Второй клинт передеает данные о размерах кнопки полосы прокрутки и иконки приложения. Сервер получает данные в виде: «Клиент #1. Сообщение» и «Клиент #2. Сообщение». Также реализована возможность ввода информации в поле клиентов и отправка ее серверу вместе с данными. Изображения окон работающих приложений приведены на рисунках 2.4.1 и 2.4.2:
Рис. 2.4.1 — Окна приложений сервера и клиента № 1
Рис. 2.4.2 — Окна приложений сервера и клиента № 2
Выводы
Целью данной курсовой работы была разработка приложений архитектуры «клиент-сервер». Разработанные приложения включают: приложение, выполняющее функции сервера и два приложения, которые выполняют функции клиентов.
Архитектура «клиент-сервер» позволяет реализовать обмен информации между двумя устройствами: сервером и клиентом. Согласно данной технологии, клиент запрашивает у сервера некоторые услуги, предоставляя определенные исходные данные и параметры с помощью одного из методов коммуникации между потоками, а сервер обслуживает запрос. Метод коммуникации между процессами, использованный в данной работе, — отображение файла в память.
В результате выполнения данной курсовой работы было разработано три приложения: два приложения-клиента, которые получают необходимую информацию о характеристиках системы и приложение-сервер, которому полученная информация передается для последующего ее вывода на экран. Были выполнены требования, представленные к разрабатываемым приложениям.
По окончанию выполнения работы, разработанные приложения были проверены на практике и полностью подтвердили свою работоспособность. Были проведены необходимые исследования и составлены схемы алгоритмов к основным модулям приложений.
Можно сделать вывод, что поставленная задача была достигнута, задание на курсовой проект было выполнено.
Перечень ссылок
1. Гордеев А. В., Молчанов А. Ю. Системное программное обеспечение: Учебник для вузов — СПб: Питер, 2003. — 736 с. — С.389.
2. Дейтел Х. М., Дейтел П. Дж., Чофнес Д. Р. Операционные системы. Основы и принципы: Третье издание. Пер. с англ. — М.: ООО «Бином-Пресс», 2006. — 1024 с. — С.768.
3. Демройк М. Ю. Начала программирования. Распределенные системы, безопасность схем программирования. — М.: ООО «Бином-Пресс», 2009. — 704 с. — С.143.
4. Джонсон М. Системное программирование в среде Win32, 2-е изд.: Пер. с англ. — M.: Издательский дом «Вильямс», 2001. — 464 с. — С.346.
5. Документация Win32 API (MSDN).
6. Питер Блюм, LabVIEW. Стиль программирования, М: «ДМК Пресс», 2008.
7. Рихтер Дж. Windows для профессионалов: создание эффективных Win32 приложений с учетом специфики 64-разрядной версии Windows, 4-е изд.: Пер, англ — СПб: Питер; М.: Издательско-торговый дом «Русская Редакция», 2001. — 752 с. — С.578.
8. Страуструп Б. Язык программирования С++. Специальное издание. Пер. с англ. — М.: ООО «И.Д. Вильямс», 2007. — 1104 с.
9. Суранов А. Я., LabVIEW 8.20., Справочник по функциям, М: «ДМК Пресс», 2007.
10. Таненбаум Э. Современные операционные системы, 2-е изд.: Пер. с англ. — СПб: Питер, 2003. — 1040 с. — С.552.
11. Таненбаум Э. Современные операционные системы, 2-е изд.: Пер. с англ. — СПб: Питер, 2003. — 1040 с.
12. Трахтенгерц Э. А. Программное обеспечение параллельных процессов. — М.: Наука, 2003. — 272 с. — С.84.
13. Трэвис Дж., Кринг Дж., LabVIEW для всех, М: «ДМК Пресс», 2008.
14. Щербаков Є.В., Щербакова М. Є. Мовні засоби системного програмування: навчальний посібник. — Луганськ: Вид-во СНУ ім.В. Даля, 2006. — 376 с.
15. Щербаков Є.В., Щербакова М. Є., Скарга-Бандурова І.С. Діалогові засоби системного програмування: навчальний посібник. — Луганськ: Вид-во СНУ ім.В. Даля, 2010. — 408 с.
16. Эндрюс Грегори Р. Основы многопоточного, параллельного и распределенного программирования. / Пер. с англ. К.: Диалектика, 2008. — 512 с. — С.153.
17. Методические указания к курсовой работе по дисциплине «Системное программное обеспечение — 42 с.
18. http://loi. sscc.ru/gis/oop/win32api/win32.html
19. http://msdn. microsoft.com/ru-ru/library/bb384843. aspx
20. http://w32api. narod.ru/functions/GetSystemMetrics.html
Приложения
Приложение А
Распечатка программы-сервера
// MapServer. cpp: определяет точку входа для приложения.
#include «stdafx. h»
#include «MapServer. h»
#include
#include
#include
#include
#define MAX_LOADSTRING 100
#define BUF_SIZE 1024
LPCSTR nameMutex = «Global\MapMutex» ;
LPTSTR nameEvent = «Global\MapEvent» ;
HANDLE hServerMutex; // дескриптор мьютекса на доступ к буферу памяти
HANDLE hEventVvod;
unsigned uThreadIDs [2];
HANDLE hThreads [2];
BOOL Working=true;
HANDLE hMapFile;
static HWND hwndEdit;
struct D{
TCHAR Buf [1024];
};
D* lpD;
// Глобальные переменные:
HINSTANCE hInst; // текущий экземпляр
TCHAR szTitle [MAX_LOADSTRING]; // Текст строки заголовка
TCHAR szWindowClass [MAX_LOADSTRING]; // имя класса главного окна
// Отправить объявления функций, включенных в этот модуль кода:
ATOMMyRegisterClass (HINSTANCE hInstance);
BOOLInitInstance (HINSTANCE, int);
LRESULT CALLBACKWndProc (HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACKAbout (HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{UNREFERENCED_PARAMETER (hPrevInstance);
UNREFERENCED_PARAMETER (lpCmdLine);
// TODO: разместите код здесь.
MSG msg;
HACCEL hAccelTable;
// Инициализация глобальных строк
LoadString (hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString (hInstance, IDC_MAPSERVER, szWindowClass, MAX_LOADSTRING);
MyRegisterClass (hInstance);
// Выполнить инициализацию приложения:
if (! InitInstance (hInstance, nCmdShow))
{return FALSE;
}
hAccelTable = LoadAccelerators (hInstance, MAKEINTRESOURCE (IDC_MAPSERVER));
// Цикл основного сообщения:
while (GetMessage (&msg, NULL, 0, 0))
{if (! TranslateAccelerator (msg. hwnd, hAccelTable, &msg))
{TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
return (int) msg. wParam;
}
// ФУНКЦИЯ: MyRegisterClass ()
// НАЗНАЧЕНИЕ: регистрирует класс окна.
// КОММЕНТАРИИ:
// Эта функция необходима в случае, если нужно, чтобы данный код
// был совместим с системами Win32, не имеющими функции RegisterClassEx'
// которая была добавлена в Windows 95. Вызов этой функции важен для того,
// чтобы приложение получило «качественные» значки и установило связь с ними.
ATOM MyRegisterClass (HINSTANCE hInstance)
WNDCLASSEX wcex;
wcex. cbSize = sizeof (WNDCLASSEX);
wcex. style= CS_HREDRAW
// ФУНКЦИЯ: InitInstance (HINSTANCE, int)
// НАЗНАЧЕНИЕ: сохраняет обработку экземпляра и создает главное окно.
// КОММЕНТАРИИ:
// В данной функции дескриптор экземпляра сохраняется в глобальной переменной, а также создается и выводится на экран главное окно программы.
BOOL InitInstance (HINSTANCE hInstance, int nCmdShow)
{ HWND hWnd;
hInst = hInstance; // Сохранить дескриптор экземпляра в глобальной переменной
hWnd = CreateWindow (szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (! hWnd)
{ return FALSE;
}
ShowWindow (hWnd, nCmdShow);
UpdateWindow (hWnd);
return TRUE;
}
unsigned __stdcall VvodThreadFunc (void * arg) // Поток ожидания данных от клиентов
{while (Working)
{WaitForSingleObject (hEventVvod, INFINITE); // Ждем своего события
WaitForSingleObject (hServerMutex, INFINITE); // Ждем доступа к памяти
// данные готовы, вывод на экран
SendMessage (hwndEdit, WM_SETTEXT, 0, (LPARAM) lpD->Buf);
ReleaseMutex (hServerMutex); // Разрешаем записывать в общую память
}
_endthreadex (0);
return 0;
};
// ФУНКЦИЯ: WndProc (HWND, UINT, WPARAM, LPARAM)
// НАЗНАЧЕНИЕ: обрабатывает сообщения в главном окне.
// WM_COMMAND — обработка меню приложения
// WM_PAINT-Закрасить главное окно
// WM_DESTROY — ввести сообщение о выходе и вернуться.
LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR ss [80];
switch (message)
{case WM_CREATE:
hMapFile = CreateFileMapping (
INVALID_HANDLE_VALUE, // использование файла подкачки
NULL, // защита по умолчанию
PAGE_READWRITE, // доступ к чтению/записи
0, // макс. размер объекта
BUF_SIZE, // размер буфера
" myFileMapping"); // имя отраженного в памяти объекта
if (hMapFile == NULL || hMapFile == INVALID_HANDLE_VALUE)
{ MessageBox (hWnd,
" Не может создать отраженный в памяти объект (%d). n" ,
" Map", MB_OK);
return 0;
}
lpD= (D*) MapViewOfFile (hMapFile, // дескриптор отраж. в памяти объекта
FILE_MAP_ALL_ACCESS, // разрешение чтения/записи
0, 0, BUF_SIZE);
if (lpD == NULL)
{ MessageBox (hWnd,
" Представление проецированного файла не возможно (%d). n" ,
" Map", MB_OK);
return 0;
}
hServerMutex = CreateMutexA (NULL, true, nameMutex);
if (hServerMutex == NULL) MessageBox (hWnd, «Error mutex», «Map», MB_OK);
// Создаем событиe с автосбросом, со сброшенным начальным состоянием
hEventVvod = CreateEvent (NULL, FALSE, TRUE, nameEvent);
hwndEdit = CreateWindow (TEXT («EDIT»), NULL,
WS_CHILD | WS_VISIBLE | WS_VSCROLL |
ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL,
10, 40, 500, 400, hWnd, NULL, hInst, NULL);
// Создаем поток
hThreads = (HANDLE) _beginthreadex (NULL, 0,&VvodThreadFunc, 0,0,&uThreadIDs [0]);
ReleaseMutex (hServerMutex);
break;
case WM_COMMAND:
wmId = LOWORD (wParam);
wmEvent = HIWORD (wParam);
switch (wmId)
{case IDM_ABOUT:
DialogBox (hInst, MAKEINTRESOURCE (IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow (hWnd);
break;
default:
return DefWindowProc (hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint (hWnd, &ps);
// TODO: Add any drawing code here.
EndPaint (hWnd, &ps);
break;
case WM_DESTROY:
CloseHandle (hThreads [0]);
UnmapViewOfFile (lpD);
CloseHandle (hMapFile);
PostQuitMessage (0);
break;
default:
return DefWindowProc (hWnd, message, wParam, lParam);
}
return 0;
}
// Обработчик сообщений для окна «О программе» .
INT_PTR CALLBACK About (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{UNREFERENCED_PARAMETER (lParam);
switch (message)
{case WM_INITDIALOG:
return (INT_PTR) TRUE;
case WM_COMMAND:
if (LOWORD (wParam) == IDOK || LOWORD (wParam) == IDCANCEL)
{EndDialog (hDlg, LOWORD (wParam));
return (INT_PTR) TRUE;
}
break;
}
return (INT_PTR) FALSE;
}
Приложение Б
Распечатка программы-клиента № 1
// client1. cpp: определяет точку входа для приложения.
#include «stdafx. h»
#include «client1. h»
#include
#define MAX_LOADSTRING 100
#define BUF_SIZE 1024
// Глобальные переменные:
HINSTANCE hInst; // текущий экземпляр
TCHAR szTitle [MAX_LOADSTRING]; // Текст строки заголовка
TCHAR szWindowClass [MAX_LOADSTRING]; // имя класса главного окна
LPCSTR nameMutex = «Global\MapMutex» ;
LPTSTR nameEvent = «Global\MapEvent» ;
HANDLE hServerMutex; // дескриптор мьютекса на доступ к буферу памяти
HANDLE hEventVvod; // дескриптор события «Данные готовы»
HANDLE hMapFile;
char szBuf [512];
struct D{
char Buf [1024];
};
D* lpD;
bool Podkluchen=false;
TCHAR mess [2048];
TCHAR* m_mess = mess;
static HWND hwndEdit;
int menuW;
bool fMouse;
void function_kl (HWND hWnd)
{ // Определение длины текста в поле редактирования
DWORD cbWritten = SendMessage (hwndEdit, WM_GETTEXTLENGTH, 0,0);
SendMessage (hwndEdit, WM_GETTEXT, (WPARAM) cbWritten, (LPARAM) szBuf);
// Отсылаем введенную строку на сервер
sprintf (m_mess, szBuf, strlen (szBuf) + 1,&cbWritten, m_mess);
sprintf (m_mess, «%snrn», m_mess);
menuW=GetSystemMetrics (SM_CYMENU); // ширина полосы меню в пикселях
sprintf (m_mess, «%snШирина полосы меню: %d pxrn», m_mess, menuW);
fMouse = GetSystemMetrics (SM_MOUSEPRESENT); // наличие мыши в системе
if (fMouse)
sprintf (m_mess, «%sМышь присутствует в системе. rn», m_mess);
else
sprintf (m_mess, «%sМышь отсутствует в системе. rn», m_mess);
return;
}
// Отправить объявления функций, включенных в этот модуль кода:
ATOMMyRegisterClass (HINSTANCE hInstance);
BOOLInitInstance (HINSTANCE, int);
LRESULT CALLBACKWndProc (HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACKAbout (HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{UNREFERENCED_PARAMETER (hPrevInstance);
UNREFERENCED_PARAMETER (lpCmdLine);
// TODO: разместите код здесь.
MSG msg;
HACCEL hAccelTable;
// Инициализация глобальных строк
LoadString (hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString (hInstance, IDC_CLIENT1, szWindowClass, MAX_LOADSTRING);
MyRegisterClass (hInstance);
// Выполнить инициализацию приложения:
if (! InitInstance (hInstance, nCmdShow))
{return FALSE;
}
hAccelTable = LoadAccelerators (hInstance, MAKEINTRESOURCE (IDC_CLIENT1));
// Цикл основного сообщения:
while (GetMessage (&msg, NULL, 0, 0))
{if (! TranslateAccelerator (msg. hwnd, hAccelTable, &msg))
{TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
return (int) msg. wParam;
}
// ФУНКЦИЯ: MyRegisterClass ()
// НАЗНАЧЕНИЕ: регистрирует класс окна.
// КОММЕНТАРИИ:
// Эта функция необходима только в случае, если нужно, чтобы данный
// код был совместим с системами Win32, не имеющими функции RegisterClassEx'
// которая была добавлена в Windows 95. Вызов этой функции важен для того,
// чтобы приложение получило «качественные» значки и установило связь с ними.
ATOM MyRegisterClass (HINSTANCE hInstance)
WNDCLASSEX wcex;
wcex. cbSize = sizeof (WNDCLASSEX);
wcex. style= CS_HREDRAW
// ФУНКЦИЯ: InitInstance (HINSTANCE, int)
// НАЗНАЧЕНИЕ: сохраняет обработку экземпляра и создает главное окно.
// КОММЕНТАРИИ:
// В данной функции дескриптор экземпляра сохраняется в глобальной переменной,
// а также создается и выводится на экран главное окно программы.
BOOL InitInstance (HINSTANCE hInstance, int nCmdShow)
{ HWND hWnd;
hInst = hInstance; // Сохранить дескриптор экземпляра в глобальной переменной
hWnd = CreateWindow (szWindowClass, // szTitle,
" Клиент № 1″, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, 400, 250, NULL, NULL, hInstance, NULL);
if (! hWnd)
{ return FALSE;
}
ShowWindow (hWnd, nCmdShow);
UpdateWindow (hWnd);
return TRUE;
}
// ФУНКЦИЯ: WndProc (HWND, UINT, WPARAM, LPARAM)
// НАЗНАЧЕНИЕ: обрабатывает сообщения в главном окне.
// WM_COMMAND — обработка меню приложения
// WM_PAINT-Закрасить главное окно
// WM_DESTROY — ввести сообщение о выходе и вернуться.
LRESULT CALLBACK WndProc (HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
int j;
switch (message)
{case WM_CREATE:
hwndEdit = CreateWindow (// Создаем доч. окно для вывода данных от процессов
TEXT («EDIT»), TEXT («Клиент #1. Сообщение: rn»),
WS_CHILD | WS_VISIBLE | WS_VSCROLL |
ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL,
20, 10, 400, 200, hWnd, NULL, hInst, NULL);
break;
case WM_COMMAND:
wmId = LOWORD (wParam);
wmEvent = HIWORD (wParam);
// Parse the menu selections:
switch (wmId)
{case IDM_ABOUT:
DialogBox (hInst, MAKEINTRESOURCE (IDD_ABOUTBOX), hWnd, About);
break;
case ID_32 771: // пункт меню «Подключиться»
if (Podkluchen) return 0;
hMapFile = OpenFileMapping (
FILE_MAP_ALL_ACCESS, // доступ к чтению/записи
FALSE, // имя не наследуется
" myFileMapping"); // имя «проецируемого «объекта
if (hMapFile == NULL)
{
MessageBox (hWnd,
" Невозможно открыть объект проекция файла" ,
" Клиент", MB_OK);
Podkluchen=false;
return 0;
}
lpD= (D*) MapViewOfFile (hMapFile, // дескриптор «проец.» объекта
FILE_MAP_ALL_ACCESS, // разрешение чтения/записи
0, 0, BUF_SIZE);
if (lpD == NULL)
{ MessageBox (hWnd,
" Представление проецированного файла невозможно (%d). n" ,
" Клиент", MB_OK);
Podkluchen=false;
return 0;
}
hServerMutex = CreateMutexA (NULL, true, nameMutex);
if (hServerMutex == NULL) MessageBox (hWnd, «Error mutex» ,
" Map", MB_OK);
// Откр. событиe с автосбросом, со сброшенным начальным состоянием
hEventVvod = OpenEvent (EVENT_ALL_ACCESS, FALSE, nameEvent);
Podkluchen=true;
break;
case ID_32 772: // пункт меню «послать сообщение»
if (Podkluchen)
{FillMemory (lpD->Buf, 1024,0); // очистка буфера
Function_kl (hWnd);
for (int j=0; j
lpD->Buf [j] =m_mess [j];
SetEvent (hEventVvod);
ReleaseMutex (hServerMutex);
}
else
MessageBox (hWnd,
" Надо подключиться к серверуn", «Клиент1», MB_OK);
break;
case IDM_EXIT:
DestroyWindow (hWnd);
break;
default:
return DefWindowProc (hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint (hWnd, &ps);
// TODO: Add any drawing code here.
EndPaint (hWnd, &ps);
break;
case WM_DESTROY:
UnmapViewOfFile (lpD);
CloseHandle (hMapFile);
ReleaseMutex (hServerMutex);
PostQuitMessage (0);
break;
default:
return DefWindowProc (hWnd, message, wParam, lParam);
}
return 0;
}
// Обработчик сообщений для окна «О программе» .
INT_PTR CALLBACK About (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{UNREFERENCED_PARAMETER (lParam);
switch (message)
{case WM_INITDIALOG:
return (INT_PTR) TRUE;
case WM_COMMAND:
if (LOWORD (wParam) == IDOK || LOWORD (wParam) == IDCANCEL)
{EndDialog (hDlg, LOWORD (wParam));
return (INT_PTR) TRUE;
}
break;
}
return (INT_PTR) FALSE;
}
Распечатка функции function_kl программы-клиента № 2
void function_kl (HWND hWnd)
{
// Определение длины текста в поле редактирования
DWORD cbWritten = SendMessage (hwndEdit, WM_GETTEXTLENGTH, 0,0);
SendMessage (hwndEdit, WM_GETTEXT, (WPARAM) cbWritten, (LPARAM) szBuf);
// Отсылаем введенную строку на сервер
sprintf (m_mess, szBuf, strlen (szBuf) + 1,&cbWritten, m_mess);
sprintf (m_mess, «%snrn», m_mess);
scr=GetSystemMetrics (SM_CXVSCROLL);
int a=scr;
scr=GetSystemMetrics (SM_CYVSCROLL);
int b=scr;
sprintf (m_mess, «%sШирина и высота кнопки полосы прокрутки: %d x %d
pxrn", m_mess, a, b);
menuW=GetSystemMetrics (SM_CXICON);
a=menuW;
menuW=GetSystemMetrics (SM_CYICON);
b=menuW;
sprintf (m_mess, «%sШирина и высота иконки приложения: %d x %d pxrn», m_mess, a, b);
return;
}