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

Створення Програми

Клас CTestApp містить функцію InitInstance(), з якої починається виконання програми і створення об’єкту програми theApp (Рис. 37). В функції InitInstance() створюється об’єкт вікна програми, до нього приєднується вікно програми і вікно програми на екрані.

Клас CMainFrame містить об’єкти класів CStatusBar, CToolBar та CChildView і функції, що підтримують зовнішній вигляд вікна програми (Рис. 38).

Клас CChildView містить функції PreCreateWindow() та OnPaint() (Рис. 39). У функції PreCreateWindow() налаштовується зовнішній вигляд робочої області вікна програми, а функція OnPaint() дозволяє здійснювати графічний вивід у робочу область вікна програми. Для цього вона містить об’єкт класу контексту екрана CPaintDC.

Контекст екрана інкапсулює весь графічний вивід в робочу область вікна програми.

Якщо, програма, що створюється повинна працювати з текстовими документами, то базовим класом для класу дочірнього вікна CChildView у діалозі Рис. 35 необхідно вибрати клас CEditView. Тоді, майстер створення проекту автоматично згенерує класи «документу» та «вигляду» для підтримки текстових даних, та забезпечить їх збереження у файлі.

Рисунок 38. Клас CMainFrame.

Рисунок 39. Клас CChildView.

Якщо запустити програму на компіляцію і виконання, то вона створить вікно програми (Рис. 40), але не буде виконувати ніяких корисних дій.

Рисунок 40. Вікно програми після виконання.

Завдання

Використовуючи програму з однодокументною архітектурою забезпечити читання та запис текстових файлів з полями (розділяються комами) заданих об’єктів. За допомогою розробленої програми можна додавати нові записи до відкритого файлу.

Багатодокументна програма

Процес створення багатодокументної програми аналогічний процесу створення однодокументної. Лише у діалозі Рис. 30 необхідно вибрати прапорець “Multiple documents”.

Для того, щоб урізноманітнити вигляд у якому будуть виводитися дані для багатодокументної програми пропонується створити клас дочірнього вікна CChildView на основі стандартного для MFC касу CListView. Для цього необхідно в діалозі Рис. 35 зробити відповідний вибір. У результаті майстер проектів створить відповідні класи «документу» та «вигляду», які підтримують відображення даних у вигляді таблиці.

Нижче приведено приклад вмісту файлів заголовків та реалізації «документу» та його «вигляду» для відображення даних в таблиці.

Код для роботи з «документом»:

// CTableDoc document

class CTableDoc : public CDocument {

DECLARE_DYNCREATE(CTableDoc)

public:

CTableDoc();

virtual ~CTableDoc();

virtual void Serialize(CArchive& ar); // overridden for document i/o

virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);

virtual void DeleteContents();

int GetRowTotal();

STableRow * GetTable();

#ifdef _DEBUG

virtual void AssertValid() const;

virtual void Dump(CDumpContext& dc) const;

#endif

protected:

virtual BOOL OnNewDocument();

protected:

int m_RowTotal;

STableRow * m_pTable;

DECLARE_MESSAGE_MAP()

};

// ****************************************************************************

inline int CTableDoc::GetRowTotal() { return m_RowTotal; }

// ****************************************************************************

inline STableRow * CTableDoc::GetTable() { return m_pTable; }

// ****************************************************************************

BOOL CTableDoc::OnOpenDocument(LPCTSTR lpszPathName)

{

if (!CDocument::OnOpenDocument(lpszPathName))

return FALSE;

int i;

char szInBuff[1024];

char * szCurr;

FILE * fIn = fopen(lpszPathName, "r");

size_t nLenKeyStr = strlen(g_KeyRowTotal);

while (!feof(fIn)) {

fgets(szInBuff, 1024, fIn);

szCurr = strtok(szInBuff, ";");

if (szCurr && !strncmp(szCurr, g_KeyRowTotal, nLenKeyStr)) {

m_RowTotal = atoi(szCurr + nLenKeyStr);

break;

}

}

nLenKeyStr = strlen(g_szSurfFilePref);

if (m_RowTotal) {

m_pTable = (STableRow *)malloc(m_RowTotal * sizeof(STableRow));

i = 0;

while (!feof(fIn) && i < m_RowTotal) {

fgets(szInBuff, 1024, fIn);

if (szInBuff && !strncmp(szInBuff, g_szSurfFilePref, nLenKeyStr)) {

if (szCurr = strtok(szInBuff, ";")) {

sscanf(szCurr, "%s", m_pTable[i].szVoidName);

}

if (szCurr = strtok(NULL, ";")) {

m_pTable[i].nFaceCount = atoi(szCurr);

}

if (szCurr = strtok(NULL, ";")) {

sscanf(szCurr, "%f", &m_pTable[i].fVolume);

}

if (szCurr = strtok(NULL, ";")) {

m_pTable[i].centr.x = atoi(szCurr);

}

if (szCurr = strtok(NULL, ";")) {

m_pTable[i].centr.y = atoi(szCurr);

}

if (szCurr = strtok(NULL, ";")) {

m_pTable[i].centr.z = atoi(szCurr);

}

i++;

}

}

m_RowTotal = i;

}

fclose(fIn);

return TRUE;

}

// ****************************************************************************

void CTableDoc::DeleteContents()

{

if (m_RowTotal) free(m_pTable), m_RowTotal = 0;

CDocument::DeleteContents();

}

// ****************************************************************************

Код для роботи з «виглядом»:

// CTableView view

class CTableView : public CListView

