Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
6 семестр / ОСиСП_ЛР1.docx
Скачиваний:
0
Добавлен:
18.02.2023
Размер:
1.66 Mб
Скачать

Министерство образования Республики Беларусь

ПОЛОЦКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ

Кафедра технологий программирования

Методические указания для выполнения лабораторной работы № 1

по курсу «Операционные системы и системное программирование»

«Оконный пользовательский интерфейс. Создание оконных приложений средствами WinAPI и WinForms»

Полоцк, 2019

Цель: научиться создавать оконный интерфейс для приложений в ОС Windows.

Теоретическая часть

С++

Библиотека Win32 API – библиотека, содержащая функции ОС Windows предназначенные для организации взаимодействия прикладных программ пользователя с сервисом, предоставляемым ОС Windows. В программу необходимо, как минимум, подключить библиотеку . При использовании специфичных сервисов возможно понадобится подключение и других библиотек. В библиотеке Win32 API содержится описание довольно большого количества типов данных, большинство из которых создано с использованием директив #define или typedef. Эти типы данных могут переопределять системные типы данных языков С/C++ таких как int, long, char*, constchar* и д.р. Также эти типы данных могут содержать объявления структур, предназначенных для описания каких-либо сложных объектов, посредством которых осуществляется взаимодействие с операционной системой. В таблице 1 приведены некоторые из типов данных, описанные в библиотеках Win32API.

В основе взаимодействия программы с внешним миром и с операционной системой лежит

концепция сообщений. С точки зрения приложения, сообщение является уведомлением о том,

что произошло некоторое событие, которое может требовать, а может и не требовать

выполнения определенных действий. Это событие может быть следствием действий

пользователя, например перемещения курсора или щелчка кнопкой мыши, изменения размеров

окна или выбора пункта меню. Кроме того, событие может генерироваться приложением, а

также операционной системой.

Сообщение - это структура данных, содержащая следующие элементы:

 дескриптор окна, которому адресовано сообщение;

 код (номер) сообщения;

 дополнительную информацию, зависящую от кода сообщения.

Сообщения в Windows описываются с помощью структуры

Сообщения от внешних источников, например от клавиатуры, адресуются в каждый конкретный момент времени только одному из работающих приложений, а именно - активному окну. Windows играет роль диспетчера сообщений. Для этого с момента старта операционная система создает в памяти глобальный объект,называемый системной очередьюсообщений.Все сообщения,генерируемые как аппаратурой,так и приложениями,помещаютсяв эту очередь. Windows периодически опрашивает эту очередь и, если она не пуста, посылает очередное сообщение нужному адресату, определяемому при помощи дескриптора окна. Сообщения, получаемые приложением , могут поступать асинхронно из разных источников. Например , приложение может работать с системным таймером, посылающим ему сообщения с заданным интервалом, и одновременно оно должно быть готовым в любой момент получить любое сообщение от операционной системы. Чтобы не допустить потери сообщений, Windows одновременно с запуском приложения создает глобальный объект, называемый очередью сообщений приложения. Основу программы в Win32 составляет функция WinMain, которая «заменяет» собой стандартную функцию main языков C и C++. Описание этой функции имеет следующий вид:

Параметры функции WinMain:

 HINSTANCE hInstance – идентификатор текущего приложения;

 HINSTANCE hPrevInstance – идентификатор приложения, являющегося родительским для данного приложения;

 LPTSTR lpCmdLine – С-строка, содержащая параметры командной строки;

intnCmdShow – код вида начального отображения окна. Возвращаемое значение функции WinMain: целое число, интерпретируемое как код возврата. Обычно в качестве его значения указывается параметр сообщения закрытия приложения в виде: (int) msg.wParam На рисунке 1 приведен основной алгоритм реализации функции WinMain.

Для описания класса окна необходимо заполнить структуру типа WNDCLASSEX или WNDCLASS (старый вариант).

После заполнения всех полей данной структуры класса окна необходимо зарегистрировать с помощью функции RegisterClassEx() или RegisterClass() (старый вариант). Прототипфункции:

