Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Спільні елементи керування 4 страница






{public: BOOL InitInstance(); };

 

// t1.cpp: implementation of the CMain class.

 

#include < afxwin.h>

#include < afxcmn.h>

#include " t1.h"

#include " resource.h"

 

#define ID_TREE 400002

#define NUM 5

 

CMain:: CMain()

{Create(NULL, " Використання дерева", WS_OVERLAPPEDWINDOW, rectDefault, NULL, MAKEINTRESOURCE(IDR_MENU1));

InitCommonControls();

RECT r;

r.left=r.top=30;

r.right=220; r.bottom=200;

m_Tree.Create(WS_VISIBLE | WS_CHILD | WS_BORDER | TVS_EDITLABELS |

TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT, r, this, ID_TREE);

InitTree();

}

 

BEGIN_MESSAGE_MAP(CMain, CFrameWnd)

ON_WM_PAINT()

ON_COMMAND(ID_TREE_EXPAND, OnExpand)

ON_COMMAND(ID_TREE_COLLAPSE, OnCollapse)

END_MESSAGE_MAP()

 

BOOL CApp:: InitInstance()

{m_pMainWnd = new CMain;

m_pMainWnd -> ShowWindow(m_nCmdShow);

m_pMainWnd -> UpdateWindow();

return TRUE; }

 

CApp App;

 

HTREEITEM hTreeCtrl[30];

HTREEITEM hTreeCurrent;

int i;

 

void CMain:: InitTree()

{TV_INSERTSTRUCT tvs;

TV_ITEM tvi;

tvs.hInsertAfter=TVI_LAST;

tvi.mask=TVIF_TEXT;

tvi.pszText=" One";

tvs.hParent=TVI_ROOT;

tvs.item=tvi;

hTreeCtrl[0]=m_Tree.InsertItem(& tvs);

hTreeCurrent=hTreeCtrl[0];

 

tvi.pszText=" Two";

tvs.hParent=hTreeCtrl[0];

tvs.item=tvi;

hTreeCtrl[1]=m_Tree.InsertItem(& tvs);

 

tvi.pszText=" Three";

tvs.hParent=hTreeCtrl[1];

tvs.item=tvi;

hTreeCtrl[2]=m_Tree.InsertItem(& tvs);

 

tvi.pszText=" Four";

tvs.hParent=hTreeCtrl[2];

tvs.item=tvi;

hTreeCtrl[3]=m_Tree.InsertItem(& tvs);

tvi.pszText=" Five";

tvs.hParent=hTreeCtrl[2];

tvs.item=tvi;

hTreeCtrl[4]=m_Tree.InsertItem(& tvs);

i=5;

}

 

void CMain:: OnPaint()

{CPaintDC dc(this);

TV_ITEM tvi;

char str1[40];

char str2[40];

tvi.hItem = hTreeCurrent;

tvi.pszText = str1;

tvi.cchTextMax = sizeof(str1)-1;

tvi.mask=TVIF_TEXT | TVIF_HANDLE;

m_Tree.GetItem(& tvi);

wsprintf(str2, " Current Selection %s", tvi.pszText);

dc.TextOut(2, 220, str2, strlen(str2));

}

 

void CMain:: OnExpand() {m_Tree.Expand(hTreeCurrent, TVE_EXPAND); }

void CMain:: OnCollapse() {m_Tree.Expand(hTreeCurrent, TVE_COLLAPSE); }

 

 

5.10.7 Використання елементів перегляду дерев у діалогових вікнах

У п. 5.10.2 вже зазначувалося, що послідовність створення елементів перегляду дерев має дещо інший вигляд. Насамперед, він визначається можливістю розмістити та встановити розмір вікна перегляду дерева безпосередньо у шаблоні діалогового вікна. Крім того, необхідно зв’язати ресурси діалогового вікна з відповідним йому об’єктом, також викликати функцію ініціалізації дерева елементів. Усі ці особливості стануть предметом наступної програми. В ній передбачатиметься додавання та вилучення елементів дерева, редагування текстових поміток існуючих вузлів.

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

Визначимо такий порядок побудови програми:

1) створити новий проект типу “Win32 Application” з опцією “empty project”;

