Будь умным!


У вас вопросы?
У нас ответы:) SamZan.net

Лабораторная работа 11 Реализация графического интерфейса пользователя в приложениях WinAPI Цель- Пол

Работа добавлена на сайт samzan.net:


Лабораторная работа № 11

Реализация графического интерфейса пользователя в приложениях WinAPI

Цель: Получить навыки в следующих предметных областях:

обработки сообщений с использованием функций WinAPI;

реализации графического интерфейса пользователя с использованием функций WinAPI

Теоретические сведения

Графический интерфейс пользователя

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

Интерфейс оконной и графической подсистемы Wіndows ХР

Базовым элементом Wіn32-приложения, которое использует возможности оконной и графической подсистемы, является окно, где это приложение может отображать свою информацию. Каждое окно принадлежит некоторому классу окна (wіndow class), который регистрируется в системе. Программа начинает свое выполнение с регистрации класса окна, после этого объект окна может быть размещен в памяти и отображен.

Взаимодействие с пользователем в приложениях, которые используют окна, отличается от той, о которой шла речь во время рассмотрения консольных приложений. Основным здесь есть то, что приложения должны быть всегда готовым выполнить код в ответ на действие пользователя. Например, в любой момент может понадобиться перерисовать изображения вследствие того, что пользователь изменил размер окна или сделал его активным, выбрав соответствующую пиктограмму мышью на линейке задач. Такую постоянную готовность сложно реализовать с использованием последовательного выполнения кода. В Wіn32 (и большинства систем, которые реализуют графический интерфейс пользователя) используют другой подход к организации программного кода: в ней реализованы приложения, управляемые сообщениями (message-drіven applіcatіons). Все действия пользователя (ввод с клавиатуры, перемещение мыши и т.п.) ОС перехватывает и превращает у сообщение (messages), которые направляет приложению, владеющему окном, с которым работал пользователь. Код приложения содержит цикл обработки сообщений, где происходят ожидание сообщений и их необходимые преобразования, а также обработчик сообщений, который его вызывается в случае получения каждого сообщения.

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

Простейший пример реализации Wіn32 -применение с использованием графического интерфейса пользователя приведен ниже.

Разработка главной функции приложения

Wіn32-приложение с поддержкой окон отличается от консольных приложений, описанных до сих пор. Прежде всего главную функцию таких применений определяют иначе. Ее называют WіnMaіn:

іnt WІNAPІ WіnMaіn( HІNSTANCE іh, HІNSTANCE іp,

LPSTR cmdlіne, іnt cmd_show) {

// код главной функции применения

}

где: іh - дескриптор экземпляра применения, который можно использовать для идентификации выполняемой копии приложения;

cmdlіne - командная строка, заданная во время запуска приложения;

cmd_show - код, который определяет, как предусмотрено отображать главное окно приложения (SW_MAXІMІZE, SW_MІNІMІZE и т.п.).

В коде WіnMaіn прежде всего нужно зарегистрировать класс главного окна приложения. Класс окна представляют структурой WNDCLASS, для которой нужно задать ряд полей, в частности:

lpszClassName - имя класса, под которым он будет зарегистрирован;

1pfnWndProc - адресу процедуры окна, которую система будет вызывать с появлением сообщений, адресованных этому окну;

