Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
сис прог печать.doc
Скачиваний:
22
Добавлен:
11.12.2018
Размер:
329.22 Кб
Скачать

МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ УКРАИНЫ

ДОНБАССКАЯ ГОСУДАРСТВЕННАЯ

МАШИНОСТРОИТЕЛЬНАЯ АКАДЕМИЯ

Кафедра кит контрольная работа по дисциплине "Системное программирование"

Выполнил: Проверил:

ст. гр. ИТ-08-1зт доцент каф. ИСПР

Шатохин Я.А. Сагайда П.И.

Оценка

Дата

Роспись

Краматорск 2011 Задание №1

Цель: Приобрести навыки создания клиентских и пользовательских приложений, осуществляющих обмен большими объемами данных с помощью посылки и обработки сообщения WM_COPYDATA; регистрации и обработка пользовательских сообщений.

Индивидуальное задание: реализовать обмен данными о результатах вызова функций Windows API между двумя приложениями используя функции GetCurrentDirectory, SystemTimeToFileTime

Решение

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

DWORD GetCurrentDirectory(DWORD nBufferLength, char* lpBuffer);

Возвращает текущий каталог. Обычно это каталог, в котором была запущена программа.

Параметры: nBufferLength - размер буфера для принимаемой строки

lpBuffer - принимый путь

Возвращаемое значение: В случе успеха строка содеражщая путь, в случае неуспеха 0. Получить дополнительную информацию об ошибке испольнения можно с помощью функции GetLastError.

SystemTimeToFileTime(CONST SYSTEMTIME *lpSystemTime, LPFILETIME lpFileTime);

Преобразует системное время во время файла.

Параметры:

lpSystemTime - указывает на структуру, которая содержит преобразуемое время. Член wDayOfWeek структуры типа SYSTEMTIME игнорируется.

lpFileTime - указывает на структуру типа FILETIME, которая получает преобразованное системное время.

Структура FILETIME определена следующим образом:

typedef struct _FILETIME

{

DWORD dwLowDateTime; // младшее слово

DWORD dwHighDateTime; // старшее слово

} FILETIME;

Структура SYSTEMTIME определена так:

typedef struct _SYSTEMTIME

{

WORD wYear; // год

WORD wMonth; // месяц (1 - январь, 2 - февраль, и т. д.)

WORD wDayOfWeek; // день недели (0 - воскресение, 1 - понедельник, и т. д.)

WORD wDay; // день месяца

WORD wHour; // часы

WORD wMinute; // минуты

WORD wSecond; // секунды

WORD wMilliseconds; // миллисекунды

} SYSTEMTIME;

Возвращаемое значение

В случае успешного завершения функция возвращает значение отличное от 0. Если функция потерпела неудачу, то возвращается 0. Windows 2000/XP: Чтобы получить дополнительную информацию об ошибке, используйте функцию GetLastError.

Описание программной части

Клиентская часть:

В данной части используется функция GetCurrentDirectory() которая возвращает директорию в которой находится файл серверной части. Алгоритм работы следующий: клиент посылает запрос серверу запрос с помощью функции SendMessage() в которую передается в качестве параметра хэндл принимающего приложения, обработчик сообщений( в нашем случае используется WM_COPYDATA и пользовательское сообщение WM_USERINTER, зарегистрированного с помощью функции RegisterWindowMessage()), и два параметра, первый хэндл клиента, а через второй передается структура COPYDATASTRUCT в которую упаковывается данные функции.

В этой структуре в поле dwData передается адрес функции:

  • Если dwData = 5 – выполнить преобразование GetCurrentDirectory()

В обработчике WM_COPYDATA когда серверная часть возвращает в обработчике происходит обработка сообщения от функции GetCurrentDirectory() если dwData = 10 и результат выводится на экран.

При вызове функции SystemTimeToFileTime() данные передаются таким же образом только в структуру упаковываются данные структуры SYSTEMTIME в которой хранится время. В поле dwData при передаче серверу записывается значение 20, а при возврате от сервера значение поля содержит значение 25 и структуру FILETIME, значение которой выводится на экран.

Серверная часть:

Сервер получает данные от клиентской части и в обработчике событий WM_COPYDATA или WM_USERINTER размещается код вызова функций и возвращает значение клиентскому приложению результат через соответсвующие структуры указанные выше. Результат работы сервера указаны в консоли серверной части в виде сообщений.

Код сервера:

__fastcall TForm2::copydata(TMessage& Msg)

