Dolya_po_C++
.pdfif (eventBuffer[i].Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) isRunning = false; // выход, если нажата клавиша ESC
}
else if (eventBuffer[i].EventType == MOUSE_EVENT) { // Событие левой кнопки мыши
if (eventBuffer[i].Event.MouseEvent.dwButtonState & FROM_LEFT_1ST_BUTTON_PRESSED) { if (eventBuffer[i].Event.MouseEvent.dwEventFlags == 0) {
// Выполнен однократный щелчек мыши
if (eventBuffer[i].Event.MouseEvent.dwControlKeyState == 0) {
// Управляющие клавиши не нажаты. Вычисляем «пиксельные» координаты точки щелчка x = eventBuffer[i].Event.MouseEvent.dwMousePosition.X*fontW-2;
y = eventBuffer[i].Event.MouseEvent.dwMousePosition.Y*fontH-4;
if (bInPoint[0]){rgnTek=rn1ControlPoint;rgnIndex=1;} // выделена 1-я управляющая точка else if (bInPoint[1]){rgnTek=rn2ControlPoint;rgnIndex=2; //выдел. 2-я управляющая точка if (bInPoint[0] || bInPoint[1]) {
// получить старые координаты выделенной области (точки)
GetRgnBox(rgnTek, &rgnRect); |
|
|
|
|
dx = x - rgnRect.left; |
// величина сдвига области |
по |
горизонтали |
|
dy = y - rgnRect.top; |
// величина |
сдвига области |
по |
вертикали |
FillRect(hdc, &clientRect, bkBrush); |
// полная очистка окна |
|
|
|
OffsetRgn(rgnTek, dx, dy); |
// смещение |
области |
|
|
// получить новые координаты выделенной области (точки)
GetRgnBox(rgnTek, &rgnRect); arrBez[rgnIndex].x = rgnRect.left + rgR; arrBez[rgnIndex].y = rgnRect.top + rgR; bInPoint[rgnIndex - 1] = false;
drawBezier(hdc,penBez,penLine,arrBez,rn1ControlPoint,rn2ControlPoint);
}
}
else if (eventBuffer[i].Event.MouseEvent.dwControlKeyState==LEFT_CTRL_PRESSED){
// Нажата левая CTRL и выполнен щелчек мыши.
x = eventBuffer[i].Event.MouseEvent.dwMousePosition.X*fontW+3; y = eventBuffer[i].Event.MouseEvent.dwMousePosition.Y*fontH+5;
// Проверка, что щелчек в окрестности одной из управляющих точек bInPoint[0]=PtInRegion(rn1ControlPoint,x,y);
61
bInPoint[1]=PtInRegion(rn2ControlPoint,x,y); |
|
|
if (bInPoint[0]) { |
|
|
FillRgn(hdc, rn1ControlPoint, activeBrush); |
// |
попали в область, меняем цвет |
FillRgn(hdc, rn2ControlPoint, inactiveBrush); // |
снять выделение 2-й точки |
|
} |
|
|
else if (bInPoint[1]) { |
|
|
FillRgn(hdc, rn2ControlPoint, activeBrush); |
// |
попали в область, меняем цвет |
FillRgn(hdc, rn1ControlPoint, inactiveBrush); // |
снять выделение 1-й точки |
|
} |
|
|
else { |
|
|
FillRgn(hdc, rn1ControlPoint, inactiveBrush); // |
снять выделение 1-й точки |
|
FillRgn(hdc, rn2ControlPoint, inactiveBrush); // |
снять выделение 2-й точки |
|
} |
|
|
}
}
}
}
}
delete[] eventBuffer;
}
}
}
//Функция рисования одного сегмента Безье и его многоугольника.
//Кривая рисуется пером HPEN penBez, а многоугольник пером HPEN penLine.
//POINT *arr -массив координат точек, точек всегда 4.
//HRGN rn1ControlPoint, HRGN rn2ControlPoint - дескрипторы областей управляющих точек. void drawBezier(HDC hdc, HPEN penBez, HPEN penLine, POINT *arr,
HRGN rn1ControlPoint, HRGN rn2ControlPoint)
{
const int cnt = 4; |
// для кубического сегмента Безье нужны 4 точки |
|
SelectObject(hdc, penBez); |
// |
помещаем перо кривой в контекст |
PolyBezier(hdc, arr, cnt); |
// |
рисуем один сегмент кривой Безье |
HBRUSH pntBrush=CreateSolidBrush(RGB(0,0,255)); // кисть для концевых точек кривой (не управляющих)
SelectObject(hdc, penLine); // помещаем перо ломаной в контекст
62
bigPoint(hdc, arr[0].x, arr[0].y, 5, pntBrush); // начальная точка многоугольника bigPoint(hdc, arr[cnt - 1].x, arr[cnt - 1].y, 5, pntBrush); // конечная точка многоугольника
Polyline(hdc, arr, cnt); |
|
// рисуем многоугольник Безье |
HBRUSH inactiveBrush = CreateSolidBrush(RGB(200, 200, 200)); |
||
FillRgn(hdc, rn1ControlPoint, inactiveBrush); |
// |
заливаем область 1-й управляющей точки |
FillRgn(hdc, rn2ControlPoint, inactiveBrush); |
// |
заливаем область 2-й управляющей точки |
}
// Рисуем круг с центорм в точке (x,y) радиуса r кистью brush void bigPoint(HDC hdc, int x, int y, int r, HBRUSH brush)
{
SelectObject(hdc, brush);
Ellipse(hdc, x - r, y - r, x + r, y + r);
}
На следующих рисунках показаны три различных сегмента Безье, имеющие одинаковые конечные точки и разные управляющие.
В программе созданы две вспомогательные функции. Функция bigPoint используется для рисования кругов, идентифицирующих концевые точки сегмента Безье. Функция drawBezier используется для рисования одного сегмента Безье и его многоугольника. Она принимает аргументы, необходимые для рисоавния сегмента и многоугольника Безье, назначение которых описано в комментарии к коду этой функции.
Попробуйте написать аналогичную программу для рисования кривой, составленной из двух сегментов Безье.
63
1.3 Заключение
В этом пособии мы привели описание небольшого количества функций Windows API, которые можно использовать в консольных приложениях. Значительно больше функций осталось за пределами нашего рассмотрения.
В первом параграфе мы описали «текстовые» функции работы с консолью. Во втором параграфе описали некоторые графические функции, которые, в принципе, не предназначены для работы с консолью. Помните, что основным режимом работы консольного окна является текстовый и графические возможности этого окна недостаточно функциональны. Тем не менее, все, что нами было изложено, без всяких изменений, но с некоторыми существенными улучшениями функциональности, используется в «оконных» приложениях
Windows.
Надеемся, что наше небольшое введение в графические возможности консольных приложений послужит для вас стимулом к дальнейшему знакомству с графическими возможностями «настоящих» приложений
Windows.
64