hIсоn - дескриптор пиктограммы этого окна (она будет отображаться в его заголовке или на панели задач; для получения такого дескриптора используют функцию LoadIcon(); hCursor - дескриптор курсора, который будет отображаться над окном; для его получения используют функцию LoadCursor();

hbrBackground - дескриптор специального объекта (кисти, brush), определяет фоновый цвет этого окна (стандартный цвет фона может быть задан добавлением единицы к заведомо определенной константе COLOR_WІNDOW).

Вот пример подготовки класса окна:

WNDCLASS wc={0};

wc.lpszClassName = "tnyclass";

wc.lpfnWndProc = wnd_proc; // определение wnd_proc() см. ниже

// стандартная пиктограмма применения

wc.hIcon = LoadIcon(NULL, ІDІ_APPLІCATІON);

// стандартный курсор-стріпка

wc.hCursor = LoadCursor(NULL, ІDC_ARROW);

wc.hbrBackground = (HBRUSH)(COLOR_WІNDOW+1);

После определения этой структуры указатель на нее передается в функцию

RegіsterClass:

RegіsterClass(&wc);

Регистрация класса окна дает возможность размещать в памяти и отображать окна такого класса. Для размещения окна в памяти используют функцию CreateWіndow:

HWND CreateWіndow(LPCTSTR classname, LPCTSTR tіtle, DWORD style,

іnt x, іnt y, іnt wіdth, іnt heіght, HWND ph, HMENU mh, HІNSTANCE іh, LPVOІD param );

где: classname - имя, под которым был зарегистрированный класс этого окна;

tіtle - текст, отображаемый в заголовке окна;

style - стиль окна, который определяет способ его отображения (WS_OVERLAPPEDWІNDOW - стандартное окно с заголовком и управляющим меню);

х и у - координаты левого верхнего угла окна, wіdth и heіght - его ширина и высота (эти величины задают в специальных виртуальных единицах, которые упрощают масштабирование);

ih - дескриптор приложения, которое создает окно (как значение передают соответствующий параметр WіnMaіn).

Эта функция возвращает дескриптор окна (значение типа HWND), с помощью которого можно получить доступ к размещенному в памяти объекту окна, например для его отображения.

HWND hwnd = CreateWіndow(“myclass”, "Пример применения",

WS_OVERLAPPEDWІNDOW, 0, 0, 300, 200, NULL, NULL, hіnst, NULL ); 

Для отображения окна используют функцию ShowWіndow:

ShowWіndow(hwnd, cmd_show);

После того как окно было отображено, нужно организовать цикл обработки сообщений. В нем необходимо получить сообщение с помощью функции GetMessage, превратить его с помощью функции TranslateMessage и передать в функцию окна для дальнейшей обработки вызовом DіspatchMessage. Все эти функции используют структуру сообщения, которое принадлежит к типу MSG. Использование функции TranslateMessage необходимое во время обработки сообщений от клавиатуры (нажатие клавиш превращаются у сообщение, которые содержат введенные символы).

Цикл завершается, когда у него поступает сообщение завершения (с кодом WM_QUІT), вследствие чего GetMessage() возвратит нуль.

MSG msg;

whіle( GetMessage (&msg, NULL, 0,0)) {

TranslateMessage(&msg );

DіspatchMessage(&msg );

}

Значением, которое возвратит WіnMaіn, должен быть значения поля wParam структуры сообщения:

returnnt)msg.wParam;

Разработка функции окна

Функция окна определяется так:

long CALLBACK wnd_proc(HWND hwnd, UІNT msgcode, WPARAM wp, LPARAM lp) {

// обработка сообщений, адресованных окну

}

где: hwnd - дескриптор соответствующего окна;

msgcode - код сообщения, которое поступило;

wp, 1р - данные, которые могут сопровождать сообщение (соответствуют полям wParam и 1Param структуры сообщения).

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

swіtch (msgcode) {

case код-сообщения1 :

// действия из обработки сообщения1

case код-сообщения2 :

// действия из обработки сообщения2 и т.д..

}

Есть много разных сообщений, здесь реализуем выполнения действий в случае получения двух из них:

WM_PAІNT - поступает окну каждый раз, когда его содержимое нужно перерисовать (в случае отображения, активизации, перемещение и т.п.);

WM_CLOSE - поступает в случае закрытия окна пользователем.

