Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Visual2.doc
Скачиваний:
5
Добавлен:
07.03.2016
Размер:
3.31 Mб
Скачать

9.2. Додатки без використання архітектури «Документ-вид»

Створимо додаток без використання архітектури «Документ-Вид» з назвою example. Для цього потрібно виконати такі дії:

Запустити меню File → New.

Обрати на вкладці Projects пункт MFC AppWizard (exe), ввести ім’я проекту (рис. 9.1).

Рис. 9.1. Вибір типу створюваного проекту

На 1-му кроці треба зняти виділення Document/View architecture support? (Чи потрібна підтримка архітектури «Документ-Вид»?). На рис. 9.2 наведено основні параметри проекту, які треба ввести користувачу.

Інші кроки можна пропустити, так створюється простий додаток без використання архітектури «Документ-Вид».

В результаті отримуємо наступні класи (табл. 9.1):

Таблиця 9.1

Перелік класів додатку без використання архітектури «Документ-вид»

Назва класу

Базовий клас

Опис

CExampleApp

CWinApp

Головний клас додатку

CMainFrame

CFrameWnd

Клас головного вікна додатку

CChildView

CWnd

Клас вікна, дочірнього відносно головного вікна

CAboutDlg

CDialog

Клас вікна діалогу

Рис. 9.2. Введення основних параметрів проекту

9.2.1. Приклад додатку реєстрації wnd-класу вікна

Приклад додатку реєстрації WND-класу вікна знаходиться у папці DISK\Structure\Dchild_no_tem_0.

Як було зазначено в п. 9.1 всі вікна базуються на структурі WNDCLASS. Розглянемо роботу зі структурами типу WNDCLASS та функціями: AfxRegisterClass, AfxRegisterWndClass, SetClassLong та іншими. Створимо додаток з назвою Dchild_no_tem_0, на рисунку 9.3 зображено його основні класи.

Рис. 9.3. Схема підключення класів вікон у додатку Dchild_no_tem_0

При створенні дочірніх вікон використаємо 3 різних підходи. Щоб вікна з різними параметрами класів було легко відрізнити одне від одного ми у кожному з них задамо свій колір фону. Перше вікно буде створено на основі стандартного класу вікна (цей клас має назву «AfxFrameOrView42d»), фон вікна буде замінений функцією SetClassLong. Друге вікно створюватиметься на основі власного класу, фон вікна буде встановлено при реєстрації класу. Третє вікно також буде створено на основі свого класу, але зміна фону буде зроблена у функції PreCreateWindow.

Функція створення першого дочірнього вікна має вид:

void CMainFrame::OnChild1()

{

if(m_child2) { delete m_child2; m_child2 = 0;}

if(m_child3) { delete m_child3; m_child3 = 0;}

if(m_child1) return;

SetWindowText("Child 1");

m_child1 = new CChild1;

if (!m_child1->CreateEx(0, NULL, "",

AFX_WS_DEFAULT_VIEW, CRect(0, 0, 0, 0),

this, AFX_IDW_PANE_FIRST))

return;

CBrush * br = new CBrush(RGB(255,0,0));

SetClassLong(m_child1->m_hWnd, GCL_HBRBACKGROUND,

(long)(HBRUSH)GetStockObject(*br));

RecalcLayout();

}

На початку функції видаляємо всі інші дочірні вікна. Якщо дане вікно відкрито виходимо з функції. Встановлюємо напис заголовка вікна. Створюємо об’єкт класу CChild1. Функцією CreateEx створюється саме дочірнє вікно. У 2-му параметрі задаємо NULL, отже при створенні вікна буде задано клас звичайного стандартного вікна. Параметр AFX_IDW_PANE_FIRST потрібен для вкладених дочірніх вікон. Вікна з іншими параметрами відображатись не будуть, оскільки будуть працювати у фоновому режимі. Функцією SetClassLong можна встановити нові параметри для класу вікна, у даному випадку змінюємо колір фону на червоний.

Для роботи з другим вікном створимо функцію RegisterMyWndClass для реєстрації власного WND-класу. Через параметр name будемо давати ім’я цього класу:

bool CMainFrame::RegisterMyWndClass(CString name)

{

WNDCLASS wc={0};

HINSTANCE hInst=AfxGetInstanceHandle();

wc.lpszClassName=name;

wc.hInstance=hInst;

wc.lpfnWndProc=::DefWindowProc;

wc.hCursor=::LoadCursor(NULL,IDC_ARROW);

CBrush *br = new CBrush;

br->CreateSolidBrush(RGB(0,255,0));

wc.hbrBackground=(HBRUSH)(*br);

wc.style = CS_GLOBALCLASS|CS_DBLCLKS;

if (!AfxRegisterClass(&wc))

{

AfxThrowResourceException();

return false;

}

return true;

}