2) додати у проект ресурс діалогового вікна (ідентифікатор IDD_DIALOG1) із шаблоном ресурсу дерева (ідентифікатор IDC_TREE1, встановлено властивість “Edit labels”), кнопок “Додати” для додавання вузлів (ідентифікатор IDC_BUTTON1), “Вилучити” – для вилучення вузлів дерева (ідентифікатор IDC_BUTTON2), “Редагувати” – для редагування текстових позначок вузлів (ідентифікатор IDC_BUTTON3) із загальним виглядом, наведеним на рисунку 5.13.

 

Рисунок 5.13 – Вигляд ресурсів програми для діалогового вікна з деревом

 

3) зберегти файл ресурсів та додати у проект;

4) викликати майстер класів (Class Wizard) та за його допомогою створити клас діалогового вікна CSDialog, відповідний створеним ресурсам;

5) також у Class Wizard, визначити об’єкти, відповідні ресурсу дерева (m_Tree класу CTreeCtrl) та полю редагування (m_Edit типу CEdit);

6) поставити за допомогою Class Wizard у відповідність кнопкам у діалоговому вікні такі функції: OnAdd() – для кнопки “Додати”, OnDelete() – для кнопки “Вилучити”, OnEdit() – для кнопки “Редагувати” (усі – на сторінці “Message map”, повідомлення – BN_CLICKED); також визначити обробку повідомлення WM_INITDIALOG – функцію OnInitDialog() для ініціалізації діалогового вікна (особливості подібних операцій детально описані у п. 5.7.4);

7) через поле структури проекту додати клас прикладки CApp (породжуваний з CWinApp, розташований у файлах SDialog1.h та SDialog1.cpp) та визначити в ньому функцію InitInstance() типу BOOL із таким кодом:

BOOL CApp:: InitInstance()

{CSDialog a;

a.DoModal();

return TRUE; }

8) оголосити глобальний об’єкт прикладки: CApp App;

9) у файлі SDialog.cpp змінити директиви препроцесора #include на такі:

#include < afxwin.h>

#include < afxcmn.h>

#include " resource.h"

#include " SDialog.h"

 

10) натиснувши “Alt+F7” змінити опції проекту на такі, що передбачають використання MFC, спробувати побудувати і виконати проект; у разі успішної побудови та виконання продовжити побудову, інакше – виправити помилки;

11) у клас CSDialog додати об’єкт списку зображень для зберігання пікто-грам, відповідних вузлам дерева:

 

CImageList m_treeImageList;

 

12) за допомогою редактора ресурсів створити пікторами вузлів: IDI_ICON1, IDI_ICON2, IDI_ICON2;

13) визначити глобальні змінні для зберігання вузлів дерева:

 

HTREEITEM hTreeCtrl[30]; // масив дескрипторів вузлів

HTREEITEM hTreeCurrent; // дескриптор поточного вузла

int i; // кількість вузлів дерева

 

14) у клас CSDialog додати функцію void InitTree() та визначити її код у вигляді, визначеному прикладом 5.10, здійснити виклик InitTree() з функції ініціалізації діалогового вікна OnInitDialog();

 

Приклад 5.10 – Ініціалізація дерева для діалогового вікна

 

void CSDialog:: InitTree()

{m_treeImageList.Create(16, 16, FALSE, 3, 0); // створення порожнього списку піктограм

// завантаження пікторами кожна розміром 16x16 пікселів

HICON hIcon = LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ICON1));

m_treeImageList.Add(hIcon); // додавання піктограми у список

hIcon = LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ICON2));

m_treeImageList.Add(hIcon);

hIcon = LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ICON3));

m_treeImageList.Add(hIcon);

// під’єднання списку піктограм до об’єкта дерева

m_Tree.SetImageList(& m_treeImageList, TVSIL_NORMAL);

 

TV_INSERTSTRUCT tvs;

TV_ITEM tvi;

tvs.hInsertAfter=TVI_LAST;

// встановлення стилів підтримки тексту, піктограм необраного та обраного вузлів дерева

tvi.mask=TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;

 

tvi.pszText=" One"; // текстова позначка вузла дерева

tvi.iImage=0; // код піктограми необраного вузла дерева

tvi.iSelectedImage=1; // код піктограми обраного вузла дерева

tvs.hParent=TVI_ROOT;

tvs.item=tvi;

hTreeCtrl[0]=m_Tree.InsertItem(& tvs);

hTreeCurrent=hTreeCtrl[0];

 

tvi.pszText=" Two";

tvi.iImage=0; tvi.iSelectedImage=1;

tvs.hParent=hTreeCtrl[0];

