5606

Графический интерфейс в MS WINDOWS

Контрольная

Информатика, кибернетика и программирование

Графический интерфейс в MSWINDOWS Переход к программированию для Windows требует знаний графических возможностей этой операционной системы. Связано это с тем, что Windows является графической системой, в нем отсутствует текстовый режим...

Русский

2012-12-15

1.37 MB

8 чел.

Графический интерфейс в MS WINDOWS

Переход к программированию для Windows требует знаний графических возможностей этой операционной системы. Связано это с тем, что Windows является графической системой, в нем отсутствует текстовый режим, - основной режим DOS. Кроме этого, хорошее графическое исполнение является одним из основных требований к современному программному обеспечению.

В этой главе будет рассказано о графическом интерфейсе GDI (Graphicс Device Interface - интерфейс графических устройств). Посредством этого интерфейса Windows выводит графику на экран монитора, принтер и другие устройства. GDI избавляет программиста учитывать многие аппаратные особенности компьютеров, например, особенности различных видеокарт. Рисование, с использованием GDI, имеет как положительные так и отрицательные стороны. К положительным сторонам можно отнести переносимость программ, в том числе и на различные платформы. С дугой стороны GDI является довольно «толстой» прослойкой, поэтому программы, использующие GDI, работают медленно.

Альтернативой GDI является графическая библиотека OpenGL. Это довольно тонкая прослойка между приложением и видеокартой, что делает сопоставимой скорость работы программы DOS и приложения Windows. Кроме этого, OpenGL обладает еще целым рядом достоинств по сравнению с GDI. Эти достоинства рассматриваются в курсе «Компьютерная графика». Крупный недостаток OpenGL - возможность работы только в среде Windows 95 и Windows NT.

1 Некоторые предупреждения

Приложения Windows не работают непосредственно с физическими устройствами (например, с монитором или принтером). Выполняя запрос приложения (нарисовать линию или написать текст), приложение обращается к GDI, которое, в свою очередь, обращается к соответствующему драйверу, а тот, непосредственно к физическому устройству. В процессе выполнения команды GDI (или драйвер) учитывают ограничения, накладываемые соответствующим физическим устройством. Например, приложение может использовать любой из примерно 16 миллионов цветов, но если данное устройство не поддерживает такого количества цветов, то GDI будет подбирать наиболее близкие цвета, в этом случае многие нарисованные приложением линии могут оказаться одного цвета.

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

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

2 Состав и назначение GDI

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

Если же говорить точно, то контекст отображения является структурой данных, описывающих устройство отображения. В этой структуре хранятся различные характеристики устройства (бумаги) и набор инструментов для рисования, выбранные по умолчанию. Приложение может выбрать в контекст отображения различные инструменты (например, перья различной толщины и цвета). Поэтому, если Вам необходимо нарисовать линию красного цвета, то перед выполнением операции рисования, необходимо выбрать в контекст отображения соответствующее перо.

Функции рисования не имеют параметров, указывающих цвет и толщину линий. Такие параметры хранятся в контексте отображения.

Приложение может создать контекст отображения не только для экрана монитора, но и для любого другою графического устройства, например, для принтера. В этом случае, оно может рисовать на принтере различные изображения, используя те же функции, что и при рисовании на экране. Можно создать контекст отображения для метафайла. Метафайл - это обычный файл на диске или в памяти, в котором хранятся последовательности команд интерфейса GDI. Приложение может выполнить вывод графической информации в метафайл, как в обычное устройство вывода, а затем «проиграть» метафайл на реальном устройстве вывода (экран монитора или принтер).

3 Контекст отображения и контекст устройства. Атрибуты контекста отображения.

Опишем более подробно, что такое «лист бумаги», на которой приложение рисует, то есть контекста отображения.

Может существовать два типа контекста: контекст отображения и контекст устройства,

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

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

Необходимо иметь в виду, что оба контекста представляют собой одну и ту же структуру.

Всего контекст отображения (структура) имеет 20 атрибутов. Это:

1. описание применяемой системы координат;

2. цвет графических объектов и цвет фона;

3. описание цветовой палитры (набора цветов используемых для рисования);

4. описание пера для рисования линий;

описание кисти для закрашивания;

6. описание области, где приложение может рисовать, или наоборот, области, в которой рисовать запрещено;

7. атрибуты, предназначенные для рисования текста (это шрифт и цвет текста, расстояние между буквами, а также цвет текста).

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

4 Работа с контекстами

Всего существует около 10 различных контекстов отображения. Чаще всего используется общий контекст отображения.

4.1 Общий контекст отображения

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

HDC BeginPalnt(

HWND hWnd,               II дескриптор окна

LPPAINTSTRUCT *lрРаint    II указатель на структуру для рисования );

Функция подготавливает для рисования окно, заполняя структуру PAINTSTRUCT информацией, которую можно использовать в процессе рисования.

Контекст отображения, полученный с помощью функции BeginPaint, необходимо освободить перед завершением обработки сообщения WM_PAINT, вызвав функцию EndPaint.

BOOL EndPaint(

HWND hWnd,                                   II дескриптор окна

CONST PAINTSTRUCT *lpPaint   II указатель на структуру для рисования );

Обработчик сообщений WM_PAINT выглядит следующим образом:

case WM_PAINT:

{

PAINTSTRUCT ps;

HDC hdc;

// Получаем общий контекст отображения

hdc= BeginPaint(/nwnd, &ps);

Text0ut(hdc, 10, 20, "String", 6);

// Отдаем контекст отображения EndPaint(hwnd, &ps);

return 0;

}

Функции BeginPaint и EndPaint можно использовать только в обработчике сообщений WM_PAINT. Если же приложению необходимо рисовать во время обработки других сообщений, то необходимо использовать функции соответственно:

HDC GetDC(

HWND hWnd                  //дескриптор окна

     );

И