В даній функції відбувається створення вікна з зеленим фоном. Спочатку готуємо структуру wc типу WNDCLASS. Через функцію AfxGetInstanceHandle отримуємо дескриптор нашого додатку. Зв’язування структур WNDCLASS та CREATESTRUCT відбувається через параметри структур WNDCLASS.lpszClassName і CREATESTRUCT.lpszClass, які вміщують ім’я зареєстрованого WND-класу. Потім задаємо кожен параметр структури самостійно. Створюємо об'єкт класу CBrush функцією CreateSolidBrush з зеленим кольором. Завдяки функції AfxRegisterClass зареєструємо клас вікна, давши йому структуру wc. Тепер всі вікна створені на основі Windows класу з ім’ям вказаним у name будуть з зеленим фоном. У разі невдалої реєстрації класу викликаємо функцію AfxThrowResourceException, котра використовується при виникненні проблем з ресурсами.

Функція створення другого дочірнього вікна має вид:

void CMainFrame::OnChild2()

{

if(m_child1) { delete m_child1; m_child1 = 0;}

if(m_child3) { delete m_child3; m_child3 = 0;}

if(m_child2) return;

SetWindowText("Child 2");

m_child2 = new CChild2;

// AFX_WS_DEFAULT_VIEW -> WS_CHILD|WS_VISIBLE|WS_BORDER

if (!m_child2->CreateEx(0,str, "Child 2",

WS_CHILD|WS_VISIBLE|WS_BORDER,CRect(0, 0, 0, 0),

this, AFX_IDW_PANE_FIRST))

return;

RecalcLayout();

}

У цьому прикладі робимо аналогічні дії, але при створенні вікна даємо ім’я класу із змінної str, яка отримала значення "MyWndClass" у конструкторі класу CMainFrame. Там ми зареєстрували новий клас з цим ім’ям створеною нами функцією RegisterMyWndClass.

Приведемо функцію створення третього дочірнього вікна:

void CMainFrame::OnChild3()

{

if(m_child1) { delete m_child1; m_child1 = 0;}

if(m_child2) { delete m_child2; m_child2 = 0;}

if(m_child3) return;

CRect rect;

GetWindowRect(&rect);

rect.OffsetRect(20,80);

SetWindowText("Child 3");

m_child3 = new CChild3;

if (!m_child3->CreateEx(0,NULL, "Child 3",

WS_CHILD|WS_VISIBLE|WS_BORDER,CRect(0, 0, 0, 0),

this, AFX_IDW_PANE_FIRST))

return;

RecalcLayout();

}

У функції PreCreateWindow створюємо вікно на основі власного WND-класу:

BOOL CChild3::PreCreateWindow(CREATESTRUCT& cs)

{

if( !CFrameWnd::PreCreateWindow(cs))

return FALSE;

CBrush *br = new CBrush;

br->CreateSolidBrush(RGB(0,0,255));

cs.dwExStyle |= WS_EX_CLIENTEDGE;

cs.style &= ~WS_BORDER;

cs.lpszClass = AfxRegisterWndClass(

CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,

::LoadCursor(NULL, IDC_ARROW), HBRUSH(*br), NULL);

return TRUE;

}

У PreCreateWindow продемонстровано реєстрацію WND-класу за допомогою функції AfxRegisterWndClass. У якості параметрів цієї функції передаються основні параметри структури WNDCLASS – стилі класу вікна (CS_...), дескриптор курсору, дескриптор пензля, дескриптор іконки, всі інші параметри передаються по умовчанню. Головною відмінністю функції реєстрації класу вікна AfxRegisterWndClass від функції AfxRegisterClass є те, що функція AfxRegisterWndClass сама формує ім’я зареєстрованого класу та повертає його у вигляді 16-го рядку. Рядок коду програми

cs.lpszClass = AfxRegisterWndClass(

CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,

::LoadCursor(NULL, IDC_ARROW), HBRUSH(*br), NULL);

забезпечує зв’язок структури ініціалізації вікна CREATESTRUCT та структури основних властивостей вікна WNDCLASS.

Таким чином, у результаті виконання функції отримаємо вікно синього кольору.

На рис. 9.4 показано результат роботи додатку.

Рис. 9.4. Приклад роботи додатку Dchild_no_tem_0, із вікнами Child1, Child2 та Child3

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]