tvs.item=tvi;

hTreeCtrl[1]=m_Tree.InsertItem(& tvs);

 

tvi.pszText=" Three";

tvi.iImage=1; tvi.iSelectedImage=2;

tvs.hParent=hTreeCtrl[1];

tvs.item=tvi;

hTreeCtrl[2]=m_Tree.InsertItem(& tvs);

tvi.pszText=" Four";

tvi.iImage=1; tvi.iSelectedImage=2;

tvs.hParent=hTreeCtrl[2];

tvs.item=tvi;

hTreeCtrl[3]=m_Tree.InsertItem(& tvs);

 

tvi.pszText=" Five";

tvi.iImage=1; tvi.iSelectedImage=2;

tvs.hParent=hTreeCtrl[2];

tvs.item=tvi;

hTreeCtrl[4]=m_Tree.InsertItem(& tvs);

}

 

15) реалізувати функції OnAdd(), OnDelete(), OnEdit() у спосіб, наведений у прикладі 5.11:

 

Приклад 5.11 – Реалізація функцій додавання, вилучення та редагування вузлів

 

void CSDialog:: OnAdd()

{// TODO: Add your control notification handler code here

if(! m_Tree.GetSelectedItem())

MessageBox(" Вузол не обрано", " "); // жоден вузол дерева не обрано

else {i++; char str[20];

m_Edit.GetWindowText(str, sizeof(str));

if(strlen(str))

{hTreeCurrent=m_Tree.GetSelectedItem();

TV_INSERTSTRUCT tvs;

TV_ITEM tvi;

tvs.hInsertAfter=TVI_LAST;

tvi.mask=TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;

tvi.iImage=0;

tvi.iSelectedImage=1;

tvi.pszText=str;

tvs.hParent=hTreeCurrent;

tvs.item=tvi;

hTreeCtrl[i]=m_Tree.InsertItem(& tvs);

hTreeCurrent=hTreeCtrl[i];

InvalidateRect(NULL);

} else MessageBox(" Задайте ім’я", " "); // ім’я вузла є порожнім

}}

 

void CSDialog:: OnDelete()

{// TODO: Add your control notification handler code here

if(! m_Tree.GetSelectedItem()) // жоден вузол дерева не обрано

MessageBox(" Вузол не обрано", " ");

else {hTreeCurrent=m_Tree.GetSelectedItem();

if(! m_Tree.GetParentItem(hTreeCurrent)) // заборона вилучати корінь дерева

MessageBox(" Не можна вилучити корінь", " ");

else {m_Tree.DeleteItem(hTreeCurrent); i--;

hTreeCurrent=hTreeCtrl[i--];

InvalidateRect(NULL);

}}}

 

void CSDialog:: OnEdit()

{ // TODO: Add your control notification handler code here

hTreeCurrent=m_Tree.GetSelectedItem();

m_Tree.EditLabel(hTreeCurrent);

}

 

16) забезпечити редагування вузлів дерева також і за допомогою натискання правої клавіші миші на будь-якому з вузлів, для чого у Class Wizard вибрати ідентифікатор об’єкта дерева IDC_TREE1 та його повідомлення NM_RCLICK, що дозволить додати функцію OnRclickTree1():

 

void CSDialog:: OnRclickTree1(NMHDR* pNMHDR, LRESULT* pResult)

{ // TODO: Add your control notification handler code here

hTreeCurrent=m_Tree.GetSelectedItem();

m_Tree.EditLabel(hTreeCurrent);

*pResult = 0;

}

Функція діє так само, як і OnEdit(), аде для її використання необхідно лише обрати вузол, текстову позначку якого необхідно відредагувати. Одна тількі неприємність: результат редагування за допомогою функцій OnEdit(), OnRclickTree1() після задання нової позначки не зберігається і програма не реагує на повідомлення про початок редагування вузла та закінчення процесу редагування (TVN_BEGINLABELEDIT та TVN_ENDLABELEDIT). Для уникнення проблеми додамо обробку цих повідомлень.

17) за допомогою Class Wizard для класу CSDialog оберемо обробку повідомлення WM_NOTIFY і таким чином оголосимо функцію:

 

BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);

 

Її необхідно реалізувати у зазначений у прикладі 5.12 спосіб:

 

Приклад 5.12 – Реалізація обробки повідомлення нотифікації у діалоговому вікні

 