{

typedef struct tagMYREC

{

char s1[80];

DWORD n;

} MYREC;

MYREC szClient;

char pDataClient[80];

PCOPYDATASTRUCT MyCDS;

COPYDATASTRUCT pMyCDS;

MyCDS = (PCOPYDATASTRUCT)Msg.LParam;

if(MyCDS->dwData == 5){

Memo1->Lines->Add("Запрос функции GetCurrentDirectory Клиент ID: "+ IntToStr(Msg.WParam));

GetCurrentDirectory(szClient.n,(LPSTR) ((MYREC *)(MyCDS->lpData))->s1);

pMyCDS.dwData = 10;

pMyCDS.cbData = sizeof(szClient);

pMyCDS.lpData = &szClient;

SendMessage( (HANDLE)Msg.WParam,

WM_COPYDATA,

(WPARAM)(HWND) Form2->Handle,

(LPARAM) (LPVOID) &pMyCDS );

Memo1->Lines->Add("Сообщение отправлено GetCurrentDirectory Клиент ID:"+IntToStr(hwDispatch));

Memo1->Lines->Add(szClient.s1);

}

if(MyCDS->dwData == 20){

FILETIME MYTIME;

Memo1->Lines->Add("Запрос функции SystemTimeToFileTime Клиент ID: "+ IntToStr(Msg.WParam));

SystemTimeToFileTime(((SYSTEMTIME *)(MyCDS->lpData)),&MYTIME);

pMyCDS.dwData = 25;

pMyCDS.cbData = sizeof( MYTIME );

pMyCDS.lpData = &MYTIME;

SendMessage( (HANDLE)Msg.WParam,

WM_COPYDATA,

(WPARAM)(HWND) Form2->Handle,

(LPARAM) (LPVOID) &pMyCDS );

Memo1->Lines->Add("Сообщение отправлено SystemTimeToFileTime Клиент ID:"+IntToStr(hwDispatch));

}

}

Код клиента:

void __fastcall TForm3::Button1Click(TObject *Sender)

{

HANDLE hwDispatch;

typedef struct tagMYREC

{

char s1[80];

DWORD n;

} MYREC;

COPYDATASTRUCT MyCDS;

MYREC MyRec;

HRESULT hResult;

MyCDS.dwData = 5;

MyCDS.cbData = sizeof( MyRec );

MyCDS.lpData = &MyRec;

hwDispatch = FindWindow( NULL, "server" );

if( hwDispatch != NULL )

SendMessage( hwDispatch,

WM_COPYDATA,

(WPARAM)(HWND) Form3->Handle,

(LPARAM) (LPVOID) &MyCDS );

else

MessageBox( Form3->Handle, "Can't send WM_COPYDATA", "Клиент", MB_OK );

}

__fastcall TForm3::result(TMessage& Msg)

{

typedef struct tagMYREC

{

char s1[80];

DWORD n;

} MYREC;

PCOPYDATASTRUCT pMyCDS;

pMyCDS = (PCOPYDATASTRUCT)Msg.LParam;

if(pMyCDS->dwData == 10) Edit2->Text = (LPSTR)((MYREC *)(pMyCDS->lpData))->s1;

if(pMyCDS->dwData == 25) {

Memo1->Lines->Add("Младшое слово: " + IntToStr(((FILETIME *)(pMyCDS->lpData))->dwLowDateTime));

Memo1->Lines->Add("Старшое слово: " +IntToStr(((FILETIME *)(pMyCDS->lpData))->dwHighDateTime));

}

}

void __fastcall TForm3::Button2Click(TObject *Sender)

{

SYSTEMTIME MyTime;

MyTime.wYear = Year->Text.ToInt();

MyTime.wMonth = Month->Text.ToInt();

MyTime.wDay = Day->Text.ToInt();

MyTime.wHour = Hour->Text.ToInt();

MyTime.wMinute = Minute->Text.ToInt();

MyTime.wSecond = Second->Text.ToInt();

HANDLE hwDispatch;

COPYDATASTRUCT MyCDS;

MyCDS.dwData = 20;

MyCDS.cbData = sizeof( MyTime );

MyCDS.lpData = &MyTime;

hwDispatch = FindWindow( NULL, "server" );

if( hwDispatch != NULL )

SendMessage( hwDispatch,

WM_COPYDATA,

(WPARAM)(HWND) Form3->Handle,

(LPARAM) (LPVOID) &MyCDS );

else

MessageBox( Form3->Handle, "Can't send WM_COPYDATA", "Клиент", MB_OK );

}

Результат

Вывод : Обмен сообщениями широко используется если необходимо для обмена небольшими сообщениями( так возвращаемый тип void, в данный тип можно упаковать практически любые данные) между приложениями. Недостатком является то, что вызов пользовательского сообщения должно быть зарегистрировано до компиляции приложения, хотя данной момент можно обойти, если передавать необходимые действия (код функции) в упакованном сообщении стандартным WM_COPYDATA.