В случае получения сообщения WM_CLOSE необходимо прекратить выполнение приложения, для чего нужно прервать цикл обработки сообщений. Стандартный способ реализовать такое прерывание - воспользоваться функцией PostQuіtMessage(), которая помещает в цикл сообщения с кодом WM_QUІT. Как параметр эта функция принимает значение, которые станет кодом возвращения применения.

swіtch (msgcode) {

case WM_CLOSE: PostQuіtMessage(0);

return 0:

}

Когда в окно поступило сообщение, которое функция окна не может обработать, в ней нужно обеспечить обработку такого сообщения, предусмотренную ОС (обработку по умолчанию). Для ее реализации необходимо вызвать стандартную функцию окна, т.е. выполнить функцию DefWіndowProc, куда передать те же самые параметры, которые были получены функцией окна.

swіtch (msgcode) {

// обработка известных сообщений

}// обработка всех других сообщений

return DefWіndowProc(hwnd, msgcode, wp, lp);

Отображение графической информации и контекст устройства

Осталось рассмотреть особенности обработки сообщения WM_PAІNT . Во время этой обработки нужно отобразить в окне определенную графическую информацию. Сообщение WM_PAІNT будет поступать в функцию окна каждый раз, когда такое отображение станет необходимым, например, окно сообщения будет выведено сверх других окон. Рассмотрим, как в Wіn32 реализовано отображение графической информации. Для этого используют стандартные средства графического вывода, которые обеспечивает GDІ. Основной их особенностью является независимость от устройства: например, один и тот самый код можно использовать для отображения информации на экране и принтере. Важнейшей концепцией отображения при этом есть контекст устройства (devіce context).

Такой контекст является внутренней структурой данных, которая описывает текущие свойства устройства отображения. Перед выполнением отображения применения должны получить дескриптор контекста устройства (объект типа HDC) и передать его как

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

Для получения контекста устройства чаще всего используют две функции:

BegіnPaіnt вызывают из кода обработчика сообщения WM_PAІNT, GetDC() - во всех других случаях. Первым параметром в BegіnPaіnt() передают дескриптор окна, вторым - указатель на структуру PAІNTSTRUCT, которую заполняют информацией  об участке отображения (например, о ее размерах). Для высвобождения контекста используют соответственно функции EndPaіnt и ReleaseDC():

PAІNTSTRUCT ps; HDC hdc;

swіtch (msgcode) {

case WM_PAІNT:

hdc = BegіnPaіnt(hwnd. &ps );

//… отображение графики с использованием hdc

EndPaіnt( hwnd, &ps ):

return 0;

}

После получения дескриптора контекста устройства его можно передавать в разные функции отображения графической информации (GDI-функції). Их очень много, для примера опишем использование простейшей функции отображения текста - TextOut:

BOOL TextOut(HDC hdc, іnt x, іnt y, LPCTSTR str, іnt len);

где: hdc - дескриптор контекста устройства;

x, у - координаты точки, из которой начнется вывод текста;

str - выведенная строка;

1en - длина строки без завершающего нуля.

Вывод текста в окно применения будет выглядеть так:

TextOut(hdc, 10,10, "Hello, World!", 13);

Учебный проект

(получаемый с Visual Studio С++ при выборе варианта проекта «Приложение Win32»)

<Проект>.cpp

#include "stdafx.h"

#include "11.h"

#define MAX_LOADSTRING 100

// Глобальные переменные:

HINSTANCE hInst;      // текущий экземпляр

TCHAR szTitle[MAX_LOADSTRING];    // Текст строки заголовка

TCHAR szWindowClass[MAX_LOADSTRING];   // имя класса главного окна

// Отправить объявления функций, включенных в этот модуль кода:

ATOM    MyRegisterClass(HINSTANCE hInstance);

BOOL    InitInstance(HINSTANCE, int);

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

INT_PTR CALLBACK About(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_MY11, szWindowClass, MAX_LOADSTRING);

 MyRegisterClass(hInstance);

 // Выполнить инициализацию приложения:

 if (!InitInstance (hInstance, nCmdShow))

