added some development tools
[windows-sources.git] / developer / VC / WTL80 / Samples / Wizard97Test / Wizard / TestWizardFilePreviewPage.cpp
blobc056eb9542a60388ff66c9d95971743f230c949e
2 #include "stdafx.h"
3 #include "TestWizardFilePreviewPage.h"
5 ///////////////////////////////////////////////////////////////////////////////
6 // CFileListViewCtrl - a sortable list view of the resulting files
8 LRESULT CFileListViewCtrl::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
10 LRESULT result = DefWindowProc();
11 if(result == -1)
13 return -1;
16 this->Initialize();
17 return result;
20 LRESULT CFileListViewCtrl::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
22 this->Uninitialize();
24 bHandled = FALSE;
25 return 0;
28 LRESULT CFileListViewCtrl::OnContextMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
30 bHandled = TRUE;
32 int indexSelectedNearMenu = -1;
34 POINT ptPopup = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
35 if(ptPopup.x == -1 && ptPopup.y == -1)
37 // They used the context menu key or Shift-F10 to bring up the context menu
38 indexSelectedNearMenu = this->GetNextItem(-1, LVNI_SELECTED);
39 RECT rect = {0};
40 if(indexSelectedNearMenu >= 0)
42 // If there is a selected item, popup the menu under the first selected item,
43 // if not, pop it up in the top left of the list view
44 this->GetItemRect(indexSelectedNearMenu, &rect, LVIR_BOUNDS);
45 ::MapWindowPoints(m_hWnd, NULL, (LPPOINT)&rect, 2);
46 ptPopup.x = rect.left;
47 ptPopup.y = rect.bottom;
50 else
52 POINT ptClient = ptPopup;
53 ::MapWindowPoints(NULL, m_hWnd, &ptClient, 1);
55 LVHITTESTINFO hti = { 0 };
56 hti.pt = ptClient;
57 indexSelectedNearMenu = this->HitTest(&hti);
60 if(indexSelectedNearMenu > 0)
62 // TODO: Handle multiple selection
63 CString fullPath;
64 this->GetItemText(indexSelectedNearMenu, ListColumn_FullPath, fullPath);
66 // Build up the menu to show
67 //CMenu mnuContext;
68 //if(mnuContext.CreatePopupMenu())
69 //{
70 //}
73 return 0;
76 void CFileListViewCtrl::Initialize(void)
78 this->InitializeListColumns();
81 void CFileListViewCtrl::InitializeListColumns(void)
83 CRect rcList;
84 this->GetClientRect(&rcList);
86 int width = rcList.Width();
87 int columnWidth = 0;
88 int remainingWidth = width;
90 // NOTE: We'll take the default sort type (LVCOLSORT_TEXT)
91 // for the "Name" and "Folder" columns.
92 // LVCOLSORT_TEXT uses lstrcmp, which uses the currently
93 // selected user locale for sorting. This matches the sorting
94 // in the file list in Windows Explorer. With lstrcmp:
95 // "a" < "A" and "A" < "b" and "b" < "B"
96 // By comparison, with _tcscmp the sort order is in "ASCII" order:
97 // "A" < "a" and "Z" < "a"
98 // LVCOLSORT_TEXTNOCASE uses lstrcmpi, which sorts:
99 // "a" == "A" and "A" < "b" and "b" == "B"
101 columnWidth = ::MulDiv(width, 20, 100); // 20%
102 this->InsertColumn(ListColumn_Name, _T("Name"), LVCFMT_LEFT, columnWidth, ListColumn_Name);
103 //baseClass::SetColumnSortType(ListColumn_Name, LVCOLSORT_TEXT);
104 remainingWidth -= columnWidth;
106 columnWidth = ::MulDiv(width, 50, 100); // 50%
107 this->InsertColumn(ListColumn_Folder, _T("In Folder"), LVCFMT_LEFT, columnWidth, ListColumn_Folder);
108 //baseClass::SetColumnSortType(ListColumn_Folder, LVCOLSORT_TEXT);
109 remainingWidth -= columnWidth;
111 columnWidth = ::MulDiv(width, 15, 100); // 15%
112 this->InsertColumn(ListColumn_LastModified, _T("Date Modified"), LVCFMT_LEFT, columnWidth, ListColumn_LastModified);
113 baseClass::SetColumnSortType(ListColumn_LastModified, LVCOLSORT_DATETIME);
114 remainingWidth -= columnWidth;
116 columnWidth = remainingWidth;
117 this->InsertColumn(ListColumn_Size, _T("Size"), LVCFMT_LEFT, columnWidth, ListColumn_Size);
118 baseClass::SetColumnSortType(ListColumn_Size, LVCOLSORT_CUSTOM);
120 // Hidden columns
121 // (We could go to more work to keep these truly hidden,
122 // but for now, we'll allow column size adjusts, Ctrl+NumPad+
123 // and the like to reveal the columns).
124 this->InsertColumn(ListColumn_SizeBytes, _T("Size in Bytes"), LVCFMT_LEFT, 0, ListColumn_SizeBytes);
125 baseClass::SetColumnSortType(ListColumn_SizeBytes, LVCOLSORT_DECIMAL);
127 this->InsertColumn(ListColumn_FullPath, _T("Full Path"), LVCFMT_LEFT, 0, ListColumn_FullPath);
128 //baseClass::SetColumnSortType(ListColumn_FullPath, LVCOLSORT_TEXT);
131 void CFileListViewCtrl::Uninitialize(void)
135 BOOL CFileListViewCtrl::SubclassWindow(HWND hWnd)
137 ATLASSERT(m_hWnd == NULL);
138 ATLASSERT(::IsWindow(hWnd));
139 BOOL returnValue = baseClass::SubclassWindow(hWnd);
140 if(returnValue)
142 this->Initialize();
144 return returnValue;
147 HWND CFileListViewCtrl::UnsubclassWindow(BOOL bForce)
149 this->Uninitialize();
151 return baseClass::UnsubclassWindow(bForce);
154 int CFileListViewCtrl::CompareItemsCustom(LVCompareParam* pItem1, LVCompareParam* pItem2, int iSortCol)
156 int result = 0;
158 // Deal with all of the custom sort columns
159 switch(iSortCol)
161 case ListColumn_Size:
163 // Sort based on ListColumn_SizeBytes
165 // NOTE: There's other ways to use a "proxy column" for sorting, this is just one
166 // (mainly, just to give an example of CompareItemsCustom).
167 // Another way would be to have DoSortItems run on the hidden column,
168 // but then SetSortColumn for the visible column.
170 CString sizeInBytesLHS, sizeInBytesRHS;
171 this->GetItemText(pItem1->iItem, ListColumn_SizeBytes, sizeInBytesLHS);
172 this->GetItemText(pItem2->iItem, ListColumn_SizeBytes, sizeInBytesRHS);
174 __int64 difference = _ttoi64(sizeInBytesRHS) - _ttoi64(sizeInBytesLHS);
175 if(difference < 0)
176 result = 1;
177 else if(difference > 0)
178 result = -1;
179 else
180 result = 0;
182 break;
185 return result;
188 void CFileListViewCtrl::OnFileFound(LPCTSTR directory, LPWIN32_FIND_DATA findFileData)
190 TCHAR fileFullPath[MAX_PATH+1] = {0};
191 ::PathCombine(fileFullPath, directory, findFileData->cFileName);
193 ULARGE_INTEGER fileSize = { findFileData->nFileSizeLow, findFileData->nFileSizeHigh };
195 this->AddFile(directory, findFileData->cFileName, fileFullPath, findFileData->ftLastWriteTime, fileSize.QuadPart);
198 int CFileListViewCtrl::AddFile(LPCTSTR fileFullPath)
200 int index = -1;
202 WIN32_FILE_ATTRIBUTE_DATA attributes = {0};
203 if(::GetFileAttributesEx(fileFullPath, GetFileExInfoStandard, &attributes))
205 TCHAR fileSpec[MAX_PATH+1] = {0};
206 TCHAR directory[MAX_PATH+1] = {0};
208 ::lstrcpyn(fileSpec, fileFullPath, MAX_PATH);
209 ::lstrcpyn(directory, fileFullPath, MAX_PATH);
211 ::PathStripPath(fileSpec);
212 ::PathRemoveFileSpec(directory);
214 ULARGE_INTEGER fileSize = { attributes.nFileSizeLow, attributes.nFileSizeHigh };
216 index = this->AddFile(directory, fileSpec, fileFullPath, attributes.ftLastWriteTime, fileSize.QuadPart);
219 return index;
222 int CFileListViewCtrl::AddFile(LPCTSTR directory, LPCTSTR fileSpec, LPCTSTR fileFullPath, FILETIME lastWriteTimeUTC, ULONGLONG fileSize)
224 FILETIME localTime = {0};
225 SYSTEMTIME st = {0};
226 ::FileTimeToLocalFileTime(&lastWriteTimeUTC, &localTime);
227 ::FileTimeToSystemTime(&localTime, &st);
229 int hour12 = st.wHour;
230 if(st.wHour == 0)
231 hour12 = 12;
232 else if(st.wHour > 12)
233 hour12 -= 12;
235 CString lastModified;
236 lastModified.Format(_T("%d/%d/%d %d:%.2d %s"),
237 st.wMonth, st.wDay, st.wYear,
238 hour12, st.wMinute, (st.wHour > 11) ? _T("PM") : _T("AM"));
240 TCHAR size[32] = {0};
241 ::StrFormatByteSize64(fileSize, size, 31);
243 CString sizeBytes;
244 sizeBytes.Format(_T("%I64u"), fileSize);
246 int index = this->GetItemCount();
247 this->InsertItem(index, fileSpec);
248 this->SetItemText(index, ListColumn_Folder, directory);
249 this->SetItemText(index, ListColumn_LastModified, lastModified);
250 this->SetItemText(index, ListColumn_Size, size);
251 this->SetItemText(index, ListColumn_SizeBytes, sizeBytes);
252 this->SetItemText(index, ListColumn_FullPath, fileFullPath);
254 return index;
257 void CFileListViewCtrl::AutoResizeColumns(void)
259 this->SetColumnWidth(ListColumn_Name, LVSCW_AUTOSIZE_USEHEADER);
260 this->SetColumnWidth(ListColumn_Folder, LVSCW_AUTOSIZE_USEHEADER);
261 this->SetColumnWidth(ListColumn_LastModified, LVSCW_AUTOSIZE_USEHEADER);
262 this->SetColumnWidth(ListColumn_Size, LVSCW_AUTOSIZE_USEHEADER);
263 this->SetColumnWidth(ListColumn_SizeBytes, 0);
264 this->SetColumnWidth(ListColumn_FullPath, 0);
268 ///////////////////////////////////////////////////////////////////////////////
269 // CTestWizardFilePreviewPage - Wizard page to preview the files located by the path/filter
271 LRESULT CTestWizardFilePreviewPage::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
273 CWaitCursor waitCursor;
275 this->InitializeControls();
276 this->InitializeValues();
278 return 1;
281 LRESULT CTestWizardFilePreviewPage::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
283 // Be sure the base gets the message too
284 bHandled = FALSE;
286 this->UninitializeControls();
287 return 0;
290 LRESULT CTestWizardFilePreviewPage::OnClickPreview(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
292 CWaitCursor waitCursor;
294 m_listFiles.EnableWindow(TRUE);
296 this->UpdateFileList();
298 return 0;
301 void CTestWizardFilePreviewPage::InitializeControls(void)
303 m_listFiles.SubclassWindow(this->GetDlgItem(IDC_LIST_FILES));
305 m_buttonPreview = this->GetDlgItem(IDC_BTN_PREVIEW);
307 m_listFiles.EnableWindow(FALSE);
310 void CTestWizardFilePreviewPage::UninitializeControls(void)
312 m_listFiles.UnsubclassWindow();
315 void CTestWizardFilePreviewPage::InitializeValues(void)
317 m_listFiles.DeleteAllItems();
320 bool CTestWizardFilePreviewPage::StoreValues(void)
322 return true;
325 void CTestWizardFilePreviewPage::UpdateFileList()
327 CWaitCursor waitCursor;
329 m_listFiles.SetSortColumn(-1);
331 m_listFiles.SetRedraw(FALSE);
332 m_listFiles.DeleteAllItems();
334 int fileCount = m_pTestWizardInfo->FindFiles(&m_listFiles);
336 if(fileCount < 1)
338 m_listFiles.InsertItem(0, _T("(No existing files found for the path and filter)"));
341 m_listFiles.AutoResizeColumns();
343 m_listFiles.SetRedraw(TRUE);
344 m_listFiles.Invalidate();
347 // Overrides from base class
348 int CTestWizardFilePreviewPage::OnSetActive()
350 m_listFiles.EnableWindow(FALSE);
352 this->SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
354 // 0 = allow activate
355 // -1 = go back to page that was active
356 // page ID = jump to page
357 return 0;
360 int CTestWizardFilePreviewPage::OnWizardNext()
362 bool success = this->StoreValues();
363 if(!success)
365 // Any errors are already reported, and if appropriate,
366 // the control that needs attention has been given focus.
367 return -1;
370 // 0 = goto next page
371 // -1 = prevent page change
372 // >0 = jump to page by dlg ID
374 return m_pTestWizardInfo->FindNextPage(IDD);
377 int CTestWizardFilePreviewPage::OnWizardBack()
379 return m_pTestWizardInfo->FindPreviousPage(IDD);
382 void CTestWizardFilePreviewPage::OnHelp()
384 m_pTestWizardInfo->ShowHelp(IDD);