ATOM RegisterClassEx(CONST WNDCLASSEX *lpwcx );

В параметре в функцию передается адрес заполненной структуры типа WNDCLASSEX. Функция возвращает идентификатор зарегистрированного класса окна в случае успешного выполнения. В случае ошибки функция возвращает 0. После успешной регистрации класса окна необходимо создать само окно. Это осуществляется с помощью функции CreateWindow. Прототип функции:

В случае успешного выполнения функция CreateWindow возвращает дескриптор созданного окна. В случае ошибки функция возвращает NULL. Некоторые стили окна приведены в таблице 2.

После того, как окно успешно создано, его необходимо отобразить используя функции

ShowWindow и UpdateWindow.

Функция отображения окна:

BOOL ShowWindow(HWND hWnd, intnCmdShow);

Некоторые типы команд отображения окна:

 SW_HIDE – скрыть окно и активизировать другое окно,

 SW_MAXIMIZE – развернуть на весь экран,

 SW_MINIMIZE – свернуть окно и активизировать предыдущее окно,

 SW_RESTORE – восстановить изначальные размеры окна,

 SW_SHOW – активизировать окно и отобразить его.

Функция возвращает истину, если окно было изначально видимо, и ложь – если нет.

Функция обновления окна:

voidUpdateWindow(HWNDhWnd);

Вызывает обновление (перерисовку) окна.

После создания и отображения окна необходимо организовать цикл получения и

обработки сообщений. Для этих целей в Win32 API используются следующие функции:

 GetMessage – получение сообщения,

 TranslateMessage – преобразует сообщения виртуальных клавиш в символьные сообщения,

 DispatchMessage – вызывает обработчик сообщения.

Функция получения сообщения

Если функция получает сообщение отлично от WM_QUIT, то возвращается не нулевое

значение (истина).

Функция преобразования сообщения виртуальных клавиш в символьные сообщения

BOOL TranslateMessage(const MSG *lpMsg );

Возвращает значение «истина», если сообщение было успешно преобразовано. Если

сообщение не преобразовано, то возвращает значение «ложь». Данная функция предназначена

для создания сообщений WM_CHAR на основе сообщений WM_KEYDOWN и WM_KEYUP.

Функция обработки сообщения

LRESULT DispatchMessage(const MSG *lpmsg );

Функция вызывает функцию-обработчик сообщений для данного окна и возвращает

результат обработки. Значение результата зависит от самой функции-обработчика, и как

правило игнорируется.

Типовая функция WinMain, реализующая основной алгоритм работы приложения:

Далее приведены некоторые функции для работы с окнами:

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

BOOL IsWindow(HWND hwnd);

Функция проверки наличия фокуса ввода у окна

BOOL IsWindowEnabled(HWND hwnd);

Функция разрешения или запрета фокуса ввода у окна

BOOL EnableWindow(HWND hwnd, BOOL flag);

Функция передачи фокуса управления окну

HWND SetFocus(HWND hwnd);

Функция поиска окна с заданными классом и названием

HWND FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName);

Функцияперемещенияокна

BOOL MoveWindow(HWND hwnd, int x, int y, intnWidth,

intnHeight, BOOL bRepaint);

Функцияотносительногоперемещенияокна:

BOOL SetWindowPos(HWND hwnd, HWND hwndInsertAfter, int x, int y,

intnWidth,intnHeight, UINT uFlags);

hwndInsertAfter может быть дескриптором существующего окна или одним из следующих

значений:

 HWND_BOTTOM – помещает окно ниже других окон,

 HWND_NOTOPMOST – помещает временное или дочернее окно выше временных или

дочерних окон, но ниже перекрывающихся окон,

 HWND_TOP – помещает окно выше всех окон,

 HWND_TOPMOST – то же, что HWND_NOTOPMOST, но окно сохраняет позицию после

потери активности.

Вывод окна на передний план и передача ему управления:

BOOL SetForegroundWindow(HWND hwnd);

Функция получения системных метрик:

intGetSystemMetric(intnIndex);