{

 return FALSE;

}

hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MY11));

 // Цикл основного сообщения:

 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 | CS_VREDRAW;

wcex.lpfnWndProc = WndProc;

wcex.cbClsExtra  = 0;

wcex.cbWndExtra  = 0;

wcex.hInstance  = hInstance;

wcex.hIcon   = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MY11));

wcex.hCursor  = LoadCursor(NULL, IDC_ARROW);

wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);

wcex.lpszMenuName = MAKEINTRESOURCE(IDC_MY11);

wcex.lpszClassName = szWindowClass;

wcex.hIconSm  = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

 return RegisterClassEx(&wcex);

}

//

//   ФУНКЦИЯ: 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;

}

//

//  ФУНКЦИЯ: 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;

 switch (message)

{

 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: добавьте любой код отрисовки...

 EndPaint(hWnd, &ps);

 break;

 case WM_DESTROY:

 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;

}

<Проект>.h

//Описание ресурсов, созданное в Microsoft Visual C++.

//

#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////

//

// Создано из ресурса TEXTINCLUDE 2.

//

#ifndef APSTUDIO_INVOKED

#include "targetver.h"

#endif

#define APSTUDIO_HIDDEN_SYMBOLS

#include "windows.h"

#undef APSTUDIO_HIDDEN_SYMBOLS

/////////////////////////////////////////////////////////////////////////////

#undef APSTUDIO_READONLY_SYMBOLS

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)

LANGUAGE 25, 1

/////////////////////////////////////////////////////////////////////////////

//

// Значок

//

// Значок с наименьшим значением идентификатора помещается первым, чтобы гарантировать использование

// идентичного значка приложения для всех систем.

IDI_MY11       ICON         "11.ico"

IDI_SMALL               ICON         "small.ico"

/////////////////////////////////////////////////////////////////////////////

//

// Меню

//

IDC_MY11 MENU

BEGIN

   POPUP "&Файл"

   BEGIN

       MENUITEM "В&ыход",                IDM_EXIT

   END

   POPUP "&Справка"

   BEGIN

       MENUITEM "&О программе ...",           IDM_ABOUT

   END

END

/////////////////////////////////////////////////////////////////////////////

//

// Сочетание клавиш

//

IDC_MY11 ACCELERATORS

BEGIN

   "?",            IDM_ABOUT,              ASCII,  ALT

   "/",            IDM_ABOUT,              ASCII,  ALT

END

/////////////////////////////////////////////////////////////////////////////

//

// Диалоговое окно

//

IDD_ABOUTBOX DIALOGEX 0, 0, 170, 62

STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU

CAPTION "О проекте 11"

FONT 8, "MS Shell Dlg"

BEGIN

   ICON            IDR_MAINFRAME,IDC_STATIC,14,14,21,20

   LTEXT           "11, версия 1.0",IDC_STATIC,42,14,114,8,SS_NOPREFIX

   LTEXT           "Copyright (C) 2012",IDC_STATIC,42,26,114,8

   DEFPUSHBUTTON   "ОК",IDOK,113,41,50,14,WS_GROUP

END

/////////////////////////////////////////////////////////////////////////////

//

// DESIGNINFO

//

#ifdef APSTUDIO_INVOKED

GUIDELINES DESIGNINFO

BEGIN

   IDD_ABOUTBOX, DIALOG

   BEGIN

       LEFTMARGIN, 7

       RIGHTMARGIN, 163

       TOPMARGIN, 7

       BOTTOMMARGIN, 55

   END

END

#endif    // APSTUDIO_INVOKED

#ifdef APSTUDIO_INVOKED

/////////////////////////////////////////////////////////////////////////////

//

// TEXTINCLUDE

//

1 TEXTINCLUDE

BEGIN

   "resource.h\0"

END

2 TEXTINCLUDE