int ReleaseDC(

HWND hwnd,                 // дескриптор окна

HDC hdc                     II дескриптор контекста отображения ){

4.2 Контекст физического устройства

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

HDC CreateDC(

LPCSTR lp4:Driver,            II имя драйвера

LPCSTR lps:De\'ice,            II имя устройства

LPCSTR 1рч:0шри1,           II имя файла или порта вывода

CONST DEVMODE *lpvlnitDala II данные для инициализации принтера

);

Например, для создания контекста отображения струйного принтера Lexmark 1020 ColorFine 2, работающего с

драйвером wwlxru.drv и подключенного к порту LPT1, необходимо вызвать функцию CreateDC следующим образом:

hdc = CreateDC( "wwlxru", "Lexmark 1020 ColorFine 2 ", ''LPT1". NULL);

Созданный таким образом контекст устройств необходимо удалить (но не освободить) при помощи функции DeleteDC:

BOOL DeleteDC (

HDC hdc                     II дескриптор контекста отображения

);

4.3 Контекст для устройства DISPLAY

Что бы рисовать в любом месте экрана, необходимо создать контекст монитора:

Hdc = -CreateDC("DISPLAY", NULL, NULL, NULL);

После использования контекста, его необходимо удалить, вызвав функцию DeleteDC.

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

hdc = GetDC{NULL);

Этот контекст нужно не удалять, • освобождать:

ReleaseDC( NULL, hdc );

4.4 Контекст для памяти

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

Контекст для памяти создается совместимым с тем контекстом отображения, в котором будет выполняться вывод на физическое устройство. Для этих целей служит функция CreateCompatibleDC:

HDC CreateCompatibleDC (

HDC/ hdc                     //дескриптор контекста отображения

);

4.5 Контекст для метафайла

Метафайл может находиться как на диске, так и памяти. В последнем случае его можно использовать для переноса в другие приложения (например Word).

Создается метафайл функцией СгeateМetаfile:

HDC CreateMetaFile (

LPCSTR IpszFileName         II Указатель на текстовую строку с именем файла

);

Параметр IpszFileName должен содержать полное имя файла или NULL. В последнем случае будет создан метафайл в памяти.

После рисования в контексте метафайла его необходимо закрыть, вызвав функцию CloseMetaFile:

НМЕТАFILE CloseMetaFile(

HDCLbdc.._.                  // дескриптор контекста отображения

);

После закрытия метафайла, пользоваться им уже нельзя.

С метафайлом можно выполнить следующие операции:

• Можно скопировать метафайл в обычный дисковый файл, вызвав функцию CopyMetaFile

HMETAFILE CopyMetaFile(HMETAFILE hmf, LPCSTR IpszfileName );

• Можно проиграть метафайл в контексте отображения или в контексте устройства

BOOL PlayMetaFile(HDC hdc, HMETAFILE hmf);

 Можно удалить метафайл

BOOL DeleteMetaFile(HМЕТАFILE hmf);

Удаление метафайла делает недоступным идентификатор hmf. Функция DeleteMetafile не удаляет метафайл с диска. Чтобы воспользоваться метафайлом, находящимся на диске, его необходимо загрузить

HMETAFILE GetMetaFile( LPCSTR IpszFileName);

5 Выбор режима отображения

1 Физические и логические координаты

Физические координаты имеют отношение непосредственно к физическому устройству вывода. Здесь, в качестве единицы измерения всегда используется пиксел. Если устройство вывода - монитор, то физические координаты носят название экранных координат. Начало этой системы координат располагается в левом верхнем углу (рис. 1).

Чтобы определить физическое разрешение монитора, следует использовать функцию GetDeviceCaps:

HDC hdc;

int nVertRes, nHorzRes,

hdc = CreateDC("DISPLAY", NULL, NULL, NULL);

nVertRes = GetDeviceCaps(hdc, VETREZ); nHorzRes = GetDeviceCaps(hdc, HORZRES);

DeleteDC(hdc);

Использование физических координат неудобно по двум причинам.

Рисунок 1. Физическая система координат монитора

Во-первых, разрешение зависит от типа видеоконтроллера, а во-вторых, что самое главное, от видеоконтроллера зависит отношения высоты к ширине пиксела. Потому, если вы попробуете в физической системе координат нарисовать квадрат, например 50 х 50 пикселов, то, в общем случае, вы получите прямоугольник. По той же причине вместо окружности получится эллипс. Избежать этих неприятностей помогает логическая система координат.

2 Логическая система координат

Приложение может использовать несколько логических координат. Но постарайтесь не использовать более одной, так как в них очень легко запутаться. Здесь можно использовать любое направление координатных осей. можно выбирать начало системы координат.

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

int SetMapMode(

HDC,                    // дескриптор контекста отображения

int nMapMode                 II режим отображения

);

Функция возвращает режим отображения установленный ранее.

Параметр nMapMode может принимать одно от следующих значений:

Режим отображения nMapMode

Направление оси X

Направление оси Y

Размер одной логической единицы

V

MM_TEXT

Вправо

Вниз

1 пиксел (физическая система координат)

MM_LOMETR1C

Вправо

Вниз

0,1 мм.

MM_HIMETRIC

Вправо

Вниз

0,01 мм.

MM_LOENGLISH

Вправо

Вниз

0,01 дюйм.

MM H1ENCL1SH

Вправо

Вниз

0,001 дюйм

MM_TWIPS

Вправо

Вниз

1/1440 дюйма

MM _ISOTROPIC

Можно выбирать

Можно выбирать

Произвольный, одинаковый для осей Х и Y

MM_ANISOTROPIC

Можно выбирать

Можно выбирать

Произвольный, может быть разный для осей Х и Y

Функция GetMapMode может в любой момент определить текущий режим отображения:

int WINAPI Gc(MapMode(

HDC hdc                     II дескриптор контекста отображения

);

3 Преобразование координат

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

xWindow, yWlmlow логические координаты точки

xWinOrg,. yWinOrg, –- начало логической системы координат

, - отношения, определяющие масштаб изображения по координатным осям

xViewporl, yViewport физические координаты точки к пикселах

xVewOrg. yViewOrg - начало физических координат

6 Режимы отображения

6.1 Режим ММ_ТЕХТ

Этот режим установлен по умолчанию. Формулы преобразования упрощаются и принимают вид:

Как видно, в режиме ММ_ТЕХТ приложение может изменить начало физической и лошческой систем координат. Для этого служат соответственно функции:

BOOL SetViewportOrgEx(

НDC hdc,                    //дескриптор контекста отображения

int nXOrigin,                II новое значение для sWinOrg

 int nYOrigin,               II новое значение для yWlnOrg,

LPOINT Ippt                 II указатель на структуру POINT

);

BOOL SetWindowOrgEx (

НDC hdc,                     //дескриптор контекста отображения

Int xWinOrg,                  II новое значение для xWinOrg

Int yWinOrg,                  II новое значение для yWinOrg

LPOINT Ippt                 II указатель на структуру POINT

);

В структуру lppt записываются старые координаты начала системы координат.

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

По смыслу переменные xWinOrg, yWinOrg логические координаты, они могут быть только отрицательными.

Рисунок 2. Вид координатной системы после переключения в метрический режим

Рисунок 3. Метрическая система координат.

6.2 Метрические режимы отображения MM_LOMETRIC, MM LOENGLISH, MM_HIENGLISH и MM_TWIPS.

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

int SetMapMode(

HDC hdc,                    // дескриптор контекста отображения

int nMapMode                // режим отображения

);

система координат примет очень странный вид (рис. 2). Координаты у могут быть только отрицательными.

Перед перемещением начала координат, следует определить размеры клиентской части окна; cxClient, cyClient, а затем вызвать уже знакомую функцию SetViewportOrg. Для перемещения начала координат в нижний левый угол параметры функции будут следующими:

SetViewportOrg (hdc, 0, cyClient);

Внимание! CyClient>0, так как мы переносим начало физической системы координат. Система координат примет привычный вид.

6.3 Режимы MM_ISOTROPIC, MM_ANISOTROPIC.

Эти режимы, помимо прочего, допускают изменение масштаба координатных осей и их ориентации. С этой целью используются функции:

BOOL SetWindowExtEx(

HDC hdc,                    //дескриптор контекста отображения

int xWinExt,                  // новое значение для xWinExt

int yWinExt,                  // новое значение для yWinExt

LPSIZE IpSize               // предыдущий размер области просмотра

);

BOOL SetViewpor(ExtEx(

HDC hdi;                    // дескриптор контекста отображения

int xViewExt,                  // новое значение для xViewExt

int yViewExt,                  // новое значение для yViewExt 

LPSIZE IpSize                // предыдущий размер области просмотра

);

IpSize является указателем на структуру SIZE, в которую помещаются размеры предыдущей области просмотра. Если IpSize NULL, ничего не возвращается.

В качестве примера, создадим систему координат с началом отсчета в нижнем левом углу, причем ось х - направлена слева направо, а ось у – снизу вверх. Высота и ширина должны изменяться в диапазоне О...32767 (32767 -максимально возможное число при 16 разрядной системе). Применим одинаковый масштаб по осям с использованием изотропного режима отображения (MM_ISOTROPIC).

SetMapMode (hdc. MM_ISOTROPIC);

SetWindowExtEx (hdc, 32767, 32767, NULL);

SetViewportExtEx (hdc, cxClieni, -cyClienI, NULL);

SetViewportOrg (hdc. 0. cyClienI);

Рисунок 3. Изображение квадрата и круга при различных соотношениях высот, к ширине окна в изотропном а), b) и анизотропном с) режимах

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

7 Рисование геометрических фигур

Не все драйверы устройств вывода могут рисовать перечисленные ниже геометрические объекты. Поэтому, перед рисованием, хорошее приложение Windows должно определить возможность рисования необходимых ему геометрических объектов и, в случае невозможности их отображения конкретным устройством вывода (не обязательно драйвера монитора, который чаще всего сможет нарисовать любые фигуры), выдать соответствующее предупреждение и прекратить работу. Для этих целей служит функция GetDeviceCaps (см. HELP).

7.1 Рисование точки

Эта функция имеет следующий прототип;

COLORREF SetPixel(

НDC hdc,                    // контекст отображения

int nXpos,                   //х-координата точки

int nYPos,                    //у - координата точки

COLORREF cllrref    // цвет точки

);

Параметры nXpos и nYPos определяют координаты точки в установленном Вами режиме отображения для

контекста hdc.

Для конструирования цвета точки в формате COLORREF в файле wlndows.h имеется макрокоманда RGB. Используя ее, мы можем рисовать точки следующим образом:

SetPixel(hdc, 0, 0, RGB(255, 0, 0));      //точка красного цвета в начале координат

SetPixel(hdc, 0, 0, RGB(0, 0, 255));      //точка синего цвета в начале координат

Se(Pixel(hdc, 0, 0. RGB(255, 255, 255)); //точка белою цвета н начале координат

 SetPixel(hdc, 0, 0, RGB(100, 100, 100)); //точка серого цвета в начале координат

Таким образом, вы можете задать любой из 16 миллионов цветов. Но возможно вам это и не удастся. Функция SetPixel возвращает цвет, который был на экране до момента рисования Вами точки. Цвет возвращается в формате COLORREF.

Имеется функция, возвращающая цвет точки окна в формате COLORREF;

COLORREF GetPixel (НDC hdc, int пХроs, int n YPos);

Определены три макрокоманды, позволяющие выделить три цветовых компоненты из формата COLORREF.

Это GetRVaIue(rgb), GetGValue(rgb), GetBValue(rgb).

Ниже приводиться фрагмент кода, определяющий цветовые компоненты точки:

COLORREF color;

int r, g, h;

color = GetPixel (hdc, 0,0);             // цвет точки в начале координат в формате COLORREF

r  = GetRValue(color);                 // интенсивность красной компоненты

g = GetGValue(color);                 // интенсивность желтой компоненты

b = GctBValue(color);                 // интенсивность голубой компоненты

7.2 Рисование линий

7.2.1 Позиция пера

Перед рисованием линий очень часто возникает необходимость установить перо в заданную позицию. Для этой цели можно использовать функцию MoveToEx.

BOOL MoveToEx(

HDC hdc,                     II контекст отображения

int X,                            // х-координата новой позиции пера

int У,                             //у-координата новой позиции пера

LPP0INT IpPoint            //адрес структуры для записи предыдущей позиции пера

);

В структуру типа LPP0INT, на которую указывает IpPoint, после возврата из функции записываются старые координаты пера. Пример фрагмента кода:

LPP0INT pos;

int х. у;

MoveToEx(hdc, 10, 10, pos);          // помещаем перо в точку с координатами (10, 10)

х = pos.x;                             II старая х - координата пера

у = pos.y,                             II старая у - координата пера

7.2.2 Рисование прямой линии

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

BOOL LineTo(

HDC hdc,                    II контекст отображения

int nXEnd,                   II координата X конца линии

lot nYEnd                    II координата Y конца линии

);

Функция рисует прямую с началом в текущей позиции пера и концом в точке nXEnd, nYEnd. Перед рисованием прямой необходимо с помощью функции MoveToEx установить перо в начальную позицию.

7.2.3 Рисование ломаной линии

Нарисовать ломаную линию можно с помощью функции PolyLine, прототип этой функции:

BOOL Polyline(

HDC hdc,                            II контекст отображения

CONST POINT *Ippt,         II указатель на массив структур POINT

int cPoints                           II размер массива

);

Пример:

POINT CoordPolyLine[3];

CoordPolyLine[0]. х = 10;   CoordPulyline[0].у = 10;

CoordPolyLine[1].x = 20; CoordPoIyLine[1].у = 25,

CoordPolyLine[2].х = 20; CoordPolyLine[2].у = 55;

PolyLine (hdc, CoordPolyLine, 3 );

7.2.4 Рисование дуги эллипса

Это единственная функция GDI позволяющая рисовать кривые высокого порядка.

BOOL Arc (

HDC hdc                     II дескриптор контекста отображения

int nxLeft, int nyTop,            II координаты верхнего левого угла

int nxRighl. int nyliotlom,        II координаты правого нижнего угла

int nxSlcirl, Int nySlurl,           II координаты начала дуги

Int nxEnd, Int nyEnd            II координаты конца дуги

);

Рисунок 4. Дуга эллипса.

На рис. 4 представлены все необходимые пояснения к параметрам функции Arc. Дуга рисуется против часовой стрелки. Координаты центра эллипса, при необходимости можно вычислить по очевидным формулам:

хС •= (nxLeft + nxRiRht)/2:

уС = (nyTop + пуВо11от)/2;

7.2.5 Настройка атрибутов контекста отображения для рисования линий

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

HPEN CreatePen (

int fnPenSlyle,                 II стиль пера 

int nWidth,                   II ширина пера

COLORREF clrref           // цвет пера

);

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

Стиль линии

Внешний вид

Описание

PS_SOLID

PS_DASH

PS_DOT

PS_DASHDOT

PS_DASHDOTDOT

PS_NULL

PS_INSIDEFRAME

______________

–  –  –  – – –  –  –

……………………

– . – . – . – . – .– .–

_______________

Сплошная

Штриховая

Пунктирная

Штрихпунктирная, одна точка на одну линию Штрихпунктирная, две точки на одну линию Невидимая

Единицы измерения для параметра nWidfh зависят от режима отображения. Это могут быть пикселы, миллиметры и дюймы. Но линии типа PS_DASH, PS_DOT, PS_DASHDOT и PS_DASHDOTDOT могут быть толщиной только 1 пиксел. Для рисования таких линий произвольной толщины служит функция LineDDA (см. HELP).

Разница в стилях PS_SOLID и PS_INSIDEFRAME показана   на рис.  5

Концы толстых линий Windows рисует закругленными, так, как это показано на рис.  При необходимости нарисовать толстую линию с прямыми углами, придется воспользоваться функцией рисования закрашенного прямоугольника.

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

После создания пера, его необходимо выбрать в контекст отображения с помощью макрокоманды SeIectPen, а затем рисовать с использованием функций MoveToEx и LineTo.

Рисунок  Стили PS_SOLID и PS_INSIDEFRAME

После окончания рисования созданным Вами пером, строго необходимо его удалить, с помощью макрокоманды DeletePen при этом освобождается память. Отсутствие удаления пера после его использования, очень опасная ошибка, приводящая, в конце концов, к краху системы!

Перед удалением пера, следует выбрать в контекст отображения одно из встроенных перьев (например, то, которое использовалось раньше). Не забывайте, что Windows - мультизадачная система. Не сделав выбор в контекст пера, используемого ранее, Вы можете навредить другому приложению!

Нельзя удалять перо, выбранное в контекст отображения!

Нет никакого смысла в удалении встроенных перьев!

Использование макрокоманд SelectPen и DeletePen , будет показано ниже на примерах.

7.2.6 Выбор режима фона

Режим фона имеет смысл устанавливать при рисовании пунктирных и штрихпунктирных линий. Существует два режима:

OPAQUE        - непрозрачный режим (действует по умолчанию) TRANSPARENT   - прозрачный режим

В режиме OPAQUE промежутки пунктирных линий за-крашиваются цветом, выбранным в контекст отображения. В режиме TRANSPARENT промежутки не закрашиваются (рис. 6.).

Чтобы выбрать в контекст отображения цвет фона, необходимо использовать функцию SetBkColor:

COLORREF SetBkColor (HDC hdc, COLORREF clrref)',

Для установки режима фона предназначена функция SetbkMode:

int SetDkMode (11DC hdc, int fnBkMode)-,

Парамсчр fnBkMode может принимать одно из двух значений, или OPAQUE или TRANPARENT.

Рисунок 6. Режимы OPAQUE и TRANSPARENT


7.2.7 Выбор режима рисования

При рисовании на бумаге цвет линии не зависит от цвета бумаги, он определяется только цветом пера. По-другому дела обстоят при рисовании на мониторе, здесь зависимость цвета линии от цвета пера и цвета окна может быть очень сложной. Эта зависимость определяется выбором режима рисования, который устанавливается функцией lntSetROP2:

int SetROP2 (

HDC hdc,                // контекст отображения

int fnDrawMode         II режим рисования

);'

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

Режим рисования

Формула

1 ibct пиксела

R2_COPYPEN

P

Соответствует (равен) цвету пера,

R2_BLACK

0

Черный

R2_WHITE

1

Белый

R2_NOP

D

Перо ничего не рисует

R2_NOT

~D

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

R2_NOTCOPYPEN

~P

Получается инвертирование цвета пера

R2_MASKPEN

P&D

Комбинация компонентов цветов имеющихся в цвете пера и подложки

R2_NOTMASKPEN

"(P&D)

Инверсия предыдущего значения

R2_MERGEPEN

P|D

Комбинация компонентов цветов имеющихся в цвете пера и подложки

R2_NOTMERGEPEN

-(P|D)

Инверсия предыдущего значения

R2_XORPEN

PAD

Операция ИСКЛЮЧАЮЩЕЮ ИЛИ между компонентами цвета пера и подложки

R2_NOTXORPEN

~(P"D)

Инверсия комбинации инверсии цвета подложки и цвета пера

R2_MA.SKNOTPEN

P&D

Комбинация цвета подложки и инверсии цвета пера

R2_IVIASKPENNOT

P& D

Комбинация цвета пера и инверсии цвета подложки

R2_MERGENOTPEN

P|D

Комбинация цвета подложки и инверсии цвета пера

R2_MERGEPENNOT

P|~D

Комбинация цвета пера и инверсии цвета подложки

Если перо и подложка черно-белые, то результат легко предсказать.

Очень интересен режим R2_NOT при использовании, которого на черном фоне будет нарисована белая линия, а на белом фоне черная линия.

7.3 Рисование замкнутых фигур

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

7.3.1 Рисование прямоугольника

Это наиболее простая функция. Ее прототип:

BOOL Rectangle (

HDC hdc,                     // дескриптор контекста отображения

int nxTL,                     // координата х верхнего левого угла

int nyTL,                      // координата у верхнего левого угла

int nxBR,                     II координата х нижнего правого угла

int nyBR                      II координата у нижнего правого угла

);

Внутренность прямоугольника может быть закрашена или заштрихована, кроме того, его можно закрасить с помощью любого битовою изображения размером 8х8 пикселов.

С помощью функции RoundRect можно рисовать прямоугольники со скругленными углами. В зависимости от кисти, выбранной в контекст, внутренность прямоугольника может быть закрашена. Для закраски используют функцию:

int FiIIRect (

HDC hdc,                    II идентификатор контекста отображения

CONST RECT *lрrс,          II указатель на структуру RECT


HBRUSH hbrush             // идентификатор кисти для закрашивания

};

Для закрашивания границы используют функцию:

int FrameRect (

HDC hdc,                   II дескриптор контекста отображения

CONST RECT *lprc,          II указатель на структуру

RECT HBRUSH hbrush             II идентификатор кисти для закрашивания

);

Рамка всегда рисуется толщиной в один пиксел.

7.3.2 Рисование эллипса

Для рисования эллипса используют функцию Ellipse.

BOOL Ellipse<

HDC hdc,      II дескриптор контекста отображения

int nxTl,       // координата х верхнего левого угла

int nyTL,       II координата у верхнего левого угла

int nxBR,       II координата х нижнего правого угла

int nyBR       II координата у нижнего правого угла

);

Рис. 7 поясняет параметры функции Ellipse.

Сегмент эллипса (рис. 5 8) рисуется функцией Chord.

BOOL Chord(

HDC hdc                     II дескриптор контекста отображения

int nxLeft. int nyTop,          II верхний левый угол

int nxRighl, int nyBottom,        II правый нижний угол

int nxSlart, int nySlart          II начало дуги

int nxEnd, int nyEnd           II конец дуги

Рис. 8 поясняет параметры функции Chord.

Сектор эллипса (рис. 8) рисуется функцией Pie.

BOOL Pie(

HDC hdc,                            //дескриптор контекста отображения

int nxieft, Int nyTop,           II верхний левый угол

int nxRighl, int nyBottom,   // правый нижний угол

int nxStart, int nySlarl,        II начало дуги

int nxEnd. intnyEnd          //конец дуги

Рис. 9 поясняет параметры функции Pie.


Рисунок 8. Рисование сегмента эллипса.

Рисунок 9. Рисование сегмента эллипса.

7.3.3 Рисование многоугольников

Для рисования многоугольников служит функция Polygon.

BOOL Polygon (

HDC hdc,                    II дескриптор контекста отображения

CONST POINT *lppt,          II указатель на массив структур POINT 

int cPoinis                    II размер массива структур POINT

};

Параметры функции Polygon no своему смыслу аналогичны параметрам функции Polyline. Функция Polygon не использует текущую позицию пера и не изменяет ее после завершения работы.

В массиве структур POINT каждая вершина может быть указана только один раз. Функция Polygon автоматически замыкает линию, образующую многоугольник.


7.3.4 Выбор кисти

Для закрашивания внутренней области замкнутых фигур, можно использовать как встроенные кисти, так и создавать свои.

Для выбора встроенных кистей необходимо пользоваться макрокомандой GetStockBrush, определенной в файле windows.h следующим образом:

#define GetStockBrush(i) ((НBRUSH)GetStockObject(i) В качестве параметра для этой макрокоманды можно использовать следующие значения:

Значение i

Oписание

BLACK_BRUSH

WHITE_BRUSH

GRAY_BRUSH

LTCRAY_BRUSH

DKGRAY_BRUSH

NULL_BRUSH

HOLLOW_BRUS H

Кисть черного цвета

Кисть белого цвета

Серая кисть

Светло-серая кисть

Темно-серая кисть

Бесцветная кисть, которая ничего не закрашивает Синоним для NULL BRUSH

Прежде чем использовать полученную кисть, ее необходимо выбрать в контекст отображения. Это можно сделать, используя макрокоманду SelectBrush:

#define SelectBrush(hdc, hbr) ((HBRUSH)SelectObject((hdc), (HGDIOBJ)(HBRUSH)(hbr)))

Для создания цветной кисти необходимо воспользоваться функцией CreateSolidBrush:

HBRUSH CreateBrush (COLORREF cirref);

После использования кисти ее следует удалить, для освобождения памяти, не следует забывать, что перед удалением кисти, необходимо выбрать в контекст старую кисть. Для удаления кисти служит определенная в файле windows.h макрокоманда DeleteBrush.

#define DeleteBrush(hbr) DeleteObject((HGDIOBJ)(HBRUSH)(hbr))

Для штриховки внутренней области необходимо создать соответствующую кисть. HBRUSH CreateHatchBrush(int fnStyle, COLORREF clrref);

Параметр clrrеl определяет тип штриховки.

Стиль штриховки

Описание

HS_BDIAGONAL

HS_FDIAGONAL HS_DIAGCROSS

HS_HORIZONTAL

HS_VERTICAL

HS_CROSS

Штриховка под углом а = 45*

Штриховка под углом а = 135"

Двойная штриховка под углом а = 45" и Р = 135*

Штриховка горизонтальными линиями

Штриховка вертикальными линиями

Двойная штриховка горизонтальными и вертикальными линиями

Очень легко создать кисть со своим рисунком штриховки создав кисть из битового изображения размером 8х8 пикселов. Используя для этих целей функцию

HBRUSH CreatePatternBrush (HBITMAP hBilmap);

Ниже представлено приложение Draw, демонстрирующее некоторые графические возможности GDI.

Листинг 1.

Файл RDraw.cpp

//======================================================================

// Приложение Rdaw

// Демонстрация использования функции рисования графических изображений

//=====================================================================

#define STRICT

#include <windows.h>

#include <windowsx.h>    

// Прототипы функций

BOOL InitApp (HINSTANCE);

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

void DrawLines(HDC);        // Рисование линий

void DrawPolyline(HDC);      // Рисование полилиний

void DrawArc(HDC);          // Рисование дуги эллипса

void DrawRectangles(HDC);   // Рисование прямоугольников

void DrawPolygon(HDC);      // Рисование полигонов

void DrawEllipse(HDC);       // Рисование эллипса

void DrawCircle(HDC);        // Рисование окружности

void DrawPie(HDC);          // Рисование сектора эллипса

void DrawChord(HDC);       // Рисование сегмента эллипса

// Имя класса окна

CCHAR szClassName[] ="DrawClass";

// Заголовок окна

CCHAR szWindowTitle[]="Приложение Rdraw";

// Размеры внутренней области окна

short cxClient, cyClient;

// Код выбранной строки меню "Draw"

int nFigures=0;

// Режим фона

int nBkMode=0;

// Код растровой операции

int nROP2 = R2_COPYPEN;

// ==================================================================

// Функция WinMain

//===================================================================

int WINAPI

WinMain(HINSTANCE hinstance,

 HINSTANCE hPrevlnstance,

 LPSTR IpszCmdLine,

 int   nCmdShow)

{

MSG msg;    // Структура для работы с сообщениями

HWND hwnd; // Идентификатор главного окна приложения

// Определяем наличие загруженной копии приложения

if (FindWindow(szClassName, szWindowTitle))

 return FALSE;

// Инициализируем приложение

if(!InitApp(hinstance))

 return FALSE;

// Создаем главное окно приложения

hwnd = CreateWindow(

szClassName,                // имя класса окна

szWindowTitle,              // заголовок окна

WS_OVERLAPPEDWINDOW,  //стиль окна

CW_USEDEFAULT,              // задаем размеры и расположение

CW_USEDEFAULT,             // окна, принятые по умолчанию

CW_USEDEFAULT,

CW_USEDEFAULT,

0, 0, hinstance, NULL);

if (!hwnd) return FALSE;

// Рисуем главное окно максимального размера

ShowWindow(hwnd, SW_MAXIMIZE);

UpdateWindow(hwnd);

// Запускаем цикл обработки сообщений

while(GetMessage(&msg, 0, 0, 0))

{

 DispatchMessage(&msg);

}

return msg.wParam;

}

//===================================================================

// Функция InitApp // Выполняет регистрацию класса окна

//===================================================================

BOOL InitApp(HINSTANCE hinstance)

{

ATOM aWndClass;   // атом для кода возврата

WNDCLASS wc;      // структура для регистрации класса окна

// Записываем во все поля структуры нулевые значения

memset(&wc, 0, sizeof(wc));

// Подключение меню

wc.lpszMenuName  = NULL;

wc.style         = CS_HREDRAW | CS_VREDRAW;

wc.lpfnWndProc   = (WNDPROC) WndProc;

wc.cbClsExtra    = 0;

wc.cbWndExtra    = 0;

wc.hInstance     = hinstance;

wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);

wc.hCursor       = LoadCursor(NULL, IDC_ARROW);

wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);

wc.lpszClassName = (LPSTR)szClassName;

aWndClass = RegisterClass(&wc);

// Регистрация класса

return (aWndClass !=0);

}

//=================================================================

// Функция WndProc

//=================================================================

LRESULT CALLBACK

WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM IParam)

{

HDC hdc;

PAINTSTRUCT ps;

switch (msg) {

// При изменении размеров окна сохраняем новые значения ширины и высоты

 case WM_SIZE:

  // Размер клиентской части окна по горизонтали

  cxClient = LOWORD(IParam),

  // Размер клиентской части окна по верикали

  cyClient = HIWORD(IParam);

  return 0;

 // Рисование в окне

 case WM_PAINT:

  hdc = BeginPaint(hwnd, &ps);

  // Устанавливаем метрическую систему координат

  // с началом координат в левом нижнем углу окна.

  SetMapMode(hdc, MM_LOMETRIC);

  SetViewportOrgEx(hdc, 0, cyClient, NULL );

     // Устанавливаем режим отображения.

  SetBkMode(hdc, nBkMode);

  // Устанавливаем растровую операцию.

  SetROP2(hdc, nROP2);

  DrawLines(hdc);      // прямые линии

 /*

  DrawArc(hdc);       // дуга окружности

  DrawRectangles(hdc); // прямоугольники

  DrawPolygon(hdc);   // полигон

  DrawEllipse(hdc);    // эллипс

  DrawCircle(hdc);     // окружность

  DrawPie(hdc);       // сектор эллипса

  DrawChord(hdc);     // сегмент эллипса

  DrawPolyline(hdc);   // полилиния

  */

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

  EndPaint(hwnd, &ps);

  return 0;

case WM_DESTROY:

 PostQuitMessage(0);

 return 0;

default:

 break;

}

return DefWindowProc(hwnd, msg, wParam, IParam);

}

Файл RDrawfn.cpp

//===================================================================

// Файл Rdrawfn.cpp

//===================================================================

//-----------------------------

// Функции для приложения Rdraw:

//------------------------------

# define STRICT

# include <windows.h>

# include <windowsx.h>

// Размеры внутренней области окна

extern short cxClient, cyClient;

//-------------------------------------------------

//  DrawLines

// Рисование линий различной толщины и стиля

//--------------------------------------------------

void DrawLines(HDC hdc)

{

HPEN hpenW10, hpenW50;

HPEN hpenDot, hpenDash, hpenDashDot, hpenOldPen;

 

// 1. Создание перьев

//            1.1. перо толщиной 1 мм.

hpenW10 = CreatePen(PS_SOLID, 10, RGB(0,0,0));

//            1.2. перо толщиной 5 мм.

hpenW50 = CreatePen(PS_SOLID, 50, RGB(0,0,0));

//            1.3. пунктирное перо.

hpenDot = CreatePen(PS_DOT,  0, RGB(0,0,0));

//            1.4. штриховое перо.

hpenDash = CreatePen(PS_DASH, 0, RGB(0,0,0));

//            1. штрихпунктирное перо

hpenDashDot = CreatePen(PS_DASHDOT, 0, RGB(0,0,0));

// 2. Рисуем две линии различной толщины пером, находящиеся

// в контексте отображения.

//            2.1. помещаем перо в начальныю позицию

MoveToEx(hdc, 100, 100, NULL);

//            2.2. рисуем линию

LineTo(hdc, 600,100);

//            2.3. выводим поясняющий текст

TextOut(hdc, 700,100,

 "PS_SOLID. Сплошная, толщиной 1 пиксел.", 38);

// 3. Перед рисованием различными перьями, запоминаем перо

// находившееся в контексте отображения и одновременно

// выбираем перо толщиной 1 мм.

hpenOldPen = SelectPen(hdc, hpenW10);

MoveToEx(hdc, 100, 200, NULL);

LineTo(hdc, 600, 200);

TextOut(hdc, 700, 200, "PS_SOLID. Сплошная, толщиной 1 мм.", 34);

// 4. Перебираем созданные нами перья

SelectPen(hdc, hpenW50);

MoveToEx(hdc, 100, 300, NULL);

LineTo(hdc, 600, 300);

TextOut(hdc, 700, 300, "PS_SOLID. Сплошная, толщиной 5 мм.", 34);

SelectPen(hdc, hpenDot);

MoveToEx(hdc, 100, 400, NULL);

LineTo(hdc, 600, 400);

TextOut(hdc, 700, 400, "PS_DOT.  Пунктирная толщиной  1  пиксел.", 40);

SelectPen(hdc, hpenDash);

MoveToEx(hdc, 100, 500, NULL);

LineTo(hdc, 600, 500);

TextOut(hdc, 700, 500, "PS_DASH. Штриховая толщиной 1 пиксел.", 36);

SelectPen(hdc, hpenDashDot);

MoveToEx(hdc, 100, 600, NULL);                                

LineTo(hdc, 600, 600);

TextOut(hdc, 700, 600, "PS_DASHDOT. Штрихпунктирная толщиной 1 пиксел.", 46);

TextOut(hdc, 700, 800, "Для тренировки, попытайтесь использовать цвет.", 46);

//  Выбираем старое перо в контекст отображения

SelectPen(hdc, hpenOldPen);

// 6. Удаляем созданные нами перья

DeletePen(hpenW10);

DeletePen(hpenW50);

DeletePen(hpenDot);

DeletePen(hpenDash);

DeletePen(hpenDashDot);

}

//----------------------

// DrawPolyLine

// Рисование полилинии

//----------------------

void DrawPolyline(HDC hdc)

{

// Массив координат точек излома полилинии

POINT ptPoints[]=

{

 {10, 10}, {100,310},

 {40, 300}, {300, 15},

 {135,340}, {113, 125},

 {250, 137}, {300, 300},

};

// Рисуем ломаную линию

Polyline(hdc, ptPoints, sizeof ptPoints / sizeof ptPoints[0]);

}

//------------------------------

// DrawArc

// Рисование дуги эллипса

//------------------------------

void DrawArc(HDC hdc)

{

HPEN hpenW10, hpenOldPen;

// Создаем перо 1 мм

hpenW10 = CreatePen(PS_SOLID, 10, RGB(0,0,0));

// Выбираем созданное перо в контекст отображения и

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

// по умолчанию.

hpenOldPen = SelectPen(hdc, hpenW10);

// Рисуем дугу

Arc(hdc,

  1200, 600,    // верхний левый угол прямоугольника

  1900, 100,    // нижний правый угол прямоугольника

  1750, 650,    //начало

  1850, 0);    //конец

// Выбираем старое перо в контекст отображения

SelectPen(hdc, hpenOldPen);

// Удаляем созданное перо DeletePen(hpenW10);

}

//---------------------------

// DrawRectangles

// Рисование прямоугольников

//----------------------------

void DrawRectangles(HDC hdc)

{

HPEN hpenW10, hpenOldPen;

HBRUSH hbrush, hbrushOldBrush;

POINT pPoint[2];

RECT rect={350, 500, 400};

// Рисуем прямоугольник вокруг внутренней области окна.

// Так как установлен метрический режим отображения, а

// размеры окна, передаваемые вместе с сообщением WM_SIZE,

// выражены в пикселах, выполняем преобразование физических

// координат в логические

pPoint[0].x = 0;

pPoint[0].y = cyClient;

pPoint[1].x = cxClient;

pPoint[1].y = 0;

DPtoLP(hdc, pPoint, 2);

// Создаем перо толщиной 1 мм и выбираем его в контекст отображения

hpenW10 = CreatePen(PS_SOLID, 10, RGB(0,0,0));

hpenOldPen = SelectPen(hdc, hpenW10);

// Рисуем прямоугольник

Rectangle(hdc, pPoint[0].x, pPoint[0].y, pPoint[1].x, pPoint[2].y);

// Выбираем серую кисть

hbrush = GetStockBrush(GRAY_BRUSH);

hbrushOldBrush = SelectBrush(hdc, hbrush);

// Рисуем прямоугольник закрашенный серым цветом

Rectangle(hdc, 100, 500, 300, 50);

// Создаем и выбираем кисть для штриховки

hbrush = CreateHatchBrush(HS_DIAGCROSS, RGB(0,0,0));

SelectBrush(hdc, hbrush);

// Рисуем заштрихованный прямоугольник

Rectangle(hdc, 50, 300, 500,100);

// Выбираем старое перо и кисть

SelectPen(hdc, hpenOldPen);

SelectBrush(hdc, hbrushOldBrush);

// Заштриховываем прямоугольную область кистью

// brush, которая НЕ ВЫБРАНА в контексте

FillRect(hdc, &rect, hbrush);

// Рисуем прямоугольник со скругленными углами

RoundRect(hdc, 550, 200, 800, 100, 50, 50);

//   Удаляем созданные нами перо и кисть

DeletePen(hpenW10);

DeleteBrush(hbrush);

}

//---------------------------

// DrawPolygon

// Рисование прямоугольника

//------------------------------

void DrawPolygon(HDC hdc)

{

HBRUSH hbrush, hbrushOldBrush;

int nOldPolyFillMode;

// Координаты вершин первого многоугольника

POINT ptPoints1[]=

{

 {10,  10},  {100, 310}, {40, 300},

 {300, 15},  {135, 340}, {113,125},

 {250, 137}, {300, 300}

};

POINT ptPoints2[] =

{

 {310, 10}, {400 ,310}, {340, 300},

 {600, 15}, {435, 340}, {413, 125},

 {550,137}, {600, 300}

};

// Выбираем встроенную серую кисть

hbrush = GetStockBrush(GRAY_BRUSH);

hbrushOldBrush = SelectBrush(hdc, hbrush);

// Рисуем первый многоугольник в режиме заполнения

//ALTERNATE, установленном по умолчанию

Polygon(hdc, ptPoints1,

  sizeof ptPoints1/sizeof ptPoints1[0]);

// Устанавливаем режим заполнения WINDING

nOldPolyFillMode = SetPolyFillMode(hdc, WINDING);

// Рисуем второй многоугольник

Polygon(hdc, ptPoints2,

  sizeof ptPoints2/sizeof ptPoints2[0]);

// Восстанавливаем старый режим заполнения

SetPolyFillMode(hdc,nOldPolyFillMode);

SelectBrush(hdc, hbrushOldBrush);

}

//----------------------------

// DrawEllipse               

// Рисование эллипса

//-----------------------------

void DrawEllipse(HDC hdc)

{

POINT pPoint[2];

// Эллипс будет вписан во внутреннюю область окна,

// поэтому определяем координаты углов в текущей

// (метрической) системе координат после выполнения

// преобразований.

pPoint[0].x  = 0;

pPoint[0].y = cyClient;

pPoint[1].x = cxClient;

pPoint[1].y = 0;

DPtoLP(hdc, pPoint, 2);

// Рисуем эллипс

Ellipse(hdc, pPoint[0].x, pPoint[0].y, pPoint[1].x, pPoint[1].y );

}

//------------------------------

// DrawCircle

// Рисование сектора круга

//-------------------------------

void DrawCircle(HDC hdc)

{

// Рисуем эллипс вписанный в квадрат

Ellipse (hdc, 100, 600, 600, 100);

}

//------------------------------

// DrawPie

// Рисование сектора круга

//-----------------------------

void DrawPie(HDC hdc)

{

HPEN hpenW10, hpenOldPen;

// Создаем перо и выбираем его

hpenW10 = CreatePen(PS_SOLID, 10, RGB(0,0,0));

hpenOldPen = SelectPen(hdc, hpenW10);

// Рисуем сектор круга

Pie(hdc, 100, 600, 800, 100, 650, 650,750, 0);

// Выбираем старое перо и удаляем созданное

SelectPen(hdc, hpenOldPen);

DeletePen(hpenW10);

}

//-----------------------------

// DrawChord

// Рисование сегмента круга

//-----------------------------

void DrawChord(HDC hdc)

{

HPEN hpenW10, hpenOldPen;

hpenW10 =CreatePen(PS_SOLID, 10, RGB(0,0,0));

hpenOldPen = SelectPen(hdc, hpenW10);

// Рисуем сегмент круга

Chord(hdc,100,600, 800, 100, 650, 650, 750, 0);

SelectPen(hdc, hpenOldPen);

DeletePen(hpenW10);

}


 

А также другие работы, которые могут Вас заинтересовать

71546. Дослідження мотивації українського споживача шляхом тестування цін 165.5 KB
  Проектування будь-якого товару (послуги) слід починати передусім із визначення комплексу соціально-економічних потреб людей, які необхідно задовольнити. Тому вивчення потреб потенційних покупців є основним завданням підприємств в умовах маркетингової орієнтації.
71547. Складання проекту лісових культур для Криницького лісництва ДП Бучацьке ЛГ 352.5 KB
  Завдання досліджень - вивчення наукової літератури, яка стосується теми роботи; складання методики досліджень, вибірка інформації щодо лісокультурного фонду лісництва, обґрунтування типів, технології створення лісових культур на даній ділянці.
71548. Порода английский кокер спаниель и его практическое использование 1.01 MB
  Выбрав в качестве четвероногого питомца именно спаниеля и не пожалев времени на его воспитание, вы сможете вырастить надежного и преданного друга, охотника и защитника.Несмотря на предполагаемое испанское происхождение спаниелей, Великобритания по праву считается второй родиной этой породы
71549. Особенности управления в Новгородской республике и Пскове 58.5 KB
  Современные историки по-разному оценивают вечевой строй в Новгороде. видят в вече проявление начал народоправства. Различается и периодизация истории выборных институтов и реконструкция вечевых процедур. Янин опираясь на результаты своих многолетних археологических раскопок древних городов...
71550. Казанский университет 68 KB
  Так как с начала существования отделения в нем стала преподаваться хирургия то следует считать что история кафедры хирургии в Казани начинается с 1814 года. Вначале эта кафедра была единственной на врачебном отделении на ней начиналось и заканчивалось обучение студентов хирургии.
71551. Построение пространственной модели 833.5 KB
  Нужно представить форму разрабатываемой детали как совокупность простых геометрических элементов. Все элементы должны воспроизводиться как solids-примитивы. Ими могут быть призма, цилиндр, сфера, конус, тор. Более сложные элементы нужно представить как тела, получаемые...
71553. Формування полікапроамідної текстильної нитки 25.94 KB
  Мета: Ознайомитися з формуванням полікапроамідної текстильної нитки Методи: словесний, наочний План: Технічні показники прядильної машини «Текстима-2060» Опис технологічного процесу формування нитки на машині Текстима - 2060 Матеріально-технічне забезпечення та дидактичні засоби...
71554. История становления и развития социологии как науки 191.5 KB
  Концепция постиндустриального общества Д. Изменения в экономической политической и социальной сфере общества в XVIII-XIX веках. Конт первым решил использовать научный метод для изучения общества. Он полагал что с помощью науки можно познать скрытые законы управляющие всеми обществами.