nIndex может принимать следующие значения:

 SM_CXMIN – минимальная ширина окна,

 SM_CYMIN – минимальная высота окна,

 SM_CXSCREEN – ширина окна,

 SM_CYSCREEN – высота окна,

 SM_CYCAPTOIN – высота заголовка окна,

 SM_CYMENU – высота меню окна.

Функция получения параметров окна:

BOOL GetWindowRect(HWND hwnd, LPRECT rect);

Значения флагов, управляющие набором кнопок, расположенных на окне:

 MB_ABORTRETRYIGNORE – Стоп, Отмена, Пропустить

 MB_OK – ОК,

 MB_OKCANCEL – ОК, Отмена,

 MB_RETRYCANCEL – Повтор, Отмена,

 MB_YESNO – Да, Нет,

 MB_YESNOCANCEL – Да, Нет, Отмена

Значения флагов, управляющие видом отображающейся иконки на окне сообщения:

 MB_ICONEXCLAMATION, MB_ICONWARNING – восклицательный знак;

 MB_ICONINFORMATION, MB_ICONASTERIX – символ i,

 MB_ICONQUESTION – знак вопроса,

 MB_ICONSTOP, MB_ICONERROR, MB_ICONHAND – знакостановки.

Значения флагов, управляющие способом отображения окна сообщения:

 MB_APPLMODAL – окно hwnd переводится в неактивное состояние на время работы окна

сообщения,

 MB_SYSTEMMODAL – на время работы окна сообщения все другие приложения в

неактивном состоянии,

 MB_TASKMODAL – на время работы окна сообщения текущее приложение в неактивном

состоянии. Если hwnd=NULL, то все перекрывающие окна,

 MB_HELP – добавляет кнопку «Справка»,

 MB_RIGHT – текст выравнивается по правому краю,

 MB_RTLREADING – отображает символы сообщения и текст заголовка в направлении

справа налево,

 MB_SETFOREGROUND – окно сообщения выдвигается на передний план.

С#

Для создания графического проекта нам потребуется среда разработки Visual Studio.

После установки среды и всех ее компонентов, запустим Visual Studio и создадим проект графического приложения. Для этого в меню выберем пункт File (Файл) и в подменю выберем New - > Project (Создать - > Проект). После этого перед нами откроется диалоговое окно создания нового проекта:

В левой колонке выберем Windows Desktop, а в центральной части среди типов проектов - тип Windows Forms Application и дадим ему какое-нибудь имя в поле внизу. Например, назовем его HelloApp. После этого нажимаем OK.

После этого Visual Studio откроет наш проект с созданными по умолчанию файлами:

Большую часть пространства Visual Studio занимает графический дизайнер, который содержит форму будущего приложения. Пока она пуста и имеет только заголовок Form1. Справа находится окно файлов решения/проекта - Solution Explorer (Обозреватель решений). Там и находятся все связанные с нашим приложением файлы, в том числе файлы формы Form1.cs.

Внизу справа находится окно свойств - Properties. Так как в данный момент выбрана форма как элемент управления, то в этом поле отображаются свойства, связанные с формой.

Теперь найдем в этом окне свойство формы Text и изменим его значение на любое другое:

Таким образом мы поменяли заголовок формы. Теперь перенесем на поле какой-нибудь элемент управления, например, кнопку. Для этого найдем в левой части Visual Studio вкладку Toolbox (Панель инструментов). Нажмем на эту вкладку, и у нас откроется панель с элементами, откуда мы можем с помощью мыши перенести на форму любой элемент:

Найдем среди элементов кнопку и, захватив ее указателем мыши, перенесем на форму:

Это визуальная часть. Теперь приступим к самому программированию. Добавим простейший код на языке C#, который бы выводил сообщение по нажатию кнопки. Для этого мы должны перейти в файл кода, который связан с этой формой. Если у нас не открыт файл кода, мы можем нажать на форму правой кнопкой мыши и в появившемся меню выбрать View Code (Посмотреть файл кода):