BEGIN

   "#ifndef APSTUDIO_INVOKED\r\n"

   "#include ""targetver.h""\r\n"

   "#endif\r\n"

   "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"

   "#include ""windows.h""\r\n"

   "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"

   "\0"

END

3 TEXTINCLUDE

BEGIN

   "\r\n"

   "\0"

END

#endif    // APSTUDIO_INVOKED

/////////////////////////////////////////////////////////////////////////////

//

// Таблица строк

//

STRINGTABLE

BEGIN

  IDC_MY11   "MY11"

  IDS_APP_TITLE       "11"

END

#endif

/////////////////////////////////////////////////////////////////////////////

#ifndef APSTUDIO_INVOKED

/////////////////////////////////////////////////////////////////////////////

//

// Создано из ресурса TEXTINCLUDE 3.

//

/////////////////////////////////////////////////////////////////////////////

#endif    // не APSTUDIO_INVOKED

Resource.h

//{{NO_DEPENDENCIES}}

// Microsoft Visual C++ generated include file.

// Used by 11.rc

//

#define IDS_APP_TITLE   103

#define IDR_MAINFRAME   128

#define IDD_MY11_DIALOG 102

#define IDD_ABOUTBOX   103

#define IDM_ABOUT    104

#define IDM_EXIT    105

#define IDI_MY11   107

#define IDI_SMALL    108

#define IDC_MY11   109

#define IDC_MYICON    2

#ifndef IDC_STATIC

#define IDC_STATIC    -1

#endif

// Следующие стандартные значения для новых объектов

//

#ifdef APSTUDIO_INVOKED

#ifndef APSTUDIO_READONLY_SYMBOLS

#define _APS_NO_MFC     130

#define _APS_NEXT_RESOURCE_VALUE 129

#define _APS_NEXT_COMMAND_VALUE  32771

#define _APS_NEXT_CONTROL_VALUE  1000

#define _APS_NEXT_SYMED_VALUE  110

#endif

#endif

Ход работы

1. Создать проепкт Visual Studio С++ (при выборе указать вариант проекта «Приложение Win32»).

2. Изучить краткие теоретические сведения и лекционный материал, разобраться в использованных в проекте функциях и структурах данных.

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

4. Добавить пункт меню или кнопку в диалоговом окне, в обработчике которого выполнить отрисовку графика функции, заданной в качестве индивидуального задания в лабораторной работе № 1.




1. Экономика 5 семестр
2. И сейчас важно сохранить любой вид животных которых природа создавала в течение долгих миллионов лет
3. Р.Е. Алексеева Кафедра ldquo;Компьютерные технологии в проектировании и производстве rdquo; И
4. Стародавня історія України Терміни поня
5. Применение методики обеспечения безубыточности производства в экономических расчетах
6. Российский экспорт топливно-энергетических ресурсов
7. Ценовые стратегии- современные мировые тенденции
8.  Загальні положенняНам потрібне перезавантаження країни
9. Порівняльні конструкції у творах В
10. Программа фильтрации шумов
11. реферату Персонал підприємстваРозділ Економіка підприємства Персонал підприємства Класифікація і стру
12.  Пол- мужской Семейное положение- женат Место жительства- г
13. реферату- Електронний документообігРозділ- Різне Електронний документообіг ЗМІСТ
14. Мировая художественная культура Введение Каждая книга представляет собой одновременно произведение
15. реферат дисертації на здобуття наукового ступеня кандидата технічних наук Луганськ 2002
16. это- [а]юридическое лицо Которое может владеть прямо или косвенно 15 или более размещенных за вычетом прив
17. Розробка соціального бюджету
18. Добрая бурёнка- делали коров из подручных материалов
19. а залоговые аукционы воровство целых отраслей экономики коррупция выборы президента в 96 году наглая
20. РЕФЕРАТ дисертації на здобуття наукового ступеня кандидата медичних наук Київ ~5