BOOL CSDialog:: OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)

{// TODO: Add your specialized code here and/or call the base class

TV_DISPINFO* tv_dispInfo = (TV_DISPINFO*) lParam;

if (tv_dispInfo-> hdr.code == TVN_BEGINLABELEDIT)

CEdit* pEdit = m_Tree.GetEditControl();

else if (tv_dispInfo-> hdr.code == TVN_ENDLABELEDIT)

{ if (tv_dispInfo-> item.pszText! = NULL)

m_Tree.SetItemText(tv_dispInfo-> item.hItem, tv_dispInfo-> item.pszText);

}

return CDialog:: OnNotify(wParam, lParam, pResult);

}

Як результат виконання зазначеної послідовності маємо отримати результат, наведений на рисунку 5.14.

 

Рисунок 5.14 – Вигляд діалогового вікна із реалізацією функцій дерева

 

Повний тест програми наведено у прикладі 5.13.

 

Приклад 5.13 – Текст програми із реалізацією дерева у діалоговому вікні

 

// SDialog.h: header file

class CSDialog: public CDialog

{public:

void InitTree();

CSDialog(CWnd* pParent = NULL); // standard constructor

// Dialog Data

//{{AFX_DATA(CSDialog)

enum { IDD = IDD_DIALOG1 };

CTreeCtrl m_Tree;

CImageList m_treeImageList;

CEdit m_Edit;

//}}AFX_DATA

// Overrides ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CSDialog)

protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);

//}}AFX_VIRTUAL

// Implementation

protected:

// Generated message map functions

//{{AFX_MSG(CSDialog)

virtual BOOL OnInitDialog();

afx_msg void OnAdd();

afx_msg void OnDelete();

afx_msg void OnEdit();

afx_msg void OnRclickTree1(NMHDR* pNMHDR, LRESULT* pResult);

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

class CApp: public CWinApp

{public: BOOL InitInstance();

CApp();

virtual ~CApp();

};

 

// SDialog.cpp: implementation file

#include < afxwin.h>

#include < afxcmn.h>

#include " resource.h"

#include " SDialog.h"

 

HTREEITEM hTreeCtrl[30];

HTREEITEM hTreeCurrent;

int i;

 

CSDialog:: CSDialog(CWnd* pParent /*=NULL*/): CDialog(CSDialog:: IDD, pParent)

{//{{AFX_DATA_INIT(CSDialog) // NOTE: the ClassWizard will add member initialization here

//}}AFX_DATA_INIT

}

 

void CSDialog:: DoDataExchange(CDataExchange* pDX)

{CDialog:: DoDataExchange(pDX);

//{{AFX_DATA_MAP(CSDialog)

DDX_Control(pDX, IDC_TREE1, m_Tree);

DDX_Control(pDX, IDC_EDIT1, m_Edit);

//}}AFX_DATA_MAP

}

BEGIN_MESSAGE_MAP(CSDialog, CDialog)

//{{AFX_MSG_MAP(CSDialog)

ON_BN_CLICKED(IDC_BUTTON1, OnAdd)

ON_BN_CLICKED(IDC_BUTTON2, OnDelete)

ON_BN_CLICKED(IDC_BUTTON3, OnEdit)

ON_NOTIFY(NM_RCLICK, IDC_TREE1, OnRclickTree1)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

BOOL CSDialog:: OnInitDialog()

{CDialog:: OnInitDialog(); // TODO: Add extra initialization here

InitTree();

return TRUE; }

 

CApp:: CApp(){}

CApp:: ~CApp(){}

 

BOOL CApp:: InitInstance()

{CSDialog a;

a.DoModal();

return TRUE; }

 

CApp App;

void CSDialog:: OnAdd()

{// TODO: Add your control notification handler code here

if(! m_Tree.GetSelectedItem())

MessageBox(" Node isn't selected", " ");

else {i++; char str[20];

m_Edit.GetWindowText(str, sizeof(str));

if(strlen(str))

{ hTreeCurrent=m_Tree.GetSelectedItem();

TV_INSERTSTRUCT tvs;

TV_ITEM tvi;

tvs.hInsertAfter=TVI_LAST;

tvi.mask=TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;

tvi.iImage=0;

tvi.iSelectedImage=1;

tvi.pszText=str;

tvs.hParent=hTreeCurrent;

tvs.item=tvi;

hTreeCtrl[i]=m_Tree.InsertItem(& tvs);

hTreeCurrent=hTreeCtrl[i];

InvalidateRect(NULL);

} else MessageBox(" You should set unzero name ", " ");

}}

 

