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();
20 LRESULT
CFileListViewCtrl::OnDestroy(UINT
/*uMsg*/, WPARAM
/*wParam*/, LPARAM
/*lParam*/, BOOL
& bHandled
)
28 LRESULT
CFileListViewCtrl::OnContextMenu(UINT
/*uMsg*/, WPARAM
/*wParam*/, LPARAM lParam
, BOOL
& bHandled
)
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
);
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
;
52 POINT ptClient
= ptPopup
;
53 ::MapWindowPoints(NULL
, m_hWnd
, &ptClient
, 1);
55 LVHITTESTINFO hti
= { 0 };
57 indexSelectedNearMenu
= this->HitTest(&hti
);
60 if(indexSelectedNearMenu
> 0)
62 // TODO: Handle multiple selection
64 this->GetItemText(indexSelectedNearMenu
, ListColumn_FullPath
, fullPath
);
66 // Build up the menu to show
68 //if(mnuContext.CreatePopupMenu())
76 void CFileListViewCtrl::Initialize(void)
78 this->InitializeListColumns();
81 void CFileListViewCtrl::InitializeListColumns(void)
84 this->GetClientRect(&rcList
);
86 int width
= rcList
.Width();
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
);
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
);
147 HWND
CFileListViewCtrl::UnsubclassWindow(BOOL bForce
)
149 this->Uninitialize();
151 return baseClass::UnsubclassWindow(bForce
);
154 int CFileListViewCtrl::CompareItemsCustom(LVCompareParam
* pItem1
, LVCompareParam
* pItem2
, int iSortCol
)
158 // Deal with all of the custom sort columns
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
);
177 else if(difference
> 0)
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
)
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
);
222 int CFileListViewCtrl::AddFile(LPCTSTR directory
, LPCTSTR fileSpec
, LPCTSTR fileFullPath
, FILETIME lastWriteTimeUTC
, ULONGLONG fileSize
)
224 FILETIME localTime
= {0};
226 ::FileTimeToLocalFileTime(&lastWriteTimeUTC
, &localTime
);
227 ::FileTimeToSystemTime(&localTime
, &st
);
229 int hour12
= st
.wHour
;
232 else if(st
.wHour
> 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);
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
);
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();
281 LRESULT
CTestWizardFilePreviewPage::OnDestroy(UINT
/*uMsg*/, WPARAM
/*wParam*/, LPARAM
/*lParam*/, BOOL
& bHandled
)
283 // Be sure the base gets the message too
286 this->UninitializeControls();
290 LRESULT
CTestWizardFilePreviewPage::OnClickPreview(WORD
/*wNotifyCode*/, WORD
/*wID*/, HWND
/*hWndCtl*/, BOOL
& /*bHandled*/)
292 CWaitCursor waitCursor
;
294 m_listFiles
.EnableWindow(TRUE
);
296 this->UpdateFileList();
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)
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
);
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
360 int CTestWizardFilePreviewPage::OnWizardNext()
362 bool success
= this->StoreValues();
365 // Any errors are already reported, and if appropriate,
366 // the control that needs attention has been given focus.
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
);