{

DECLARE_DYNCREATE(CTableView)

STableRow m_SelectedPos;

protected:

CTableView(); // protected constructor used by dynamic creation

virtual ~CTableView();

protected:

virtual void OnInitialUpdate(); // called first time after construct

public:

#ifdef _DEBUG

virtual void AssertValid() const;

virtual void Dump(CDumpContext& dc) const;

#endif

protected:

DECLARE_MESSAGE_MAP()

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

public:

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

};

// CTableView

#define NUM_COLUMNS 6

enum EListCol {

LC_OBJ_NAME = 0,

LC_FACES,

LC_VOLUME,

LC_COORD_X,

LC_COORD_Y,

LC_COORD_Z

};

static _TCHAR * g_szColumnLabel[NUM_COLUMNS] = {

_T("Name Object"), _T("Faces"), _T("Volume"), _T("X-coord"), _T("Y-coord"), _T("Z-coord")

};

static int g_nColumnFmt[NUM_COLUMNS] = {

LVCFMT_LEFT, LVCFMT_RIGHT, LVCFMT_RIGHT, LVCFMT_RIGHT, LVCFMT_RIGHT, LVCFMT_RIGHT

};

static int g_nColumnWidth[NUM_COLUMNS] = {

150, 100, 100, 100, 100, 100

};

// ****************************************************************************

IMPLEMENT_DYNCREATE(CTableView, CListView)

// ****************************************************************************

CTableView::CTableView() { }

// ****************************************************************************

CTableView::~CTableView() { }

// ****************************************************************************

BEGIN_MESSAGE_MAP(CTableView, CListView)

ON_NOTIFY_REFLECT(NM_DBLCLK, OnNMDblclk)

END_MESSAGE_MAP()

// ****************************************************************************

BOOL CTableView::PreCreateWindow(CREATESTRUCT& cs)

{

cs.style |= LVS_SHOWSELALWAYS | LVS_REPORT;

return CListView::PreCreateWindow(cs);

}

// ****************************************************************************

void CTableView::OnInitialUpdate()

{

CListView::OnInitialUpdate();

CListCtrl & ListCtrl = GetListCtrl();

ListCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT);

int i;

LV_COLUMN lvc;

lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;

for(i = 0; i < NUM_COLUMNS; i++) {

lvc.iSubItem = i;

lvc.pszText = g_szColumnLabel[i];

lvc.cx = g_nColumnWidth[i];

lvc.fmt = g_nColumnFmt[i];

ListCtrl.InsertColumn(i, &lvc);

}

// insert items

CTableDoc * pDoc = (CTableDoc *)GetDocument();

int nRowTotal = pDoc->GetRowTotal();

STableRow * pTable = pDoc->GetTable();

LV_ITEM lvi;

char szIntBuff[32];

lvi.mask = LVIF_TEXT;

lvi.iSubItem = 0;

lvi.iImage = i;

ListCtrl.SetItemCount(nRowTotal);

for(i = 0; i < nRowTotal; i++) {

lvi.iItem = i;

lvi.pszText = pTable[i].szVoidName;

ListCtrl.InsertItem(&lvi);

// set item text for additional columns

sprintf(szIntBuff, "%d", pTable[i].nFaceCount);

ListCtrl.SetItemText(i, LC_FACES, szIntBuff);

sprintf(szIntBuff, "%9.2f", pTable[i].fVolume);

ListCtrl.SetItemText(i, LC_VOLUME, szIntBuff);

sprintf(szIntBuff, "%d", pTable[i].centr.x);

ListCtrl.SetItemText(i, LC_COORD_X, szIntBuff);

sprintf(szIntBuff, "%d", pTable[i].centr.y);

ListCtrl.SetItemText(i, LC_COORD_Y, szIntBuff);

sprintf(szIntBuff, "%d", pTable[i].centr.z);

ListCtrl.SetItemText(i, LC_COORD_Z, szIntBuff);

}

}

// ****************************************************************************

// CTableView diagnostics

#ifdef _DEBUG

// ****************************************************************************

void CTableView::AssertValid() const

{

CListView::AssertValid();

}

// ****************************************************************************

void CTableView::Dump(CDumpContext& dc) const

{

CListView::Dump(dc);

}

#endif //_DEBUG

// CTableView message handlers

// ****************************************************************************

void CTableView::OnNMDblclk(NMHDR *pNMHDR, LRESULT *pResult) {

int nRetLen;

CListCtrl & listCtrl = GetListCtrl();

POSITION pos = listCtrl.GetFirstSelectedItemPosition();

int nBuffLen = 32;

char strBuffer[32];

if (pos) {

int nItem = listCtrl.GetNextSelectedItem(pos);

nRetLen = listCtrl.GetItemText(nItem, LC_OBJ_NAME, m_SelectedPos.szVoidName, nBuffLen);

nRetLen = listCtrl.GetItemText(nItem, LC_COORD_X, strBuffer, nBuffLen);

m_SelectedPos.centr.x = atoi(strBuffer);

nRetLen = listCtrl.GetItemText(nItem, LC_COORD_Y, strBuffer, nBuffLen);

m_SelectedPos.centr.y = atoi(strBuffer);

nRetLen = listCtrl.GetItemText(nItem, LC_COORD_Z, strBuffer, nBuffLen);

m_SelectedPos.centr.z = atoi(strBuffer);

theApp.OnVoidListViewDbClick((WPARAM)&m_SelectedPos, 0);

}

*pResult = 0;

}

// ****************************************************************************