void CSDialog:: OnDelete()

{// TODO: Add your control notification handler code here

if(! m_Tree.GetSelectedItem()) MessageBox(" Node isn't selected", " ");

else {hTreeCurrent=m_Tree.GetSelectedItem();

if(! m_Tree.GetParentItem(hTreeCurrent)) MessageBox(" You can't delete the root", " ");

else {m_Tree.DeleteItem(hTreeCurrent); i--;

hTreeCurrent=hTreeCtrl[i--];

InvalidateRect(NULL);

}}}

 

void CSDialog:: OnEdit()

{hTreeCurrent=m_Tree.GetSelectedItem();

m_Tree.EditLabel(hTreeCurrent); }

 

void CSDialog:: InitTree()

{m_treeImageList.Create(16, 16, FALSE, 3, 0);

HICON hIcon = LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ICON1));

m_treeImageList.Add(hIcon);

hIcon = LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ICON2));

m_treeImageList.Add(hIcon);

hIcon = LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ICON3));

m_treeImageList.Add(hIcon);

m_Tree.SetImageList(& m_treeImageList, TVSIL_NORMAL);

 

TV_INSERTSTRUCT tvs;

TV_ITEM tvi;

tvs.hInsertAfter=TVI_LAST;

tvi.mask=TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;

 

tvi.pszText=" One";

tvi.iImage=0;

tvi.iSelectedImage=1;

tvs.hParent=TVI_ROOT;

tvs.item=tvi;

hTreeCtrl[0]=m_Tree.InsertItem(& tvs);

hTreeCurrent=hTreeCtrl[0];

 

tvi.pszText=" Two";

tvi.iImage=0;

tvi.iSelectedImage=1;

tvs.hParent=hTreeCtrl[0];

tvs.item=tvi;

hTreeCtrl[1]=m_Tree.InsertItem(& tvs);

 

tvi.pszText=" Three";

tvi.iImage=1;

tvi.iSelectedImage=2;

tvs.hParent=hTreeCtrl[1];

tvs.item=tvi;

hTreeCtrl[2]=m_Tree.InsertItem(& tvs);

 

tvi.pszText=" Four";

tvi.iImage=1;

tvi.iSelectedImage=2;

tvs.hParent=hTreeCtrl[2];

tvs.item=tvi;

hTreeCtrl[3]=m_Tree.InsertItem(& tvs);

 

tvi.pszText=" Five";

tvi.iImage=1;

tvi.iSelectedImage=2;

tvs.hParent=hTreeCtrl[2];

tvs.item=tvi;

hTreeCtrl[4]=m_Tree.InsertItem(& tvs);

}

 

void CSDialog:: OnRclickTree1(NMHDR* pNMHDR, LRESULT* pResult)

{// TODO: Add your control notification handler code here

hTreeCurrent=m_Tree.GetSelectedItem();

m_Tree.EditLabel(hTreeCurrent);

*pResult = 0; }

 

BOOL CSDialog:: OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)

{// TODO: Add your specialized code here and/or call the base class

TV_DISPINFO* tv_dispInfo = (TV_DISPINFO*) lParam;

if (tv_dispInfo-> hdr.code == TVN_BEGINLABELEDIT)

CEdit* pEdit = m_Tree.GetEditControl();

else if (tv_dispInfo-> hdr.code == TVN_ENDLABELEDIT)

{ if (tv_dispInfo-> item.pszText! = NULL)

m_Tree.SetItemText(tv_dispInfo-> item.hItem, tv_dispInfo-> item.pszText);

}

return CDialog:: OnNotify(wParam, lParam, pResult);

}

 

5.11 Використання рядків стану

 

Рядок стану (або “status bar control”) є горизонтальним вікном, яке звичайно відображується у нижній частині батьківського вікна, у якому відображується інформація про стан параметрів програми. Наприклад, програма Microsoft Word відображує поточну інформацію у формі, наведеній на рис. 5.15.

 

 

Рисунок 5.15 – Приклад використання рядка стану

 

У MFC рядок стану забезпечується за допомогою класу CStatusBarCtrl. Для створення рядка стану необхідно виконати декілька кроків:

1) створити об’єкт типу CStatusBarCtrl у класі вікна програми;