Однако воспользуемся другим способом, чтобы не писать много лишнего кода. Наведем указатель мыши на кнопку и щелкнем по ней двойным щелчком. Мы автоматически попадаем в файл кода Form1.cs, который выглядит так:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

 

namespace HelloApp

{

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }

 

        private void button1_Click(object sender, EventArgs e)

        {

 

        }

    }

}

Добавим вывод сообщения по нажатию кнопки, изменив код следующим образом:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

 

namespace HelloApp

{

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }

 

        private void button1_Click(object sender, EventArgs e)

        {

            MessageBox.Show("Привет");

        }

    }

}

Запуск приложения

Чтобы запустить приложение в режиме отладки, нажмем на клавишу F5 или на зеленую стрелочку на панели Visual Studio. После этого запустится наша форма с одинокой кнопкой. И если мы нажмем на кнопку на форме, то нам будет отображено сообщение с приветствием.

После запуска приложения студия компилирует его в файл с расширением exe. Найти данный файл можно, зайдя в папку проекта и далее в каталог bin/Debug или bin/Release

Внешний вид приложения является нам преимущественно через формы. Формы являются основными строительными блоками. Они предоставляют контейнер для различных элементов управления. А механизм событий позволяет элементам формы отзываться на ввод пользователя, и, таким образом, взаимодействовать с пользователем.

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

Если мы запустим приложение, то нам отобразится одна пустая форма. Однако даже такой простой проект с пустой формой имеет несколько компонентов:

Все файлы в Windows Forms

Несмотря на то, что мы видим только форму, но стартовой точкой входа в графическое приложение является класс Program, расположенный в файле Program.cs:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Threading.Tasks;

using System.Windows.Forms;

namespace HelloApp

{

static class Program

{

[STAThread]

static void Main()

{

Application.EnableVisualStyles();

Application.SetCompatibleTextRenderingDefault(false);

Application.Run(new Form1());

}

}

}

Сначала программой запускается данный класс, затем с помощью выражения Application.Run(new Form1()) он запускает форму Form1. Если вдруг мы захотим изменить стартовую форму в приложении на какую-нибудь другую, то нам надо изменить в этом выражении Form1 на соответствующий класс формы.

Сама форма сложна по содержанию. Она делится на ряд компонентов. Так, в структуре проекта есть файл Form1.Designer.cs, который выглядит примерно так:

namespace HelloApp

{

partial class Form1

{

/// <summary>

/// Required designer variable.

/// </summary>

private System.ComponentModel.IContainer components = null;

/// <summary>

/// Clean up any resources being used.

/// </summary>

/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>

protected override void Dispose(bool disposing)

{

if (disposing && (components != null))

{

components.Dispose();

}

base.Dispose(disposing);

}

#region Windows Form Designer generated code

/// <summary>

/// Required method for Designer support - do not modify

/// the contents of this method with the code editor.

/// </summary>

private void InitializeComponent()

{

this.SuspendLayout();

//

// Form1

//

this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);

this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;

this.ClientSize = new System.Drawing.Size(284, 261);

this.Name = "Form1";

this.Text = "Привет мир!";

this.ResumeLayout(false);

}

#endregion

}

}

Здесь объявляется частичный класс формы Form1, которая имеет два метода: Dispose(), который выполняет роль деструктора объекта, и InitializeComponent(), который устанавливает начальные значения свойств формы.

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

Но на практике вы редко будете сталкиваться с этим классом, так как он выполняет в основном дизайнерские функции - установка свойств объектов, установка переменных.

Еще один файл - Form1.resx - хранит ресурсы формы. Как правило, ресурсы используются для создания однообразных форм сразу для нескольких языковых культур.

И более важный файл - Form1.cs, который в структуре проекта называется просто Form1, содержит код или программную логику формы:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

namespace HelloApp

{

public partial class Form1 : Form

{

public Form1()

{

InitializeComponent();

}

}

}

По умолчанию здесь есть только конструктор формы, в котором просто вызывается метод InitializeComponent(), объявленный в файле дизайнера Form1.Designer.cs. Именно с этим файлом вы и будете больше работать.

Соседние файлы в папке 6 семестр