In the second half of this presentation, the discussion will concentrate on the printing aspects of the SDI interface. This can be one of the main reasons for using SDI because it takes over much of the programming detail of printing. In addition, the print preview function is automatic!
This program uses the Microsoft Foundation Classes (MFC)to create a Windows program based on the Single Document Interface (SDI) programming model. This approach divides the programming task into three parts: the Document; the Frame; and the View. At this month's meeting we will discuss how these parts interact. Other topics will include printing, vectors, CListView and CFileFind.
As shown is the screen shot above, the program presents a table or database which summarizes a group of files. In this case, the H: drive has 97385 files in 9 GigaBytes. There are 5878 "EXE" files using 1.5 GigaBytes of storage. This is 15 percent of the total file storage. The data may be sorted by clicking on the column headings.
The program features menus, a tool bar, file saving, print previewing, and printing. In addition, the window may be resized, maximized, and minimized. Most of the programming work is handled by the Microsoft C++ Version 6 application generator.
The algorithm for collecting the statistics makes use of the "vector" container. The Standard C++ Library provides an extensible framework and contains components for language support, diagnostics, general utilities, strings, locales, standard template library (containers, iterators, algorithms, numerics,) and input/output.
bWorking = target.FindFile((LPCTSTR) searchname); while (bWorking) { bWorking = target.FindNextFile(); if (target.IsDots()) continue; if (target.IsDirectory()) { Process( (LPCTSTR)target.GetFilePath()); } else // it's a regular file { record.Count=1; record.Ext.Empty(); record.KBytes = 0; int idx = target.GetFileName().ReverseFind('.'); if (idx != -1) { record.Ext = target.GetFileName().Mid(idx); record.Ext.MakeUpper(); } if (record.Ext.GetLength() > 10) continue; // most are like ".TXT" ++m_ActivityCtr; record.KBytes = target.GetLength() >> 10; // assume less than 4 gig if (target.GetLength() % 1024) ++record.KBytes; // round up std::vector<FILEinfo>::iterator mResult; mResult = std::find(Stats.begin(), Stats.end(), record); if (mResult == Stats.end()) { Stats.push_back(record); // Add to vector. } else { (*mResult).KBytes += record.KBytes; (*mResult).Count += 1; } } } void CFStatView::OnInitialUpdate() // Bruce_Arnold ... { static BOOL firstTime = true; CListView::OnInitialUpdate(); // TODO: You may populate your ListView with items by directly accessing // its list control through a call to GetListCtrl(). if (firstTime) { LVCOLUMN lvCol; GetListCtrl().InsertColumn(0, "Extension", LVCFMT_RIGHT, 100); GetListCtrl().InsertColumn(1, "Size (KB)", LVCFMT_RIGHT, 100, 1); GetListCtrl().InsertColumn(2, "Percent", LVCFMT_RIGHT, 100, 2); GetListCtrl().InsertColumn(3, "Count", LVCFMT_RIGHT, 100, 3); ::ZeroMemory(&lvCol, sizeof(LVCOLUMN)); lvCol.mask = LVCF_FMT; lvCol.fmt = LVCFMT_RIGHT; GetListCtrl().SetColumn(0, &lvCol); firstTime = false; } std::vector<FILEinfo>::iterator pVi; int i=0; char buff2[50],buff3[50]; CFStatDoc* pDoc = GetDocument(); for (pVi = pDoc->Stats.begin(); pVi != pDoc->Stats.end(); ++pVi) { GetListCtrl().InsertItem (i, (*pVi).Ext); sprintf(buff2, "%.2f", (*pVi).Percent); sprintf(buff3, "%d", (*pVi).Count); GetListCtrl().SetItemText(i, 1, pDoc->Comma_ltoa((*pVi).KBytes)); GetListCtrl().SetItemText(i, 2, buff2); GetListCtrl().SetItemText(i, 3, buff3); ++i; } }