- •О.С. Зеленський
- •Розділ 1. Загальні відомості створення додатку windows
- •1.1. Створення додатку Windows за допомогою майстра AppWizard
- •1.2. Варіанти майстрів для різних проектів
- •1.3. Короткий опис sdi програми
- •1.4. Короткий опис mdi програми
- •1.5. Короткий опис простого діалогового додатку
- •Контрольні питання
- •Розділ 2. Повідомлення і команди
- •2.1. Обробка повідомлень
- •2.2. Цикли обробки повідомлень
- •2.3. Карти повідомлень
- •Контрольні питання
- •Розділ 3. Документи та види
- •3.1. Клас додатку
- •3.2. Клас головного вікна
- •3.3. Клас документа
- •3.4. Класи виду
- •Контрольні питання
- •Розділ 4. Робота з клавіатурою, мишею і меню
- •4.1. Робота з клавіатурою
- •4.2. Робота з мишею
- •4.3. Робота з меню
- •Контрольні питання
- •Розділ 5. Виведення на екран
- •5.1. Класи графічних об'єктів
- •5.2. Робота зі шрифтами
- •5.3. Робота з пензликами та малювання графічних фігур
- •5.4. Робота з пензликом
- •5.5. Робота зі скролінгом
- •5.6. Приклад роботи з таблицями
- •5.7. Малювання на екрані маніпулятором "миша"
- •5.8. Завантаження та виведення на екран бітових зображень
- •5.9. Копіювання бітових образів
- •5.10. Малювання графічних об'єктів з використанням резинових контурів та метафайлів
- •5.11. Виділення графічних об'єктів у прямокутній області
- •5.12. Універсальний приклад роботи з двовимірною графікою з використанням резинового контуру
- •5.13. Запис на диск та зчитування з диску графічних об'єктів
- •5.14. Побудова кругових діаграм і гістограм
- •5.15. Користувацький режим роботи з графікою на прикладі малювання годинника Clock
- •Контрольні питання
- •Завдання
- •Розділ 6. Друк і попередній перегляд документів
- •6.1. Вибір і налаштування параметрів друку
- •6.2. Створення контекста пристрою
- •6.3. Друк документів і бібліотека mfc
- •6.4. Масштабування
- •6.5. Друк багатосторінкового документа
- •Контрольні питання
- •Розділ 7. Робота з файлами
- •7.1. Приклад роботи з файлами на основі класів cFile, cStdioFile та потоку fstream
- •7.1.1. Робота з класом cFile
- •7.1.2. Робота з потоком fstream
- •Можливі режими доступу
- •7.1.3. Робота з класом cStdioFile
- •7.2. Серіалізація даних, клас cArchive
- •7.3. Використання реєстру в додатках
- •Контрольні питання
- •Завдання
- •Розділ 8. Діалогові вікна
- •8.1. Створення діалогового вікна та простіші елементи керування
- •8.2. Робота зі списками і комбінованими полями
- •8.3. Ускладнений приклад зі списками
- •8.4. Робота з повзунками
- •8.5. Виведення бітових матриць в діалозі та у вікні виду
- •8.6. Лінійний регулятор, лінійний індикатор, інкриментний регулятор
- •8.7. Стандартні діалоги вибору файлів, шрифтів та кольору
- •8.8. Взаємоз'вязок діалога, документа та виду при розробці додатку
- •8.8.1. Клас cDialDoc
- •8.8.2. Клас cDialView
- •8.8.3. Клас Cdlg
- •8.9. Формування вхідного документа на основі діалогу
- •Контрольні питання
- •Завдання Робота з типовими елементами керування
- •Робота зі списками і комбінованими полями
- •Список літератури
Контрольні питання
1. Яку подію оброблює функція OnChar?
2. За яких умов відбувається подія WM_CHAR?
3. Призначення функції CreateSolidCaret.
4. Призначення функцій HideCaret і ShowCaret.
5. Призначення функції SetCaretPos.
6. Призначення функції Enable.
7. Призначення функції SetCheck.
8. Призначення акселераторів.
9. Призначення події OnLButtonDown.
10. Призначення функції GetTextMetrics.
Розділ 5. Виведення на екран
5.1. Класи графічних об'єктів
При малюванні графічних об’єктів використовуються функції класу CDC. Ці функції можуть приймаюти у своїх параметрах такі об'єкти: CPoint, CRect, CPen, CBrush, CBitmap.
Для зберігання координат точок створено клас CPoint. Він містить у собі координати точки: x, y; а також деякі функції та оператори. Функція Offset переміщує поточні координати точки, а функція SetPoint встановлює нові координати. Об'єкти цього класу можуть використовуватись як параметри для функцій контексту: SetPixel, MoveTo, LineTo.
Для зберігання координат прямокутних областей використовуються об'єкти класу CRect. Об'єкти цього класу можуть використовуватись як параметри для функцій контексту: Rectangle, Ellipse, Arc, Pie, DrawText та інших.
Приклад роботи зі шрифтами, пензликами та малюванням геометричних фігур знаходиться у папці DISK\GDI\GDI1.
5.2. Робота зі шрифтами
Створимо SDI программу з назвою Graf. У функції OnDraw будемо виводити текст або графіку. Зробимо декілька режимів відображення графіки і тексту. Для їх переключення додамо 4 пункти у меню (рис. 5.1). За режим виведення буде відповідати змінна kod_graf, яку додамо у клас CGrafView. Шрифти будемо виводити різними кольорами, для цього використаємо генератор випадкових чисел, який буде працювати в залежності від змінної kol_sec, яка повертає кількість секунд, починаючи з 1970 року:
class CGrafView : public CView
{
.............................................................
public:
int kod_graf;
int kol_sec;
.............................................................
};
У конструкторі класу поставимо змінній режиму значення 0, щоб одразу при відкритті програми було пусте вікно:
CGrafView::CGrafView()
{
kod_graf = 0;
}
Вибір режимів відображення шрифтів відбуватиметься у функціях OnText та OnText2, які повязані з доданими пунктами меню:
void CGrafView::OnText()
{
kol_sec = time(0);
kod_graf = 3;
Invalidate();
}
void CGrafView::OnText2()
{
kol_sec = time(0);
kod_graf = 4;
Invalidate();
}
Ці функції схожі, вони працюють однаково. Змінна kol_sec приймає значення кількості секунд, починаючи з 1970 року, яке змінюється кожну секунду. Отже значення kol_sec буде кожен раз іншим. Далі у змінну kod_graf записується режим малювання. А функцією Invalidate() оновлюється вікно програми.
Рис. 5.1. Меню для переключення режимів виведення графіки
Додамо зміннту font_text типу LOGFONT у клас CGrafDoc:
class CGrafDoc : public CDocument
{
.............................................................
public:
LOGFONT font_text;
.............................................................
};
У цій змінній будемо зберігати параметри шрифту. Заповнимо поля цієї змінної у конструкторі класу документа:
CGrafDoc::CGrafDoc()
{
// Структура шрифта LOGFONT
font_text.lfHeight = -14;
font_text.lfWidth = 0;
font_text.lfEscapement = 0;
font_text.lfOrientation = 0;
font_text.lfWeight = FW_NORMAL;
font_text.lfItalic = 0;
font_text.lfUnderline = 0;
font_text.lfStrikeOut = 0;
font_text.lfCharSet = RUSSIAN_CHARSET;
font_text.lfOutPrecision = OUT_TT_PRECIS;
font_text.lfClipPrecision = CLIP_DEFAULT_PRECIS;
font_text.lfQuality = PROOF_QUALITY;
font_text.lfPitchAndFamily = VARIABLE_PITCH | FF_ROMAN;
strcpy(font_text.lfFaceName,"Times New Roman");
}
Приведемо код роботи із шрифтами:
void CGrafView::OnDraw(CDC* pDC)
{
CGrafDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
.............................................................
CFont font;
CFont* font_st;
CRect rect;
GetClientRect(&rect);
.............................................................
if(kod_graf==3)
{
pDoc->font_text.lfHeight = -14;
font.CreateFontIndirect(&(pDoc->font_text));
font_st = pDC->SelectObject(&font);
int i,y= 20;
//Включення генератора випадкових чисел
srand(kol_sec);
for(i = 0;i<10;i++)
{
pDC->SetTextColor(RGB(rand()%256,
rand()%256,rand()%256));
pDC->TextOut(20,y,"Привет программистам!");
pDoc->font_text.lfHeight-=5;
y+=(int)fabs(1.3*pDoc->font_text.lfHeight);
font.DeleteObject();
font.CreateFontIndirect(&pDoc->font_text);
pDC->SelectObject(&font);
}
pDC->SelectObject(font_st);
}
if(kod_graf==4)
{
int i,h,y= 20;
h = -140;
font.CreatePointFont(h,"Times New Roman");
font_st = pDC->SelectObject(&font);
// Включення генератора випадкових чисел
srand(kol_sec);
for(i = 0;i<10;i++)
{
pDC->SetTextColor(RGB(rand()%256,
rand()%256,rand()%256));
pDC->TextOut(20,y,"Привет программистам!");
h-=50;
y+=(int)fabs(1.3*h/10.);
font.DeleteObject();
font.CreatePointFont(h,"Times New Roman");
pDC->SelectObject(&font);
}
pDC->SelectObject(font_st);
}
}
Спочатку розглянемо випадок коли kod_graf дорівнює 3. Функція CreateFontIndirect з класу CFont створює шрифт на основі структури LOGFONT. А функція SelectObject з класу CDC завантажує шрифт до контексту екрану. Ця функція може завантажувати різні графічні об'єкти, які є похідними від класу CGdiObject. При виборі нового шрифта функція повертає вказівку на попередній підключений шрифт. Цю вказівку ми зберігаємо у змінній font_st для того щоб після закінчення малювання у циклі відновити шрифт, який був у контексті. Це дуже важливо тому що при закінченні наших дій з виведення власного тексту та видаленні власних шрифтів контекст екрану залишится без шрифта. Це стосується і інших об’єктів, які завантажуються в контекст, таких як CBrush (пензлик), CPen (олівець) тощо.
Далі починається цикл для виведення декількох написів. У циклі функцією SetTextColor встановлюється значення кольору виведення тексту. Функція rand() генерує випадкові числа, отже кожен рядок тексту буде різним кольором. Функція TextOut виводить текст на екран. Далі йде збільшення координати y, щоб наступні рядки були розташовані нижче попередніх. Функція DeleteObject видаляє об’єкт шрифта з памяті. Потім створюється новий шрифт, який завантажується до контексту. Результат роботи приведений на рисунку 5.2.
Рис. 5.2. Результат програми роботи зі шрифтами, створеними за допомогою функції CreateFontIndirect
В цілому алгоритм роботи функції при kod_graf==4 схожий з попереднім випадком де kod_graf==3. Відмінністю є те, що об’єкт шрифту класу CFont створюється за допомогою функції CreatePointFont. Функція CreatePointFont може створювати шрифт приймаючи 2 параметри. Перший це висота шрифту у пунктах помножена на 10. Тобто при значенні 140 отримаємо шрифт розміром 14 pt. Другий параметр – назва шрифту. Результат роботи приведено на рисунку 5.3.
Рис. 5.3. Результат програми роботи зі шрифтами, створеними за допомогою функції CreatePointFont