2) викликати функцію Create() для створення вікна рядка стану, приєднати до нього об’єкт класу:

Функція Create() класу CStatusBarCtrl має такий вигляд:

 

BOOL CStatusBar:: Create(CWnd*pParentWnd, DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_BOTTOM, UINT nID=AFX_IDW_STATUS_BAR);

 

де pParentWnd – покажчик на батьківське вікно Windows, dwStyle - стиль рядка стану, nID – ідентифікатор дочірнього вікна панелі інструментів. Окрім стан-дартних стилів для рядка стану визначаються додаткові стилі:

 

Таблиця 5.12 – Стилі елемента рядка стану

Константа стилю Коментар
CСS_TOP розміщення рядка стану у верхній частині вікна
CCS_BOTTOM розміщення рядка стану у нижній частині вікна
CCS_NODIVIDER відсутність розподільників між окремими полями
CCS_NOHILITED відсутність виділення коло йором поточного поля
CCS_NOPARENTALIGN відсутність автоматичного вирівнювання при оновленні
CCS_NORESIZE відсутність автоматичної зміни розміру

 

Клас CStatusBarCtrl забезпечується рядом необхідних функцій, серед них зазначимо деякі.

Кількість полів у рядку стану визначає функція SetParts():

 

BOOL CStatusBarCtrl:: SetParts(int nParts, int* pWidths);

 

де nParts – кількість частин рядка (не може перевищувати 255), pWidths – адреса цілочисельного масиву, який визначає позиції правого краю кожної частини (значення -1 означає, що позиція правого краю частини перевищує правий край керування).

Для кожного з визначених полів рядка функція SetText() визначає текстове заповнення:

 

BOOL CStatusBarCtrl:: SetText (LPCTSTR lpszText, int nPane, int nType);

 

де lpszText – покажчик на рядок, что встановлюється у полі; nPane – номер поля, до якого встановлюється текст; nType – режим відображення тексту (0 – текст відображується “натиснутим” у полі, SBT_NOBORDERS – текст не має рамки, SBT_OWNERDRAW – текст відображується батьківським вікном, SBT_POPOUT – текст відображується в опуклому вигляді).

Для використання у MFC-програмі елемента відображення рядка стану необхідно виконати певну послідовність кроків:

1) створити об’єкт рядка стану;

2) визначити кількість полів рядка стану;

3) визначити текст кожного поля рядка;

4) оновити текст під час змін у роботі програми.

Якщо для програми із створенням регулятора гучності звуку (приклад 5.6) передбачити відображення поточних значень гучності у каналах через рядок стану, у програму вносяться такі зміни:

1) у класі діалогового вікна оголошується об’єкт рядка стану:

class CSDialog: public CDialog

{public: CStatusBarCtrl m_Status;

………………………….

};

2) у функції ініціалізації діалогового вікна фізично створити рядок стану:

BOOL CSDialog:: OnInitDialog()

{ CDialog:: OnInitDialog();

m_sl1.SetPos(50);

m_sl2.SetPos(50);

m_sl3.SetPos(50);

CRect r;

GetClientRect(& r);

int parts[3]; // три поля

for(int i=1; i< =3; i++)parts[i-1]=r.right/3*i; // визначення координат трьох полів

m_Status.Create(WS_VISIBLE | WS_CHILD, r, this, 1);

m_Status.SetParts(3, parts);

return TRUE;

}

3) модифікувати обробник OnVScroll() для відображення у рядку стану поточних значень регуляторів лівого, правого каналів, загального регулятора гучності звуку:

void CSDialog:: OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)

{ DWORD volume;

char str[255];

UINT uRetVal, uNumDevs;

if (uNumDevs = waveOutGetNumDevs())

{uRetVal = waveOutGetVolume(0, (LPDWORD)& volume);

if(pScrollBar==(CScrollBar*)& m_sl1)

{DWORD curVol=MAKELONG((DWORD)0xFFFF/100*m_sl1.GetPos(),

HIWORD(volume));

waveOutSetVolume(0, curVol);

wsprintf(str, " Лівий канал: %d", m_sl1.GetPos()); // формування тексту поля 0

m_Status.SetText(str, 0, 0); // визначення тексту поля 0

}

if(pScrollBar==(CScrollBar*)& m_sl2)

{DWORD curVol=MAKELONG(LOWORD(volume),

(DWORD)0xFFFF/100*m_sl2.GetPos()); waveOutSetVolume(0, curVol);

wsprintf(str, " Правий канал: %d", m_sl2.GetPos());

m_Status.SetText(str, 1, 0);

}

if(pScrollBar==(CScrollBar*)& m_sl3)

{m_sl1.SetPos(m_sl3.GetPos());

m_sl2.SetPos(m_sl3.GetPos());

DWORD curVol=MAKELONG((DWORD)0xFFFF/100*m_sl1.GetPos(),

(DWORD)0xFFFF/100*m_sl2.GetPos());

waveOutSetVolume(0, curVol);

wsprintf(str, " Лівий канал: %d", m_sl1.GetPos());

m_Status.SetText(str, 0, 0); // запис у перше поле

wsprintf(str, " Правий канал: %d", m_sl2.GetPos());

m_Status.SetText(str, 1, 0); // запис у друге поле

wsprintf(str, " Загальний: %d", m_sl3.GetPos());

m_Status.SetText(str, 2, 0); // запис у третє поле

}}

CDialog:: OnVScroll(nSBCode, nPos, pScrollBar);

}

 

Результат роботи модифікованої програми наведений на рисунку 5.16.

 

Рисунок 5.16 – Регулятор гучності із рядком стану

 

5.12 Використання закладок

 

5.12.1 Загальна інформація про закладки

Елемент закладка (tab control) зовнішньо нагадує сторінки записника, у якому доступ до кожної сторінки діалогового вікна здійснюється її простим вибором. Редактор ресурсів Visual С++ надає можливості візуального визначення вигляду елемента (зображений на рисунку 5.17).

 

 

Рисунок 5.17 – Вигляд елемента закладка

 

Кожна сторінка закладки може відображати інші елементи керування, і таким чином дозволяє об’єднувати редагування декількох сторінок із властивостями програмних об’єктів. Подібними, але більш розвиненими елементами керування є сторінки властивостей, що ми розглянемо пізніше.

У MFC закладка реалізована за допомогою класу CTabCtrl, що так само як і інші спільні елементи керування породжується від класу CWnd і є спадкоємцем його головних властивостей.

Послідовність створення закладки як елемента головного вікна програми зазвичай складається з двох кроків:

1) створити об’єкт закладки у класі головного вікна;

2) використати функцію Create() класу CTabCtrl для визначення основних властивостей елемента закладки.

Функція Create() класу CTabCtrl має такий прототип:

 

BOOL CTabCtrl:: Create(DWORD dwStyle, RECT& rect, CWnd* pParentWnd, UINT nID);

 

де dwStyle – стиль закладки, rect – її розташування та розмір, pParentWnd – покажчик на батьківське вікно (має відрізнятися від NULL), nID – ідентифікатор ресурсу.

Під час створення закладки у головному вікні програми використовують стандартні стилі WS_CHILD, WS_VISIBLE, WS_BORDER а також ряд специфічних для об’єкта закладки. Деякі з властивих закладці стилів наведено у таблиці 5.13.

 

Таблиця 5.13 – Основні стилі елемента закладка

Константа стилю Коментар
TCS_BUTTONS надає закладкам вигляд стандартних кнопок
TCS_FIXEDWIDTH фіксує ширину усіх закладок
TCS_FOCUSNEVER виключає отримання закладкою фокусу
TCS_FOCUSONBUTTONDOWN закладка отримує фокус натисканням лівої клавіші миші (використовується виключно разом з TCS_BUTTONS)
TCS_FORCEICONLEFT визначає положення піктограми ліворуч напису закладки
TCS_FORCELABELLEFT вирівнює напис та піктограму за лівим краєм
TCS_MULTILINE можливість використання декількох рядків закладок
TCS_OWNERDRAWFIXED визначає, що батьківське вікно відображає усі закладки
TCS_RIGHTJUSTIFY вирівнює напис та піктограму за правим краєм
TCS_SHAREIMAGELISTS надає можливість використання списків зображень й іншим елементам керування
TCS_TOOLTIPS використання у закладці спливаючих підказок
TCS_TABS стандартний стиль: закладки у своїй власній формі, а не у стилі кнопок
TCS_SINGLELINE відображує усі закладки в одному рядку
TCS_RAGGEDRIGHT закладки займають не всю ширину вікна
WS_TABSTOP визначає перелік елементів керування, що можуть використовуватися для переміщення між закладками

 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.