|
|
// FolderListView.cpp : implementation file
//
#include "stdafx.h"
#define __FILE_ID__ 22
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
#include <dlgprnt2.cpp>
extern CClientConsoleApp theApp;
//
// Static members:
//
CFolderListView * CFolderListView::m_psCurrentViewBeingSorted = NULL; CImageList CFolderListView::m_sImgListDocIcon; CImageList CFolderListView::m_sReportIcons;
/////////////////////////////////////////////////////////////////////////////
// CFolderListView
IMPLEMENT_DYNCREATE(CFolderListView, CListView)
BEGIN_MESSAGE_MAP(CFolderListView, CListView) //{{AFX_MSG_MAP(CFolderListView)
ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnClick) ON_WM_SETCURSOR() ON_MESSAGE (WM_FOLDER_REFRESH_ENDED, OnFolderRefreshEnded) ON_MESSAGE (WM_FOLDER_ADD_CHUNK, OnFolderAddChunk) ON_MESSAGE (WM_FOLDER_INVALIDATE, OnFolderInvalidate) ON_NOTIFY_REFLECT(NM_RCLICK, OnItemRightClick) ON_WM_CONTEXTMENU() ON_NOTIFY_REFLECT(LVN_ITEMCHANGED, OnItemChanged) ON_WM_SETCURSOR() ON_WM_CHAR() //}}AFX_MSG_MAP
ON_UPDATE_COMMAND_UI(ID_SELECT_ALL, OnUpdateSelectAll) ON_UPDATE_COMMAND_UI(ID_SELECT_NONE, OnUpdateSelectNone) ON_UPDATE_COMMAND_UI(ID_SELECT_INVERT, OnUpdateSelectInvert) ON_UPDATE_COMMAND_UI(ID_FOLDER_ITEM_VIEW, OnUpdateFolderItemView) ON_UPDATE_COMMAND_UI(ID_FOLDER_ITEM_PRINT, OnUpdateFolderItemPrint) ON_UPDATE_COMMAND_UI(ID_FOLDER_ITEM_COPY, OnUpdateFolderItemCopy) ON_UPDATE_COMMAND_UI(ID_FOLDER_ITEM_MAIL_TO, OnUpdateFolderItemSendMail) ON_UPDATE_COMMAND_UI(ID_FOLDER_ITEM_PROPERTIES, OnUpdateFolderItemProperties) ON_UPDATE_COMMAND_UI(ID_FOLDER_ITEM_DELETE, OnUpdateFolderItemDelete) ON_UPDATE_COMMAND_UI(ID_FOLDER_ITEM_PAUSE, OnUpdateFolderItemPause) ON_UPDATE_COMMAND_UI(ID_FOLDER_ITEM_RESUME, OnUpdateFolderItemResume) ON_UPDATE_COMMAND_UI(ID_FOLDER_ITEM_RESTART, OnUpdateFolderItemRestart) ON_COMMAND(ID_SELECT_ALL, OnSelectAll) ON_COMMAND(ID_SELECT_NONE, OnSelectNone) ON_COMMAND(ID_SELECT_INVERT, OnSelectInvert) ON_COMMAND(ID_FOLDER_ITEM_VIEW, OnFolderItemView) ON_COMMAND(ID_FOLDER_ITEM_PRINT, OnFolderItemPrint) ON_COMMAND(ID_FOLDER_ITEM_COPY, OnFolderItemCopy) ON_COMMAND(ID_FOLDER_ITEM_MAIL_TO, OnFolderItemMail) ON_COMMAND(ID_FOLDER_ITEM_PRINT, OnFolderItemPrint) ON_COMMAND(ID_FOLDER_ITEM_PROPERTIES, OnFolderItemProperties) ON_COMMAND(ID_FOLDER_ITEM_DELETE, OnFolderItemDelete) ON_COMMAND(ID_FOLDER_ITEM_PAUSE, OnFolderItemPause) ON_COMMAND(ID_FOLDER_ITEM_RESUME, OnFolderItemResume) ON_COMMAND(ID_FOLDER_ITEM_RESTART, OnFolderItemRestart) ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblClk) END_MESSAGE_MAP()
BOOL CFolderListView::PreCreateWindow(CREATESTRUCT& cs) { return CListView::PreCreateWindow(cs); }
BOOL CFolderListView::OnSetCursor( CWnd* pWnd, UINT nHitTest, UINT message ) { if (m_bInMultiItemsOperation || m_bSorting) { ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT)); return TRUE; }
CClientConsoleDoc* pDoc = GetDocument(); if (pDoc && pDoc->IsFolderRefreshing(m_Type)) { ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_APPSTARTING)); return TRUE; } else { return CView::OnSetCursor(pWnd, nHitTest, message); } } // CFolderListView::OnSetCursor
BOOL CFolderListView::IsSelected ( int iItem ) /*++
Routine name : CFolderListView::IsSelected
Routine description:
Checks if an item is selected in the list
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
iItem [in] - Item index
Return Value:
TRUE if item is selected in the list, FALSE otherwise.
--*/ { BOOL bRes = FALSE; DBG_ENTER(TEXT("CFolderListView::IsSelected"), bRes);
CListCtrl &refCtrl = GetListCtrl(); ASSERTION (refCtrl.GetItemCount() > iItem);
DWORD dwState = refCtrl.GetItemState (iItem , LVIS_SELECTED); if (LVIS_SELECTED & dwState) { bRes = TRUE; } return bRes; }
void CFolderListView::Select ( int iItem, BOOL bSelect ) /*++
Routine name : CFolderListView::Select
Routine description:
Selects / unselects an item in the list
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
iItem [in] - Item index bSelect [in] - TRUE if select, FALSE unselect
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::Select"), TEXT("%d"), bSelect);
CListCtrl &refCtrl = GetListCtrl(); ASSERTION (refCtrl.GetItemCount() > iItem);
refCtrl.SetItemState (iItem, bSelect ? (LVIS_SELECTED | LVIS_FOCUSED) : 0, LVIS_SELECTED | LVIS_FOCUSED); }
void CFolderListView::OnSelectAll () /*++
Routine name : CFolderListView::OnSelectAll
Routine description:
Select all list items
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::OnSelectAll"), TEXT("Type=%d"), m_Type); LV_ITEM lvItem;
CListCtrl &refCtrl = GetListCtrl(); ASSERTION (refCtrl.GetItemCount() > refCtrl.GetSelectedCount());
lvItem.mask = LVIF_STATE; lvItem.iItem = -1; // Specifies "All items"
lvItem.iSubItem = 0; lvItem.state = LVIS_SELECTED; lvItem.stateMask= LVIS_SELECTED;
m_bInMultiItemsOperation = TRUE;
refCtrl.SetItemState(-1, &lvItem);
m_bInMultiItemsOperation = FALSE; RecalcPossibleOperations();
} // CFolderListView::OnSelectAll
void CFolderListView::OnSelectNone () /*++
Routine name : CFolderListView::OnSelectNone
Routine description:
Unselect all list items
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::OnSelectNone"), TEXT("Type=%d"), m_Type);
LV_ITEM lvItem;
CListCtrl &refCtrl = GetListCtrl(); lvItem.mask = LVIF_STATE; lvItem.iItem = -1; // Specifies "All items"
lvItem.iSubItem = 0; lvItem.state = 0; lvItem.stateMask= LVIS_SELECTED;
m_bInMultiItemsOperation = TRUE;
refCtrl.SetItemState(-1, &lvItem);
m_bInMultiItemsOperation = FALSE; RecalcPossibleOperations();
} // CFolderListView::OnSelectNone
void CFolderListView::OnSelectInvert () /*++
Routine name : CFolderListView::OnSelectInvert
Routine description:
Invert list items selection
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::OnSelectInvert"), TEXT("Type=%d"), m_Type);
CListCtrl &refCtrl = GetListCtrl(); DWORD dwItemsCount = refCtrl.GetItemCount();
m_bInMultiItemsOperation = TRUE;
for (DWORD dw = 0; dw < dwItemsCount; dw++) { Select (dw, !IsSelected (dw)); }
m_bInMultiItemsOperation = FALSE; RecalcPossibleOperations();
} // CFolderListView::OnSelectInvert
void CFolderListView::OnDraw(CDC* pDC) { CListView::OnDraw (pDC); }
void CFolderListView::OnInitialUpdate() { //
// Refresh the image list (only if they are empty)
//
RefreshImageLists(FALSE); CListView::OnInitialUpdate(); }
/////////////////////////////////////////////////////////////////////////////
// CFolderListView diagnostics
#ifdef _DEBUG
void CFolderListView::AssertValid() const { CListView::AssertValid(); }
void CFolderListView::Dump(CDumpContext& dc) const { CListView::Dump(dc); }
CClientConsoleDoc* CFolderListView::GetDocument() // non-debug version is inline
{ ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CClientConsoleDoc))); return (CClientConsoleDoc*)m_pDocument; }
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CFolderListView message handlers
DWORD CFolderListView::InitColumns ( int *pColumnsUsed, DWORD dwDefaultColNum ) /*++
Routine name : CFolderListView::InitColumns
Routine description:
Inits the columns of the view.
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
pColumnsUsed [in] - Pointer to the list of ids to place in the columns. Must be a statically allocated list. dwDefaultColNum [in] - default column number
Return Value:
Standard Win32 error code
--*/ { DWORD dwRes = ERROR_SUCCESS; DBG_ENTER(TEXT("CFolderListView::InitColumns"), dwRes);
if (m_bColumnsInitialized) { return dwRes; }
m_dwDefaultColNum = dwDefaultColNum;
//
// Count the number of columns provided
//
CountColumns (pColumnsUsed);
int nItemIndex, nRes; CString cstrColumnText; DWORD dwCount = GetLogicalColumnsCount(); for (DWORD dw = 0; dw < dwCount; ++dw) { nItemIndex = ItemIndexFromLogicalColumnIndex(dw);
if(IsItemIcon(nItemIndex)) { //
// Init icon column - insert an empty string
//
nRes = GetListCtrl().InsertColumn (dw, TEXT(""), LVCFMT_LEFT); if (nRes < 0) { dwRes = ERROR_GEN_FAILURE; CALL_FAIL (WINDOW_ERR, TEXT("CListCtrl::InsertColumn"), dwRes); return dwRes; } //
// Set the header control's bitmap
//
CHeaderCtrl *pHeader = GetListCtrl().GetHeaderCtrl(); HDITEM hdItem; hdItem.mask = HDI_IMAGE | HDI_FORMAT; hdItem.fmt = HDF_LEFT | HDF_IMAGE; hdItem.iImage = 0; // Use first (and only) image from image list
if (!pHeader->SetItem (dw, &hdItem)) { dwRes = ERROR_GEN_FAILURE; CALL_FAIL (WINDOW_ERR, TEXT("CHeaderCtrl::SetItem"), dwRes); return dwRes; } } else { //
// init string column
//
dwRes = GetColumnHeaderString (cstrColumnText, nItemIndex); if (ERROR_SUCCESS != dwRes) { return dwRes; } nRes = GetListCtrl().InsertColumn (dw, cstrColumnText, GetColumnHeaderAlignment (nItemIndex)); }
if (nRes < 0) { dwRes = ERROR_GEN_FAILURE; CALL_FAIL (WINDOW_ERR, TEXT("CListCtrl::InsertColumn"), dwRes); return dwRes; } }
m_bColumnsInitialized = TRUE; return dwRes;
} // CFolderListView::InitColumns
void CFolderListView::AutoFitColumns () /*++
Routine name : CFolderListView::AutoFitColumns
Routine description:
Sets the column width to fit the contents of the column and the header
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::AutoFitColumns"));
CHeaderCtrl *pHeader = GetListCtrl().GetHeaderCtrl (); ASSERTION (pHeader); DWORD dwCount = pHeader->GetItemCount(); for (DWORD dwCol = 0; dwCol <= dwCount; dwCol++) { GetListCtrl().SetColumnWidth (dwCol, LVSCW_AUTOSIZE); int wc1 = GetListCtrl().GetColumnWidth (dwCol); GetListCtrl().SetColumnWidth (dwCol, LVSCW_AUTOSIZE_USEHEADER); int wc2 = GetListCtrl().GetColumnWidth (dwCol); int wc = max(20,max(wc1,wc2)); GetListCtrl().SetColumnWidth (dwCol, wc); } } // CFolderListView::AutoFitColumns
DWORD CFolderListView::UpdateLineTextAndIcon ( DWORD dwLineIndex, CViewRow &row ) /*++
Routine name : CFolderListView::UpdateLineTextAndIcon
Routine description:
Updates the icon and text in each column of a line item in the list
Author:
Eran Yariv (EranY), Feb, 2000
Arguments:
dwLineIndex [in] - Line index row [in] - Display information
Return Value:
Standard Win32 error code
--*/ { DWORD dwRes = ERROR_SUCCESS; DBG_ENTER(TEXT("CFolderListView::UpdateLineTextAndIcon"), dwRes);
//
// Start by setting the icon
//
LVITEM lvItem = {0}; lvItem.mask = LVIF_IMAGE; lvItem.iItem = dwLineIndex; lvItem.iSubItem = 0; lvItem.state = 0; lvItem.stateMask = 0; lvItem.pszText = NULL; lvItem.cchTextMax = 0; lvItem.lParam = NULL; lvItem.iImage = row.GetIcon(); lvItem.iIndent = 0; CListCtrl &refCtrl = GetListCtrl(); if (!refCtrl.SetItem (&lvItem)) { dwRes = ERROR_GEN_FAILURE; CALL_FAIL (WINDOW_ERR, TEXT("CListCtrl::SetItem"), dwRes); return dwRes; } //
// Set columns text
//
DWORD dwItemIndex; DWORD dwCount = GetLogicalColumnsCount(); for (DWORD dwCol = 0; dwCol < dwCount; ++dwCol) { dwItemIndex = ItemIndexFromLogicalColumnIndex (dwCol); if(IsItemIcon(dwItemIndex)) { continue; } //
// Get text from column
//
const CString &cstrColumn = row.GetItemString (dwItemIndex);
//
// Set the text in the control
//
if (!refCtrl.SetItemText (dwLineIndex, dwCol, cstrColumn)) { dwRes = ERROR_GEN_FAILURE; CALL_FAIL (WINDOW_ERR, TEXT("ListCtrl::SetItemText"), dwRes); return dwRes; } } ASSERTION (ERROR_SUCCESS == dwRes); return dwRes; } // CFolderListView::UpdateLineTextAndIcon
DWORD CFolderListView::AddItem ( DWORD dwLineIndex, CViewRow &row, LPARAM lparamItemData, PINT pintItemIndex ) /*++
Routine name : CFolderListView::AddItem
Routine description:
Adds an item to the list
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
dwLineIndex [in] - Index of addition row [in] - Row of item view information lparamItemData [in] - Item associated data pintItemIndex [out] - Item index in the list
Return Value:
Standard Win32 error code
--*/ { DWORD dwRes = ERROR_SUCCESS; DBG_ENTER(TEXT("CFolderListView::AddItem"), dwRes, TEXT("%ld"), dwLineIndex); //
// Insert the item: only state, indention and lParam are set.
//
LVITEM lvItem = {0}; lvItem.mask = LVIF_PARAM | LVIF_STATE | LVIF_INDENT; lvItem.iItem = dwLineIndex; lvItem.iSubItem = 0; lvItem.state = 0; lvItem.stateMask = 0; lvItem.pszText = NULL; lvItem.cchTextMax = 0; lvItem.lParam = lparamItemData; lvItem.iImage = 0; lvItem.iIndent = 0;
*pintItemIndex = ListView_InsertItem (GetListCtrl().m_hWnd, &lvItem); if (-1 == *pintItemIndex) { dwRes = ERROR_GEN_FAILURE; CALL_FAIL (WINDOW_ERR, TEXT("CListCtrl::InsertItem"), dwRes); return dwRes; } dwRes = UpdateLineTextAndIcon (*pintItemIndex, row); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (GENERAL_ERR, TEXT("UpdateLineTextAndIcon"), dwRes); return dwRes; } ASSERTION (ERROR_SUCCESS == dwRes); return dwRes; } // CFolderListView::AddItem
LRESULT CFolderListView::OnFolderAddChunk( WPARAM wParam, // Error code
LPARAM lParam // MSGS_MAP pointer
) /*++
Routine name : CFolderListView::OnFolderAddChunk
Routine description:
Called when a background folder thread brings a chunk of messages
Arguments:
wParam [in] - Thread error code lParam [in] - Pointer to MSGS_MAP.
Return Value:
Standard result code
--*/ { DBG_ENTER(TEXT("CFolderListView::OnFolderAddChunk")); DWORD dwRes = (DWORD) wParam; CObject* pObj = (CObject*)lParam;
if (ERROR_SUCCESS == dwRes) { OnUpdate (NULL, UPDATE_HINT_ADD_CHUNK, pObj); } else { PopupError (dwRes); } return 0; }
LRESULT CFolderListView::OnFolderRefreshEnded ( WPARAM wParam, // Error code
LPARAM lParam // CFolder pointer
) /*++
Routine name : CFolderListView::OnFolderRefreshEnded
Routine description:
Called when a background folder thread finishes its work.
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
wParam [in] - Thread error code lParam [in] - Pointer to CFolder that started the thread.
Return Value:
Standard result code
--*/ { DBG_ENTER(TEXT("CFolderListView::OnFolderRefreshEnded")); DWORD dwRes = (DWORD) wParam; CFolder *pFolder = (CFolder *) lParam;
if (ERROR_SUCCESS == dwRes) { CListCtrl &refCtrl = GetListCtrl(); m_HeaderCtrl.SetListControl (refCtrl.m_hWnd);
DoSort();
if(refCtrl.GetItemCount() > 0) { int iIndex = refCtrl.GetNextItem (-1, LVNI_SELECTED); if (-1 == iIndex) { //
// If there is no selection, set focus on the first item.
//
refCtrl.SetItemState (0, LVIS_FOCUSED, LVIS_FOCUSED); } else { //
// After sort, ensure the first selected item is visible
//
refCtrl.EnsureVisible (iIndex, FALSE); } } } else { PopupError (dwRes); } return 0; } // CFolderListView::OnFolderRefreshEnded
LRESULT CFolderListView::OnFolderInvalidate ( WPARAM wParam, // not in use
LPARAM lParam // CFolder pointer
) /*++
Routine name : CFolderListView::OnFolderRefreshEnded
Routine description:
Called by a background folder thread in order to remove the all its fax messages.
Arguments:
wParam [in] - Not in use lParam [in] - Pointer to CFolder that started the thread.
Return Value:
Standard result code
--*/ { DBG_ENTER(TEXT("CFolderListView::OnFolderInvalidate"));
CFolder *pFolder = (CFolder *) lParam; if(!pFolder) { ASSERTION_FAILURE; return 0; }
int iIndex; // View item index
CListCtrl &refCtrl = GetListCtrl();
LVFINDINFO lvfi = {0}; lvfi.flags = LVFI_PARAM;
CFaxMsg* pMsg; MSGS_MAP &msgMap = pFolder->GetData ();
pFolder->EnterData (); //
// Go through the folder's message map
//
for (MSGS_MAP::iterator it = msgMap.begin(); it != msgMap.end(); ++it) { pMsg = (*it).second;
//
// Delete the fax message from the view
//
lvfi.lParam = (LPARAM)pMsg; iIndex = refCtrl.FindItem (&lvfi); if(-1 != iIndex) { refCtrl.DeleteItem (iIndex); }
//
// Delete a fax message object
//
SAFE_DELETE (pMsg); } msgMap.clear(); pFolder->LeaveData ();
RecalcPossibleOperations ();
return 0; } // CFolderListView::OnFolderInvalidate
/***********************************
* * * Columns sort support * * * ***********************************/
int CFolderListView::CompareListItems ( CFaxMsg* pFaxMsg1, CFaxMsg* pFaxMsg2 ) /*++
Routine name : CFolderListView::CompareListItems
Routine description:
Compares two items in the list (callback)
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
pFaxMsg1 [in] - Item 1 pFaxMsg2 [in] - Item 2
Return Value:
-1 if item1 is smaler than item2 0 if identical +1 if item1 is bigger than item2
--*/ { DBG_ENTER(TEXT("CFolderListView::CompareListItems"));
//
// Make sure the we're sorting a valid column here
//
ASSERTION (m_nSortedCol >= 0); ASSERTION (m_nSortedCol <= GetLogicalColumnsCount());
//
// Get item index to sort by
//
DWORD dwItemIndex = ItemIndexFromLogicalColumnIndex (m_nSortedCol);
//
// Get comparison result
//
int iRes = m_bSortAscending ? CompareItems (pFaxMsg1, pFaxMsg2, dwItemIndex) : CompareItems (pFaxMsg2, pFaxMsg1, dwItemIndex);
return iRes; }
void CFolderListView::OnColumnClick( NMHDR* pNMHDR, LRESULT* pResult ) /*++
Routine name : CFolderListView::OnColumnClick
Routine description:
Handle mouse click on list header column (sort)
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
pNMHDR [in] - Header column information pResult [out] - Result
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::OnColumnClick"), TEXT("Type=%d"), m_Type);
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
DWORD dwItemIndex = ItemIndexFromLogicalColumnIndex (pNMListView->iSubItem); if(IsItemIcon(dwItemIndex)) { //
// no sort by icon
//
return; }
if( pNMListView->iSubItem == m_nSortedCol ) { m_bSortAscending = !m_bSortAscending; } else { m_bSortAscending = TRUE; } m_nSortedCol = pNMListView->iSubItem; DoSort(); *pResult = 0; } // CFolderListView::OnColumnClick
int CALLBACK CFolderListView::ListViewItemsCompareProc ( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort ) { DBG_ENTER(TEXT("CFolderListView::ListViewItemsCompareProc")); ASSERTION(m_psCurrentViewBeingSorted); ASSERTION(lParam1); ASSERTION(lParam2);
CFaxMsg* pFaxMsg1 = (CFaxMsg*)lParam1; CFaxMsg* pFaxMsg2 = (CFaxMsg*)lParam2;
DWORDLONG dwlId; try { dwlId = pFaxMsg1->GetId(); dwlId = pFaxMsg2->GetId(); } catch(...) { //
// The list control has invalid item
//
VERBOSE (DBG_MSG, TEXT("List control has invalid item")); ASSERTION(FALSE); return 0; }
return m_psCurrentViewBeingSorted->CompareListItems (pFaxMsg1, pFaxMsg2); }
DWORD CFolderListView::RefreshImageLists ( BOOL bForce ) /*++
Routine name : CFolderListView::RefreshImageLists
Routine description:
Loads the static list of images (icons) for the list control
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
bForce - [in] If TRUE, any existing image list is destroyed and replaced with new ones. If FALSE, existing image lists remain unchanged.
Return Value:
Standard Win32 error code
--*/ { DWORD dwRes = ERROR_SUCCESS; DBG_ENTER(TEXT("CFolderListView::RefreshImageLists"), dwRes);
CListCtrl& refCtrl = GetListCtrl();
if (bForce || (NULL == m_sReportIcons.m_hImageList)) { //
// Load image list of list view icons - 256 colors, pixel at 0,0 is mapped to background color during load
//
if(m_sReportIcons.m_hImageList) { ImageList_Destroy(m_sReportIcons.Detach()); } HIMAGELIST himl = ImageList_LoadImage( AfxGetResourceHandle(), MAKEINTRESOURCE(IDB_LIST_IMAGES), 16, 0, RGB(0, 255, 0), IMAGE_BITMAP, LR_LOADTRANSPARENT | LR_CREATEDIBSECTION); if (NULL == himl) { dwRes = GetLastError(); CALL_FAIL (RESOURCE_ERR, TEXT("ImageList_LoadImage"), dwRes); PopupError (dwRes); return dwRes; } m_sReportIcons.Attach (himl); } if (bForce || (NULL == m_sImgListDocIcon.m_hImageList)) { //
// Load the image list for the icons column and the up/down sort images - 16 colors.
//
if(m_sImgListDocIcon.m_hImageList) { ImageList_Destroy(m_sImgListDocIcon.Detach()); } dwRes = LoadDIBImageList (m_sImgListDocIcon, IDB_DOC_ICON, 16, RGB (214, 214, 214)); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (RESOURCE_ERR, TEXT("LoadDIBImageList"), dwRes); PopupError (dwRes); return dwRes; } } refCtrl.SetExtendedStyle (LVS_EX_FULLROWSELECT | // Entire row is selected
LVS_EX_INFOTIP);
refCtrl.SetImageList (&m_sReportIcons, LVSIL_SMALL); //
// Attach our custom header-control to the window of the list's header.
//
m_HeaderCtrl.SubclassWindow(refCtrl.GetHeaderCtrl()->m_hWnd); m_HeaderCtrl.SetImageList (&m_sImgListDocIcon); m_HeaderCtrl.SetListControl (refCtrl.m_hWnd); COLORREF crBkColor = ::GetSysColor(COLOR_WINDOW); refCtrl.SetBkColor(crBkColor); return dwRes; } // CFolderListView::RefreshImageLists
void CFolderListView::OnItemRightClick( NMHDR* pNMHDR, LRESULT* pResult ) /*++
Routine name : CFolderListView::OnItemRightClick
Routine description:
Handle mouse right-click on list items (popup context sensitive menu)
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
pNMHDR [in] - Item information pResult [out] - Result
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::OnItemRightClick"), TEXT("Type=%d"), m_Type); //
// Send WM_CONTEXTMENU to self
//
SendMessage(WM_CONTEXTMENU, (WPARAM) m_hWnd, GetMessagePos()); //
// Mark message as handled and suppress default handling
//
*pResult = 1; } // CFolderListView::OnItemRightClick
DWORD CFolderListView::GetServerPossibleOperations ( CFaxMsg* pMsg ) /*++
Routine name : CFolderListView::GetServerPossibleOperations
Routine description:
Retrieves operations possible on items according to server's security configuration.
Author:
Eran Yariv (EranY), Feb, 2000
Arguments:
Return Value:
Possible operations (JOB_OP*)
--*/ { DWORD dwRes = FAX_JOB_OP_ALL; DBG_ENTER(TEXT("CFolderListView::GetServerPossibleOperations"), dwRes); ASSERTION(pMsg);
CServerNode* pServer = pMsg->GetServer(); ASSERTION (pServer);
switch (m_Type) { case FOLDER_TYPE_INBOX: if (!pServer->CanManageInbox()) { //
// User cannot perform operations on the inbox
//
dwRes &= ~FAX_JOB_OP_DELETE; } break;
case FOLDER_TYPE_INCOMING: if (!pServer->CanManageAllJobs ()) { //
// User cannot perform operations on the incoming queue folder
//
dwRes &= ~(FAX_JOB_OP_DELETE | FAX_JOB_OP_PAUSE | FAX_JOB_OP_RESUME | FAX_JOB_OP_RESTART); } break;
case FOLDER_TYPE_OUTBOX: case FOLDER_TYPE_SENT_ITEMS: //
// User can do anything here
//
break;
default: ASSERTION_FAILURE; dwRes = 0; } return dwRes; } // CFolderListView::GetServerPossibleOperations
void CFolderListView::OnItemChanged( NMHDR* pNMHDR, LRESULT* pResult ) /*++
Routine name : CFolderListView::OnItemChanged
Routine description:
Handle selection changes of on list items
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
pNMHDR [in] - Item information pResult [out] - Result
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::OnItemChanged"), TEXT("Type=%d"), m_Type);
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
*pResult = 0;
if(m_bInMultiItemsOperation) { return; }
//
// Find out if a new item is selected or unselected.
//
if (pNMListView->iItem < 0) { //
// No item reported
//
return; } if (!(LVIF_STATE & (pNMListView->uChanged))) { //
// This is not a selection change report
//
return; } if ( ((pNMListView->uNewState) & LVIS_SELECTED) && !((pNMListView->uOldState) & LVIS_SELECTED)) { //
// Item changed from not-selected to selected.
// Change the possible operations the user can perform on selected items.
//
OnItemSelected((CFaxMsg*)pNMListView->lParam);
//
// If the folder is still refreshing and a command line argument asks for a specific
// message to be selected in this folder, then we mark that message in m_dwlMsgToSelect.
// Since the user just performed a manual selection of items, we no longer have to select anything for him.
//
m_dwlMsgToSelect = 0; } else if (!((pNMListView->uNewState) & LVIS_SELECTED) && ((pNMListView->uOldState) & LVIS_SELECTED)) { //
// Item changed from selected to not-selected
// Recalculate the possible operations the user can do on selected item.
OnItemUnSelected((CFaxMsg*)pNMListView->lParam);
//
// If the folder is still refreshing and a command line argument asks for a specific
// message to be selected in this folder, then we mark that message in m_dwlMsgToSelect.
// Since the user just performed a manual selection of items, we no longer have to select anything for him.
//
m_dwlMsgToSelect = 0; } } // CFolderListView::OnItemChanged
void CFolderListView::RecalcPossibleOperations () /*++
Routine name : CFolderListView::RecalcPossibleOperations
Routine description:
Recalculates the possible operation on the set of currently selected items.
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::RecalcPossibleOperations")); CListCtrl &refCtrl = GetListCtrl(); int iInd = -1; DWORD dwSelectedCount = refCtrl.GetSelectedCount (); m_dwPossibleOperationsOnSelectedItems = 0; ZeroMemory((PVOID)m_nImpossibleOperationsCounts, sizeof(m_nImpossibleOperationsCounts));
CFaxMsg* pFaxMsg = NULL; for (DWORD dwItems = 0; dwItems < dwSelectedCount; dwItems++) { iInd = refCtrl.GetNextItem (iInd, LVNI_SELECTED); if(iInd < 0) { CALL_FAIL (WINDOW_ERR, TEXT("CListCtrl::GetNextItem"), 0); break; } LPARAM lparam = (LPARAM) refCtrl.GetItemData (iInd);
OnItemSelected((CFaxMsg*)lparam); }
} // CFolderListView::RecalcPossibleOperations
void CFolderListView::OnItemSelected(CFaxMsg* pFaxMsg) /*++
Routine name : CFolderListView::OnItemSelected
Routine description:
Recalculates the possible operation due to item selection
Arguments:
pFaxMsg [in] selected fax message
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::OnItemSelected")); //
// Item changed from not-selected to selected.
// Change the possible operations the user can perform on selected items.
//
if(0 == m_dwPossibleOperationsOnSelectedItems) { m_dwPossibleOperationsOnSelectedItems = 0xFFFF; }
DWORD dwItemOperations = GetServerPossibleOperations(pFaxMsg) & pFaxMsg->GetPossibleOperations();
if (GetListCtrl().GetSelectedCount() > 1) { //
// If more than one item is selected, disable view and properties.
//
dwItemOperations &= ~(FAX_JOB_OP_VIEW | FAX_JOB_OP_PROPERTIES); }
m_dwPossibleOperationsOnSelectedItems &= dwItemOperations;
//
// Update impossible operations counts
//
DWORD dw; for(dw=0; dw < ARR_SIZE(m_nImpossibleOperationsCounts); ++dw) { if((dwItemOperations & 1) == 0) { //
// The operation is disabled.
//
m_nImpossibleOperationsCounts[dw]++; } dwItemOperations = dwItemOperations >> 1; }
} // CFolderListView::OnItemSelected
void CFolderListView::OnItemUnSelected(CFaxMsg* pFaxMsg) /*++
Routine name : CFolderListView::OnItemUnSelected
Routine description:
Recalculates the possible operation due to item unselect
Arguments:
pFaxMsg [in] unselected fax message
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::OnItemUnSelected")); CListCtrl &refCtrl = GetListCtrl(); DWORD dwSelectedCount = refCtrl.GetSelectedCount ();
if(dwSelectedCount <= 1) { m_dwPossibleOperationsOnSelectedItems = 0; ZeroMemory((PVOID)m_nImpossibleOperationsCounts, sizeof(m_nImpossibleOperationsCounts));
if(1 == dwSelectedCount) { int iInd = refCtrl.GetNextItem (-1, LVNI_SELECTED);
OnItemSelected((CFaxMsg*)refCtrl.GetItemData (iInd)); } return; }
DWORD dwItemOperations = GetServerPossibleOperations(pFaxMsg) & pFaxMsg->GetPossibleOperations(); DWORD dw; for(dw=0; dw < ARR_SIZE(m_nImpossibleOperationsCounts); ++dw) { if((dwItemOperations & 1) == 0) { //
// The operation is disabled for unselected item.
//
m_nImpossibleOperationsCounts[dw]--; ASSERTION(m_nImpossibleOperationsCounts[dw] >= 0); if(m_nImpossibleOperationsCounts[dw] == 0) { //
// Enable this operation
//
m_dwPossibleOperationsOnSelectedItems |= (1 << dw); } } dwItemOperations = dwItemOperations >> 1; }
} // CFolderListView::OnItemUnSelected
void CFolderListView::OnFolderItemView () /*++
Routine name : CFolderListView::OnFolderItemView
Routine description:
Handles message view commands
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::OnFolderItemView"), TEXT("Type=%d"), m_Type);
if(!(m_dwPossibleOperationsOnSelectedItems & FAX_JOB_OP_VIEW)) { //
// there is no TIF associated application
//
return; }
CString cstrTiff; DWORD dwRes = FetchTiff (cstrTiff); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (GENERAL_ERR, TEXT("CFolderListView::FetchTiff"), dwRes); PopupError (dwRes); return; } //
// Open the TIFF with associated application.
// All preview files are automatically removed once the application is shut down.
//
dwRes = ViewFile(cstrTiff); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (GENERAL_ERR, TEXT("ViewFile"), dwRes);
if(ERROR_NO_ASSOCIATION == dwRes) { AlignedAfxMessageBox(IDS_NO_OPEN_ASSOCIATION, MB_ICONSTOP); } else { PopupError (dwRes); } } else { if(FOLDER_TYPE_INBOX == m_Type) { theApp.InboxViewed(); } } } // CFolderListView::OnFolderItemView
void CFolderListView::OnFolderItemPrint () /*++
Routine name : CFolderListView::OnFolderItemPrint
Routine description:
Handles message print commands
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
Return Value:
None.
--*/ { DWORD dwRes; DBG_ENTER(TEXT("CFolderListView::OnFolderItemPrint"), TEXT("Type=%d"), m_Type);
HDC hPrinter; if (IsWinXPOS()) { //
// Use new look of printer selection dialog
//
C_PrintDialogEx prnDlg(FALSE, PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS | PD_NOSELECTION | PD_RETURNDC); if(IDOK != prnDlg.DoModal()) { CALL_FAIL (GENERAL_ERR, TEXT("C_PrintDialogEx::DoModal"), CommDlgExtendedError()); return; } hPrinter = prnDlg.GetPrinterDC(); if(!hPrinter) { dwRes = ERROR_CAN_NOT_COMPLETE; CALL_FAIL (GENERAL_ERR, TEXT("C_PrintDialogEx::GetPrinterDC"), dwRes); return; } } else { //
// Use legacy printer selection dialog
//
CPrintDialog prnDlg(FALSE); if(IDOK != prnDlg.DoModal()) { return; } hPrinter = prnDlg.GetPrinterDC(); if(!hPrinter) { dwRes = ERROR_CAN_NOT_COMPLETE; CALL_FAIL (GENERAL_ERR, TEXT("CPrintDialog::GetPrinterDC"), dwRes); return; } }
CString cstrTiff; dwRes = FetchTiff (cstrTiff); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (GENERAL_ERR, TEXT("CFolderListView::FetchTiff"), dwRes); PopupError (dwRes); return; }
if(!TiffPrintDC(cstrTiff, hPrinter)) { dwRes = GetLastError(); CALL_FAIL (GENERAL_ERR, TEXT("TiffPrintDC"), dwRes); goto exit; }
exit: if(hPrinter) { CDC::FromHandle(hPrinter)->DeleteDC(); }
if (!DeleteFile (cstrTiff)) { dwRes = GetLastError (); CALL_FAIL (FILE_ERR, TEXT("DeleteFile"), dwRes); } } // CFolderListView::OnFolderItemPrint
void CFolderListView::OnFolderItemCopy () /*++
Routine name : CFolderListView::OnFolderItemCopy
Routine description:
Handles message copy commands
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::OnFolderItemCopy"), TEXT("Type=%d"), m_Type);
CString cstrTiff; DWORD dwRes = FetchTiff (cstrTiff); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (GENERAL_ERR, TEXT("CFolderListView::FetchTiff"), dwRes); PopupError (dwRes); return; }
CString cstrFileName; CString cstrFilterFormat;
TCHAR szFile[MAX_PATH] = {0}; TCHAR szFilter[MAX_PATH] = {0}; OPENFILENAME ofn = {0}; //
// get tif file name
//
int nFileNamePos = cstrTiff.ReverseFind(TEXT('\\')); ASSERTION(nFileNamePos > 0); nFileNamePos++;
try { cstrFileName = cstrTiff.Right(cstrTiff.GetLength() - nFileNamePos); } catch(...) { dwRes = ERROR_NOT_ENOUGH_MEMORY; CALL_FAIL (MEM_ERR, TEXT("CString::operator="), dwRes); PopupError (dwRes); goto del_file; }
_tcscpy(szFile, cstrFileName);
dwRes = LoadResourceString(cstrFilterFormat, IDS_SAVE_AS_FILTER_FORMAT); if (ERROR_SUCCESS != dwRes) { ASSERTION_FAILURE; CALL_FAIL (RESOURCE_ERR, TEXT("LoadResourceString"), dwRes); goto del_file; }
_stprintf(szFilter, cstrFilterFormat, FAX_TIF_FILE_MASK, 0, FAX_TIF_FILE_MASK, 0);
ofn.lStructSize = GetOpenFileNameStructSize(); ofn.hwndOwner = m_hWnd; ofn.lpstrFilter = szFilter; ofn.lpstrFile = szFile; ofn.nMaxFile = ARR_SIZE(szFile); ofn.lpstrDefExt = FAX_TIF_FILE_EXT; ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_ENABLEHOOK; ofn.lpfnHook = OFNHookProc;
if(!GetSaveFileName(&ofn)) { goto del_file; }
{ //
// SHFILEOPSTRUCT::pFrom should ends with double NULL
//
TCHAR tszSrcFile[MAX_PATH+1] = {0}; _tcsncpy(tszSrcFile, cstrTiff, MAX_PATH);
//
// move the file
//
SHFILEOPSTRUCT shFileOpStruct = {0};
shFileOpStruct.wFunc = FO_MOVE; shFileOpStruct.fFlags = FOF_SILENT; // Don't display file move progress dialog
shFileOpStruct.pFrom = tszSrcFile; shFileOpStruct.pTo = szFile;
if(!SHFileOperation(&shFileOpStruct)) { //
// success
//
return; } else { dwRes = ERROR_CAN_NOT_COMPLETE; CALL_FAIL (GENERAL_ERR, TEXT("SHFileOperation"), dwRes); goto del_file; } }
del_file: if (!DeleteFile (cstrTiff)) { dwRes = GetLastError (); CALL_FAIL (FILE_ERR, TEXT("DeleteFile"), dwRes); }
} // CFolderListView::OnFolderItemCopy
void CFolderListView::OnUpdateFolderItemSendMail( CCmdUI* pCmdUI ) { pCmdUI->Enable( (m_dwPossibleOperationsOnSelectedItems & FAX_JOB_OP_VIEW) && (m_dwPossibleOperationsOnSelectedItems & FAX_JOB_OP_PROPERTIES) && theApp.IsMapiEnable()); }
void CFolderListView::OnUpdateFolderItemView( CCmdUI* pCmdUI ) { OnUpdateFolderItemPrint(pCmdUI); }
void CFolderListView::OnUpdateFolderItemPrint( CCmdUI* pCmdUI ) { pCmdUI->Enable( (m_dwPossibleOperationsOnSelectedItems & FAX_JOB_OP_VIEW) && (m_dwPossibleOperationsOnSelectedItems & FAX_JOB_OP_PROPERTIES)); }
void CFolderListView::OnUpdateFolderItemCopy( CCmdUI* pCmdUI ) { pCmdUI->Enable( (m_dwPossibleOperationsOnSelectedItems & FAX_JOB_OP_VIEW) && (m_dwPossibleOperationsOnSelectedItems & FAX_JOB_OP_PROPERTIES)); }
void CFolderListView::OnFolderItemMail () /*++
Routine name : CFolderListView::OnFolderItemMail
Routine description:
Handles message mail commands
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::OnFolderItemMail"), TEXT("Type=%d"), m_Type);
CString cstrTiff; DWORD dwRes = FetchTiff (cstrTiff); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (GENERAL_ERR, TEXT("CFolderListView::FetchTiff"), dwRes); PopupError (dwRes); return; }
//
// create a new mail message with tif file attached
//
dwRes = theApp.SendMail(cstrTiff); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (GENERAL_ERR, TEXT("CClientConsoleApp::SendMail"), dwRes); PopupError (dwRes); }
if (!DeleteFile (cstrTiff)) { dwRes = GetLastError (); CALL_FAIL (FILE_ERR, TEXT("DeleteFile"), dwRes); } } // CFolderListView::OnFolderItemMail
void CFolderListView::OnFolderItemProperties () /*++
Routine name : CFolderListView::OnFolderItemProperties
Routine description:
Handles message properties commands
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::OnFolderItemProperties"), TEXT("Type=%d"), m_Type);
//
// Make sure there's exaclty one elemented selected
//
CListCtrl &refCtrl = GetListCtrl(); ASSERTION (1 == refCtrl.GetSelectedCount()); int iInd = refCtrl.GetNextItem (-1, LVNI_SELECTED); ASSERTION (0 <= iInd); CFaxMsg* pMsg = (CFaxMsg*)(refCtrl.GetItemData (iInd)); ASSERTION (pMsg);
CServerNode* pServer = pMsg->GetServer(); ASSERTION (pServer);
CItemPropSheet propSheet(IDS_PROPERTIES_SHEET_CAPTION); DWORD dwRes = propSheet.Init(pServer->GetFolder(m_Type), pMsg); if(ERROR_SUCCESS != dwRes) { PopupError (dwRes); return; }
dwRes = propSheet.DoModal(); if(IDABORT == dwRes) { PopupError (propSheet.GetLastError()); }
} // CFolderListView::OnFolderItemProperties
DWORD CFolderListView::OpenSelectColumnsDlg() /*++
Routine name : CFolderListView::OpenSelectColumnsDlg
Routine description:
opens column select dialog and reorders the columns
Author:
Alexander Malysh (AlexMay), Jan, 2000
Arguments:
Return Value:
Error code
--*/ { DWORD dwRes = ERROR_SUCCESS; DBG_ENTER(TEXT("CFolderListView::OpenSelectColumnsDlg"), TEXT("Type=%d"), m_Type);
ASSERTION(NULL != m_pnColumnsOrder); ASSERTION(NULL != m_pViewColumnInfo);
DWORD dwCount = GetLogicalColumnsCount();
//
// init header string array
//
CString* pcstrHeaders; try { pcstrHeaders = new CString[dwCount]; } catch (...) { dwRes = ERROR_NOT_ENOUGH_MEMORY; CALL_FAIL (MEM_ERR, TEXT ("new CString[dwCount]"), dwRes); return dwRes; }
int nItemIndex; for (DWORD dw = 0; dw < dwCount; ++dw) { nItemIndex = ItemIndexFromLogicalColumnIndex(dw); dwRes = GetColumnHeaderString (pcstrHeaders[dw], nItemIndex); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (GENERAL_ERR, TEXT("GetColumnHeaderString"), dwRes); delete[] pcstrHeaders; return dwRes; } }
//
// save width
//
int nIndex; for (dw = 0; dw < m_dwDisplayedColumns; ++dw) { nIndex = m_pnColumnsOrder[dw]; ASSERTION(nIndex >= 0 && nIndex < dwCount);
m_pViewColumnInfo[nIndex].nWidth = GetListCtrl().GetColumnWidth(nIndex); }
//
// start column select dialog
//
CColumnSelectDlg dlg(pcstrHeaders, m_pnColumnsOrder, dwCount, m_dwDisplayedColumns); if(IDOK == dlg.DoModal()) { for (dw = 0; dw < dwCount; ++dw) { nIndex = m_pnColumnsOrder[dw]; ASSERTION(nIndex >= 0 && nIndex < dwCount);
m_pViewColumnInfo[nIndex].dwOrder = dw; m_pViewColumnInfo[nIndex].bShow = (dw < m_dwDisplayedColumns); }
//
// if sorted column is hidden then no sort
//
if(m_nSortedCol >= 0) { ASSERTION(m_nSortedCol < dwCount); if(!m_pViewColumnInfo[m_nSortedCol].bShow) { m_nSortedCol = -1; } } ColumnsToLayout(); }
delete[] pcstrHeaders;
return dwRes;
} // CFolderListView::OpenSelectColumnsDlg
DWORD CFolderListView::ColumnsToLayout() /*++
Routine name : CFolderListView::ColumnsToLayout
Routine description:
reorders columns according to saved layout
Author:
Alexander Malysh (AlexMay), Jan, 2000
Arguments:
Return Value:
Standard Win32 error code
--*/ { DWORD dwRes = ERROR_SUCCESS; DBG_ENTER(TEXT("CFolderListView::ColumnsToLayout"), dwRes);
ASSERTION(NULL != m_pnColumnsOrder); ASSERTION(NULL != m_pViewColumnInfo);
CListCtrl &refCtrl = GetListCtrl(); DWORD dwCount = GetLogicalColumnsCount(); CSize size; CDC* pHdrDc = refCtrl.GetHeaderCtrl()->GetDC();
//
// set column order
//
if(!refCtrl.SetColumnOrderArray(dwCount, m_pnColumnsOrder)) { dwRes = ERROR_GEN_FAILURE; CALL_FAIL (WINDOW_ERR, TEXT("CListCtrl::SetColumnOrderArray"), dwRes); return dwRes; }
//
// set column width
//
DWORD dwItemIndex; CString cstrColumnText; for (DWORD dwCol = 0; dwCol < dwCount; ++dwCol) { if(m_pViewColumnInfo[dwCol].bShow) { if(m_pViewColumnInfo[dwCol].nWidth < 0) { dwItemIndex = ItemIndexFromLogicalColumnIndex(dwCol); dwRes = GetColumnHeaderString (cstrColumnText, dwItemIndex); if(ERROR_SUCCESS != dwRes) { CALL_FAIL (GENERAL_ERR, TEXT("GetColumnHeaderString"), dwRes); return dwRes; }
size = pHdrDc->GetTextExtent(cstrColumnText); refCtrl.SetColumnWidth (dwCol, size.cx * 1.5); } else { refCtrl.SetColumnWidth (dwCol, m_pViewColumnInfo[dwCol].nWidth); } } else { refCtrl.SetColumnWidth (dwCol, 0); } }
Invalidate();
return dwRes;
} // CFolderListView::ColumnsToLayout
DWORD CFolderListView::ReadLayout( LPCTSTR lpszViewName ) /*++
Routine name : CFolderListView::ReadLayout
Routine description:
reads column layout from registry
Author:
Alexander Malysh (AlexMay), Jan, 2000
Arguments:
lpszSection [in] - registry section
Return Value:
Standard Win32 error code
--*/ { DWORD dwRes = ERROR_SUCCESS; DBG_ENTER(TEXT("CFolderListView::ReadLayout"), dwRes, TEXT("Type=%d"), m_Type);
ASSERTION(NULL == m_pnColumnsOrder); ASSERTION(NULL == m_pViewColumnInfo);
//
// columns order array allocation
//
DWORD dwCount = GetLogicalColumnsCount(); try { m_pnColumnsOrder = new int[dwCount]; } catch (...) { dwRes = ERROR_NOT_ENOUGH_MEMORY; CALL_FAIL (MEM_ERR, TEXT ("m_pdwColumnsOrder = new int[dwCount]"), dwRes); return dwRes; } for(DWORD dw=0; dw < dwCount; ++dw) { m_pnColumnsOrder[dw] = -1; } //
// columns info array allocation
//
try { m_pViewColumnInfo = new TViewColumnInfo[dwCount]; } catch (...) { dwRes = ERROR_NOT_ENOUGH_MEMORY; CALL_FAIL (MEM_ERR, TEXT ("new CString[dwCount]"), dwRes); return dwRes; }
//
// reads columns layout from registry
//
CString cstrSection; m_dwDisplayedColumns = 0; for(dw=0; dw < dwCount; ++dw) { try { cstrSection.Format(TEXT("%s\\%s\\%02d"), lpszViewName, CLIENT_VIEW_COLUMNS, dw); } catch(...) { dwRes = ERROR_NOT_ENOUGH_MEMORY; CALL_FAIL (MEM_ERR, TEXT("CString::Format"), dwRes); return dwRes; }
m_pViewColumnInfo[dw].bShow = theApp.GetProfileInt(cstrSection, CLIENT_VIEW_COL_SHOW, (dw < m_dwDefaultColNum) ? 1 : 0); if(m_pViewColumnInfo[dw].bShow) { ++m_dwDisplayedColumns; }
m_pViewColumnInfo[dw].nWidth = theApp.GetProfileInt(cstrSection, CLIENT_VIEW_COL_WIDTH, -1); m_pViewColumnInfo[dw].dwOrder = theApp.GetProfileInt(cstrSection, CLIENT_VIEW_COL_ORDER, dw); if(m_pViewColumnInfo[dw].dwOrder < dwCount) { m_pnColumnsOrder[m_pViewColumnInfo[dw].dwOrder] = dw; } else { ASSERTION_FAILURE; } }
//
// check column order consistence
//
for(dw=0; dw < dwCount; ++dw) { ASSERTION(m_pnColumnsOrder[dw] >= 0); } //
// read sort parameters
//
m_bSortAscending = theApp.GetProfileInt(lpszViewName, CLIENT_VIEW_SORT_ASCENDING, 1); m_nSortedCol = theApp.GetProfileInt(lpszViewName, CLIENT_VIEW_SORT_COLUMN, 1); if(m_nSortedCol >= dwCount) { m_nSortedCol = 0; }
return dwRes;
} // CFolderListView::ReadLayout
DWORD CFolderListView::SaveLayout( LPCTSTR lpszViewName ) /*++
Routine name : CFolderListView::SaveLayout
Routine description:
saves column layout to registry
Author:
Alexander Malysh (AlexMay), Jan, 2000
Arguments:
lpszSection [in] - registry section
Return Value:
Standard Win32 error code
--*/ { DWORD dwRes = ERROR_SUCCESS; DBG_ENTER(TEXT("CFolderListView::SaveLayout"), dwRes, TEXT("Type=%d"), m_Type); if(!m_bColumnsInitialized) { return dwRes; }
ASSERTION(m_pViewColumnInfo != NULL);
//
// save column layout to registry
//
BOOL bRes; DWORD dwWidth; CString cstrSection; DWORD dwCount = GetLogicalColumnsCount(); for(DWORD dw=0; dw < dwCount; ++dw) { try { cstrSection.Format(TEXT("%s\\%s\\%02d"), lpszViewName, CLIENT_VIEW_COLUMNS, dw); } catch(...) { dwRes = ERROR_NOT_ENOUGH_MEMORY; CALL_FAIL (MEM_ERR, TEXT("CString::Format"), dwRes); return dwRes; }
bRes = theApp.WriteProfileInt(cstrSection, CLIENT_VIEW_COL_SHOW, m_pViewColumnInfo[dw].bShow); bRes = theApp.WriteProfileInt(cstrSection, CLIENT_VIEW_COL_ORDER, m_pViewColumnInfo[dw].dwOrder); dwWidth = m_pViewColumnInfo[dw].bShow ? GetListCtrl().GetColumnWidth(dw) : -1; bRes = theApp.WriteProfileInt(cstrSection, CLIENT_VIEW_COL_WIDTH, dwWidth); }
//
// save sort parameters
//
bRes = theApp.WriteProfileInt(lpszViewName, CLIENT_VIEW_SORT_ASCENDING, m_bSortAscending); bRes = theApp.WriteProfileInt(lpszViewName, CLIENT_VIEW_SORT_COLUMN, m_nSortedCol);
return dwRes;
} // CFolderListView::SaveLayout
BOOL CFolderListView::OnNotify( WPARAM wParam, LPARAM lParam, LRESULT* pResult ) /*++
Routine name : CFolderListView::OnNotify
Routine description:
disables resizing of hidden columns
Author:
Alexander Malysh (AlexMay), Jan, 2000
Arguments:
wParam [in] - Identifies the control that sends the message lParam [in] - NMHEADER* pResult [out] - result
Return Value:
TRUE if message processed, FALSE otherwise.
--*/ { int i=0; switch (((NMHEADER*)lParam)->hdr.code) { case HDN_BEGINTRACKA: case HDN_BEGINTRACKW: case HDN_DIVIDERDBLCLICKA: case HDN_DIVIDERDBLCLICKW: DBG_ENTER(TEXT("CFolderListView::OnNotify"));
//
// get column index
//
DWORD dwIndex = ((NMHEADER*)lParam)->iItem; ASSERTION(NULL != m_pViewColumnInfo); ASSERTION(dwIndex < GetLogicalColumnsCount());
//
// ignore if hidden column
//
if(!m_pViewColumnInfo[dwIndex].bShow ) { *pResult = TRUE; return TRUE; } }
return CListView::OnNotify(wParam, lParam, pResult );
} // CFolderListView::OnNotify
void CFolderListView::DoSort() { if (m_bSorting || m_nSortedCol < 0) { //
// Already sorting or no sorting column
//
return; }
CWaitCursor waitCursor;
m_bSorting = TRUE;
CMainFrame *pFrm = GetFrm(); if (!pFrm) { //
// Shutdown in progress
//
} else { pFrm->RefreshStatusBar (); }
m_psCurrentViewBeingSorted = this; GetListCtrl().SortItems (ListViewItemsCompareProc, 0); m_HeaderCtrl.SetSortImage( m_nSortedCol, m_bSortAscending ); m_bSorting = FALSE; }
DWORD CFolderListView::RemoveItem ( LPARAM lparam, int iIndex /* = -1 */ ) /*++
Routine name : CFolderListView::RemoveItem
Routine description:
Removes an item from the list by its message / job pointer
Author:
Eran Yariv (EranY), Feb, 2000
Arguments:
lparam [in] - Message / Job pointer iIndex [in] - Optional item index in the control (for optimization)
Return Value:
Standard Win32 error code
--*/ { DWORD dwRes = ERROR_SUCCESS; DBG_ENTER(TEXT("CFolderListView::RemoveItem"), dwRes, TEXT("Type=%d"), m_Type);
CListCtrl &refCtrl = GetListCtrl(); if (-1 == iIndex) { //
// Item index no supplied - search for it
//
LVFINDINFO lvfi; lvfi.flags = LVFI_PARAM; lvfi.lParam = lparam; iIndex = refCtrl.FindItem (&lvfi); } if (-1 == iIndex) { //
// item already removed
//
CALL_FAIL (RESOURCE_ERR, TEXT("CListCtrl::FindItem"), dwRes); return dwRes; } BOOL bItemSelected = IsSelected (iIndex); //
// Now erase the item
//
if (!refCtrl.DeleteItem (iIndex)) { //
// Failed to delete the item
//
dwRes = ERROR_GEN_FAILURE; CALL_FAIL (RESOURCE_ERR, TEXT("CListCtrl::DeleteItem"), dwRes); return dwRes; }
if (bItemSelected) { //
// If the item that we just removed was selected, we have to re-compute
// the possible operations on the rest of the selected items.
//
if (!m_bInMultiItemsOperation) { //
// Only recalc if we operate on few items.
//
RecalcPossibleOperations (); } } ASSERTION (ERROR_SUCCESS == dwRes); return dwRes; } // CFolderListView::RemoveItem
DWORD CFolderListView::FindInsertionIndex ( LPARAM lparamItemData, DWORD &dwResultIndex ) /*++
Routine name : CFolderListView::FindInsertionIndex
Routine description:
Finds an insertion index for a new item to the list, according to sort settings.
This function must be called when the data critical section is held.
Author:
Eran Yariv (EranY), Feb, 2000
Arguments:
lparamItemData [in] - Pointer to item dwResultIndex [out] - Insertion index
Return Value:
Standard Win32 error code
--*/ { DWORD dwRes = ERROR_SUCCESS; DBG_ENTER(TEXT("CFolderListView::FindInsertionIndex"), dwRes, TEXT("Type=%d"), m_Type);
CListCtrl &refCtrl = GetListCtrl(); DWORD dwNumItems = refCtrl.GetItemCount (); if (!dwNumItems || (-1 == m_nSortedCol)) { //
// List is not sorted or is empty, always add at the end
//
VERBOSE (DBG_MSG, TEXT("Insertion point at index %ld"), dwResultIndex); dwResultIndex = dwNumItems; return dwRes; } //
// Get item index to sort by
//
DWORD dwItemIndex = ItemIndexFromLogicalColumnIndex (m_nSortedCol);
//
// Check if item can be placed in beginning of list (no search required)
//
LPARAM lparamTop = refCtrl.GetItemData (0); // Pointer to item in top index
LPARAM lparamBottom = refCtrl.GetItemData (dwNumItems - 1); // Pointer to item in bottom index
ASSERTION (lparamTop && lparamBottom); //
// Get comparison result against top index
//
int iRes = CompareItems ((CFaxMsg*)lparamItemData, (CFaxMsg*)lparamTop, dwItemIndex); ASSERTION ((-1 <= iRes) && (+1 >= iRes)); if (!m_bSortAscending) { iRes *= -1; } switch (iRes) { case -1: // Item is smaller than top
case 0: // Item is identical to top
//
// Insert new item before top index
//
dwResultIndex = 0; VERBOSE (DBG_MSG, TEXT("Insertion point at index %ld"), dwResultIndex); return dwRes;
default: // Item is bigger than top
//
// Do nothing
//
break; } //
// Check if item can be placed in bottom of list (no search required)
//
//
// Get comparison result against bottom index
//
iRes = CompareItems ((CFaxMsg*)lparamItemData, (CFaxMsg*)lparamBottom, dwItemIndex); ASSERTION ((-1 <= iRes) && (+1 >= iRes)); if (!m_bSortAscending) { iRes *= -1; } switch (iRes) { case +1: // Item is bigger than bottom
case 0: // Item is identical to bottom
//
// Insert new item at the bottom index
//
dwResultIndex = dwNumItems; VERBOSE (DBG_MSG, TEXT("Insertion point at index %ld"), dwResultIndex); return dwRes;
default: // Item is smaller than bottom
//
// Do nothing
//
break; } //
// Search for insertion point
//
dwRes = BooleanSearchInsertionPoint (0, dwNumItems - 1, lparamItemData, dwItemIndex, dwResultIndex); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (GENERAL_ERR, TEXT("BooleanSearchInsertionPoint"), dwRes); return dwRes; } return dwRes; } // CFolderListView::FindInsertionIndex
DWORD CFolderListView::BooleanSearchInsertionPoint ( DWORD dwTopIndex, DWORD dwBottomIndex, LPARAM lparamItemData, DWORD dwItemIndex, DWORD &dwResultIndex ) /*++
Routine name : CFolderListView::BooleanSearchInsertionPoint
Routine description:
Recursively searches an insertion point for a list item. Performs a boolean search.
This function must be called when the data critical section is held.
Author:
Eran Yariv (EranY), Feb, 2000
Arguments:
dwTopIndex [in] - Top list index dwBottomIndex [in] - Bottom list index lparamItemData [in] - Pointer to item dwItemIndex [in] - Logical column item to compare by dwResultIndex [out] - Insertion index
Return Value:
Standard Win32 error code
--*/ { DWORD dwRes = ERROR_SUCCESS; DBG_ENTER(TEXT("CFolderListView::BooleanSearchInsertionPoint"), dwRes);
ASSERTION (dwTopIndex <= dwBottomIndex);
if ((dwTopIndex == dwBottomIndex) || (dwTopIndex + 1 == dwBottomIndex)) { dwResultIndex = dwBottomIndex; VERBOSE (DBG_MSG, TEXT("Insertion point at index %ld"), dwResultIndex); return dwRes; } DWORD dwMiddleIndex = dwTopIndex + (dwBottomIndex - dwTopIndex) / 2; ASSERTION ((dwMiddleIndex != dwBottomIndex) && (dwMiddleIndex != dwTopIndex));
CListCtrl &refCtrl = GetListCtrl();
LPARAM lparamMiddle = refCtrl.GetItemData (dwMiddleIndex); // Pointer to item in middle index
ASSERTION (lparamMiddle); //
// Get comparison result against middle index
//
int iRes = CompareItems ((CFaxMsg*)lparamItemData, (CFaxMsg*)lparamMiddle, dwItemIndex); ASSERTION ((-1 <= iRes) && (+1 >= iRes)); if (!m_bSortAscending) { iRes *= -1; } switch (iRes) { case -1: // Item is smaller than middle
case 0: // Item is identical to middle
//
// Search between top and middle
//
dwRes = BooleanSearchInsertionPoint (dwTopIndex, dwMiddleIndex, lparamItemData, dwItemIndex, dwResultIndex); break;
default: // Item is bigger than middle
//
// Search between middle and bottom
//
dwRes = BooleanSearchInsertionPoint (dwMiddleIndex, dwBottomIndex, lparamItemData, dwItemIndex, dwResultIndex); break; } if (ERROR_SUCCESS != dwRes) { CALL_FAIL (GENERAL_ERR, TEXT("BooleanSearchInsertionPoint"), dwRes); } return dwRes; } // CFolderListView::BooleanSearchInsertionPoint
DWORD CFolderListView::AddSortedItem ( CViewRow &row, LPARAM lparamItemData ) /*++
Routine name : CFolderListView::AddSortedItem
Routine description:
Adds an item to the list, preserving list sort order.
This function must be called when the data critical section is held.
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
row [in] - Row of item view information lparamItemData [in] - Item associated data
Return Value:
Standard Win32 error code
--*/ { DWORD dwRes = ERROR_SUCCESS; DBG_ENTER(TEXT("CFolderListView::AddSortedItem"), dwRes, TEXT("Type=%d"), m_Type);
DWORD dwResultIndex; //
// Find insertion index according to sort order
//
dwRes = FindInsertionIndex (lparamItemData, dwResultIndex); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (GENERAL_ERR, TEXT("FindInsertionIndex"), dwRes); return dwRes; } //
// Add new item in insertion index
//
int iItemIndex; dwRes = AddItem (dwResultIndex, row, lparamItemData, &iItemIndex); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (GENERAL_ERR, TEXT("AddItem"), dwRes); return dwRes; }
ASSERTION (ERROR_SUCCESS == dwRes); return dwRes; } // CFolderListView::AddSortedItem
DWORD CFolderListView::UpdateSortedItem ( CViewRow &row, LPARAM lparamItemData ) /*++
Routine name : CFolderListView::UpdateSortedItem
Routine description:
Updates an item in the list, preserving list sort order.
This function must be called when the data critical section is held.
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
row [in] - Row of item view information lparamItemData [in] - Item associated data
Return Value:
Standard Win32 error code
--*/ { DWORD dwRes = ERROR_SUCCESS; DBG_ENTER(TEXT("CFolderListView::UpdateSortedItem"), dwRes, TEXT("Type=%d"), m_Type);
//
// Find the item in the list
//
CListCtrl &refCtrl = GetListCtrl(); LVFINDINFO lvfi; lvfi.flags = LVFI_PARAM; lvfi.lParam = lparamItemData; int iCurIndex = refCtrl.FindItem (&lvfi); if (-1 == iCurIndex) { dwRes = ERROR_NOT_FOUND; CALL_FAIL (RESOURCE_ERR, TEXT("CListCtrl::FindItem"), dwRes); return dwRes; } #ifdef _DEBUG
LPARAM lparamCurrentItem = refCtrl.GetItemData (iCurIndex); ASSERTION (lparamCurrentItem == lparamItemData); #endif
BOOL bJustUpdate = TRUE; // If TRUE, we don't move the item in the list
if (0 <= m_nSortedCol) { //
// List is sorted.
// See if the displayed text is different than the updated text
//
CString cstrDisplayedCell; try { cstrDisplayedCell = refCtrl.GetItemText (iCurIndex, m_nSortedCol); } catch (...) { dwRes = ERROR_NOT_ENOUGH_MEMORY; CALL_FAIL (MEM_ERR, TEXT ("CString::operator ="), dwRes); return dwRes; } //
// Get item index to sort by
//
DWORD dwItemIndex = ItemIndexFromLogicalColumnIndex (m_nSortedCol); const CString &cstrUpdatedString = row.GetItemString(dwItemIndex); if (cstrUpdatedString.Compare (cstrDisplayedCell)) { //
// Text in the sorted column is about to change.
// Sorry, but we must:
// 1. Remove old item from list
// 2. Insert new item (sorted)
//
bJustUpdate = FALSE; } } if (bJustUpdate) { //
// All we need to do is update the text of the list item (all sub items) and its icon
//
dwRes = UpdateLineTextAndIcon (iCurIndex, row); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (RESOURCE_ERR, TEXT("UpdateLineTextAndIcon"), dwRes); return dwRes; } } else { //
// Since the text in the sorted column is different than the new text,
// we must remove the current item and insert a new (sorted) item.
//
BOOL bItemSelected = IsSelected (iCurIndex); refCtrl.SetRedraw (FALSE); if (!refCtrl.DeleteItem (iCurIndex)) { //
// Failed to delete the item
//
dwRes = ERROR_GEN_FAILURE; refCtrl.SetRedraw (TRUE); CALL_FAIL (RESOURCE_ERR, TEXT("CListCtrl::DeleteItem"), dwRes); return dwRes; } dwRes = AddSortedItem (row, lparamItemData); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (RESOURCE_ERR, TEXT("AddSortedItem"), dwRes); refCtrl.SetRedraw (TRUE); return dwRes; } if (bItemSelected) { //
// Since the item we removed was selected, we must also selected the new item
// we just added.
// Recalculate the possible operations the user can do on selected item.
//
Select (iCurIndex, TRUE); RecalcPossibleOperations (); } refCtrl.SetRedraw (TRUE); }
ASSERTION (ERROR_SUCCESS == dwRes); return dwRes; } // CFolderListView::UpdateSortedItem
DWORD CFolderListView::ConfirmItemDelete( BOOL& bConfirm ) { DWORD dwRes = ERROR_SUCCESS; DBG_ENTER(TEXT("CFolderListView::ConfirmItemDelete"), dwRes);
//
// do we should ask to confirm ?
//
BOOL bAsk = theApp.GetProfileInt(CLIENT_CONFIRM_SEC, CLIENT_CONFIRM_ITEM_DEL, 1); if(!bAsk) { bConfirm = TRUE; return dwRes; }
CListCtrl &refCtrl = GetListCtrl(); DWORD dwSelected = refCtrl.GetSelectedCount(); ASSERTION (dwSelected > 0);
//
// prepare message string
//
CString cstrMsg; if(1 == dwSelected) { dwRes = LoadResourceString(cstrMsg, IDS_SURE_DELETE_ONE); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (RESOURCE_ERR, TEXT("LoadResourceString"), dwRes); return dwRes; } } else { //
// more then 1 selected
//
CString cstrCount; try { cstrCount.Format(TEXT("%d"), dwSelected); } catch(...) { dwRes = ERROR_NOT_ENOUGH_MEMORY; CALL_FAIL (MEM_ERR, TEXT("CString::Format"), dwRes); return dwRes; }
try { AfxFormatString1(cstrMsg, IDS_SURE_DELETE_MANY, cstrCount); } catch(...) { dwRes = ERROR_NOT_ENOUGH_MEMORY; CALL_FAIL (MEM_ERR, TEXT("AfxFormatString1"), dwRes); return dwRes; } }
//
// are you sure ?
//
DWORD dwAskRes = AlignedAfxMessageBox(cstrMsg, MB_YESNO | MB_ICONQUESTION); bConfirm = (IDYES == dwAskRes);
return dwRes;
} // CFolderListView::ConfirmItemDelete
void CFolderListView::OnDblClk( NMHDR* pNMHDR, LRESULT* pResult ) { DWORD nItem = ((NM_LISTVIEW*)pNMHDR)->iItem;
CListCtrl &refCtrl = GetListCtrl(); DWORD dwSelected = refCtrl.GetSelectedCount(); DWORD dwSelItem = refCtrl.GetNextItem (-1, LVNI_SELECTED); if(1 == dwSelected && dwSelItem == nItem) { OnFolderItemView(); }
*pResult = 0; }
DWORD CFolderListView::FetchTiff ( CString &cstrTiff ) /*++
Routine name : CFolderListView::FetchTiff
Routine description:
Fetches the TIFF image of the selected list item
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
cstrTiff [out] - Name of local TIFF file
Return Value:
Standard Win32 error code
--*/ { DWORD dwRes = ERROR_SUCCESS; DBG_ENTER(TEXT("CFolderListView::FetchTiff"), dwRes); //
// Make sure there's exaclty one elemented selected
//
CListCtrl &refCtrl = GetListCtrl(); if (1 != refCtrl.GetSelectedCount()) { return ERROR_CANTOPEN; } int iInd = refCtrl.GetNextItem (-1, LVNI_SELECTED); if (0 > iInd) { return ERROR_CANTOPEN; } CFaxMsg *pMsg = (CFaxMsg *) refCtrl.GetItemData (iInd); if (pMsg == NULL) { return ERROR_CANTOPEN; } //
// Ask message to fetch the TIFF
//
dwRes = pMsg->GetTiff (cstrTiff); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (RPC_ERR, TEXT("CFaxMsg::GetTIFF"), dwRes); } return dwRes;
} // CFolderListView::FetchTiff
void CFolderListView::OnFolderItemDelete () /*++
Routine name : CFolderListView::OnFolderItemDelete
Routine description:
Handles message delete commands
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::OnFolderItemDelete"), TEXT("Type=%d"), m_Type);
//
// are you sure ?
//
BOOL bConfirm; DWORD dwRes = ConfirmItemDelete(bConfirm); if (ERROR_SUCCESS != dwRes) { PopupError (dwRes); CALL_FAIL (GENERAL_ERR, TEXT("ConfirmItemDelete"), dwRes); return; }
if(!bConfirm) { //
// not sure.
//
return; }
CWaitCursor waitCursor; CClientConsoleDoc* pDoc = GetDocument(); ASSERTION (pDoc);
CServerNode* pServer = NULL; CFolder* pFolder = NULL;
//
// Iterate set of selected messages, deleting each message in the set
//
CListCtrl &refCtrl = GetListCtrl(); DWORD dwSelected = refCtrl.GetSelectedCount(); if(0 == dwSelected) { return; }
if (dwSelected > 1) { //
// Disable refresh while deleting
//
refCtrl.SetRedraw (FALSE); //
// Prevent costy re-calc on every deletion
//
m_bInMultiItemsOperation = TRUE;
JobOpProgressDlgStart(FAX_JOB_OP_DELETE, dwSelected); } int iInd; CFaxMsg* pMsg; DWORDLONG dwlMsgId; for (DWORD dwItem = 0; dwItem < dwSelected && !m_bJobOpCancel; ++dwItem) { iInd = refCtrl.GetNextItem (-1, LVNI_SELECTED); if(iInd < 0) { CALL_FAIL (WINDOW_ERR, TEXT("CListCtrl::GetNextItem"), 0); break; } pMsg = (CFaxMsg *) refCtrl.GetItemData (iInd); ASSERTION (pMsg);
dwlMsgId = pMsg->GetId(); //
// Ask message to delete
//
dwRes = pMsg->Delete (); if (ERROR_SUCCESS != dwRes) { PopupError (dwRes); CALL_FAIL (RPC_ERR, TEXT("CArchiveMsg::Delete"), dwRes); //
// We exit upon first error
//
goto exit; } //
// delete a message from the data map and from the view
//
pServer = pMsg->GetServer(); ASSERTION (pServer);
pFolder = pServer->GetFolder(m_Type); ASSERTION (pFolder);
dwRes = pFolder->OnJobRemoved(dwlMsgId, pMsg); if (ERROR_SUCCESS != dwRes) { PopupError (dwRes); CALL_FAIL (RPC_ERR, TEXT("CMessageFolder::OnJobRemoved"), dwRes); goto exit; }
if(m_bInMultiItemsOperation) { JobOpProgressDlgInc(); } }
exit: if (m_bInMultiItemsOperation) { JobOpProgressDlgStop(); //
// Re-enable redraw
//
refCtrl.SetRedraw (TRUE); //
// Ask for visual refresh of view
//
refCtrl.Invalidate ();
m_bInMultiItemsOperation = FALSE; RecalcPossibleOperations (); }
if(FOLDER_TYPE_INBOX == m_Type) { theApp.InboxViewed(); }
} // CFolderListView::OnFolderItemDelete
void CFolderListView::CountColumns ( int *lpItems ) /*++
Routine name : CFolderListView::CountColumns
Routine description:
Sets the items to be seen in the view.
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
lpItems [in] - List of items. ends with MSG_VIEW_ITEM_END
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::CountColumns")); m_dwAvailableColumnsNum = 0; MsgViewItemType *pItems = (MsgViewItemType *)lpItems; m_pAvailableColumns = pItems; while (MSG_VIEW_ITEM_END != *pItems) { ASSERTION (*pItems < MSG_VIEW_ITEM_END); ++m_dwAvailableColumnsNum; ++pItems; } ASSERTION (m_dwAvailableColumnsNum); } // CFolderListView::CountColumns
int CFolderListView::CompareItems ( CFaxMsg* pFaxMsg1, CFaxMsg* pFaxMsg2, DWORD dwItemIndex ) const /*++
Routine name : CFolderListView::CompareItems
Routine description:
Compares two archive items
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
pFaxMsg1 [in] - Pointer to 1st message pFaxMsg2 [in] - Pointer to 2nd message dwItemIndex [in] - Item (in the message) to comapre by
Return Value:
-1 if message1 < message2, 0 if identical, +1 if message1 > message2
--*/ { DBG_ENTER(TEXT("CFolderListView::CompareItems"));
ASSERTION (dwItemIndex < MSG_VIEW_ITEM_END); static CViewRow rowView1; static CViewRow rowView2; DWORD dwRes = rowView1.AttachToMsg (pFaxMsg1, FALSE); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (GENERAL_ERR, TEXT("CViewRow::AttachToMsg"), dwRes); return 0; } dwRes = rowView2.AttachToMsg (pFaxMsg2, FALSE); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (GENERAL_ERR, TEXT("CViewRow::AttachToMsg"), dwRes); return 0; }
return rowView1.CompareByItem (rowView2, dwItemIndex); }
DWORD CFolderListView::AddMsgMapToView( MSGS_MAP* pMap ) /*++
Routine name : CFolderListView::AddMsgMapToView
Routine description:
Add messages from the map to the view
Arguments:
pMap [in] - masage map
Return Value:
error code
--*/ { DWORD dwRes = ERROR_SUCCESS; DBG_ENTER(TEXT("CFolderListView::AddMsgMapToView"));
ASSERTION(pMap); CListCtrl &listCtrl = GetListCtrl(); DWORD dwCount = listCtrl.GetItemCount();
listCtrl.SetRedraw (FALSE);
CFaxMsg* pMsg; CViewRow viewRow; int iIndexToSelect = -1; for (MSGS_MAP::iterator it = pMap->begin(); it != pMap->end(); ++it) { int iItemIndex;
pMsg = (*it).second; dwRes = viewRow.AttachToMsg (pMsg); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (GENERAL_ERR, TEXT("CViewRow::AttachToMsg"), dwRes); break; } dwRes = AddItem (dwCount++, viewRow, (LPARAM)pMsg, &iItemIndex); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (GENERAL_ERR, TEXT("CFolderListView::AddItem"), dwRes); break; } if ((-1 == iIndexToSelect) && // No item selected yet and
m_dwlMsgToSelect && // We should keep our eyes open for an item to select and
(pMsg->GetId () == m_dwlMsgToSelect)) // Match found !!
{ //
// This is the startup selected item.
// Save the item index
//
iIndexToSelect = iItemIndex; } } if (-1 != iIndexToSelect) { //
// We have the user-specified-item-to-select in the list now
//
SelectItemByIndex (iIndexToSelect); } listCtrl.SetRedraw (); return dwRes; } // CFolderListView::AddMsgMapToView
void CFolderListView::OnUpdate ( CView* pSender, LPARAM lHint, CObject* pHint ) /*++
Routine name : CFolderListView::OnUpdate
Routine description:
Receives a notification that the view should update itself
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
pSender [in] - Unused lHint [in] - Hint of update operation pHint [in] - If lHint is UPDATE_HINT_CLEAR_VIEW or UPDATE_HINT_FILL_VIEW then pHint is a pointer to the folder that requested an update.
If lHint is UPDATE_HINT_REMOVE_ITEM, UPDATE_HINT_ADD_ITEM, or UPDATE_HINT_UPDATE_ITEM, then pHint is a pointer to the job to remove / add / update.
Otherwise, pHint is undefined.
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::OnUpdate"), TEXT("Hint=%ld, Type=%d"), lHint, m_Type);
OnUpdateHintType hint = (OnUpdateHintType) lHint;
DWORD dwRes; CListCtrl &listCtrl = GetListCtrl(); switch (hint) { case UPDATE_HINT_CREATION: //
// Do nothing
//
break;
case UPDATE_HINT_CLEAR_VIEW: //
// Clear the entire list control now
//
if (!listCtrl.DeleteAllItems ()) { CALL_FAIL (WINDOW_ERR, TEXT("CListCtrl::DeleteAllItems"), ERROR_GEN_FAILURE); } ClearPossibleOperations (); break;
case UPDATE_HINT_ADD_CHUNK: { ASSERTION (pHint); MSGS_MAP* pMap = (MSGS_MAP*) pHint;
dwRes = AddMsgMapToView(pMap); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (GENERAL_ERR, TEXT("CFolderListView::AddMsgMapToView"), dwRes); } } break;
case UPDATE_HINT_FILL_VIEW: //
// Fill the list control with my parents data
//
{ ASSERTION (pHint); CFolder *pFolder = (CFolder *) pHint;
pFolder->EnterData (); MSGS_MAP &ParentMap = pFolder->GetData ();
dwRes = AddMsgMapToView(&ParentMap); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (GENERAL_ERR, TEXT("CFolderListView::AddMsgMapToView"), dwRes); }
pFolder->LeaveData (); } break;
case UPDATE_HINT_REMOVE_ITEM: //
// The data critical section must be held.
//
{ CFaxMsg* pMsg = (CFaxMsg*)pHint; ASSERTION(pMsg);
dwRes = RemoveItem ((LPARAM)pMsg); if (ERROR_SUCCESS != dwRes) { //
// Failed to remove item from list
//
CALL_FAIL (GENERAL_ERR, TEXT("CFolderListView::RemoveItem"), dwRes); ASSERTION_FAILURE; } } break;
case UPDATE_HINT_ADD_ITEM: //
// The data critical section must be held.
//
{ CFaxMsg* pMsg = (CFaxMsg*)pHint; ASSERTION(pMsg);
CViewRow viewRow; dwRes = viewRow.AttachToMsg (pMsg); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (GENERAL_ERR, TEXT("CViewRow::AttachToMsg"), dwRes); return; } dwRes = AddSortedItem (viewRow, (LPARAM)pMsg); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (GENERAL_ERR, TEXT("CFolderListView::AddSortedItem"), dwRes); return; } } break;
case UPDATE_HINT_UPDATE_ITEM: //
// The data critical section must be held.
//
{ CFaxMsg* pMsg = (CFaxMsg*)pHint; ASSERTION(pMsg);
CViewRow viewRow; dwRes = viewRow.AttachToMsg (pMsg); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (GENERAL_ERR, TEXT("CViewRow::AttachToMsg"), dwRes); return; } dwRes = UpdateSortedItem (viewRow, (LPARAM)pMsg); if (ERROR_SUCCESS != dwRes) { CALL_FAIL (GENERAL_ERR, TEXT("CFolderListView::UpdateSortedItem"), dwRes); return; } } break;
default: //
// Unsupported hint
//
ASSERTION_FAILURE; }
if(!m_bInMultiItemsOperation) { RecalcPossibleOperations (); }
CMainFrame *pFrm = GetFrm(); if (pFrm) { pFrm->RefreshStatusBar(); }
} // CFolderListView::OnUpdate
int CFolderListView::GetPopupMenuResource () const { DBG_ENTER(TEXT("CFolderListView::GetPopupMenuResource"));
int nMenuRes=0;
switch(m_Type) { case FOLDER_TYPE_INCOMING: nMenuRes = IDM_INCOMING; break; case FOLDER_TYPE_INBOX: nMenuRes = IDM_INBOX; break; case FOLDER_TYPE_SENT_ITEMS: nMenuRes = IDM_SENTITEMS; break; case FOLDER_TYPE_OUTBOX: nMenuRes = IDM_OUTBOX; break; default: ASSERTION_FAILURE break; }
return nMenuRes; }
void CFolderListView::OnFolderItemPause () /*++
Routine name : CFolderListView::OnFolderItemPause
Routine description:
Handles job pause commands
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::OnFolderItemPause"), TEXT("Type=%d"), m_Type);
CWaitCursor waitCursor;
//
// Iterate set of selected jobs, pausing each job in the set
//
CListCtrl &refCtrl = GetListCtrl(); DWORD dwSelected = refCtrl.GetSelectedCount(); ASSERTION (dwSelected);
int iInd = -1;
if(dwSelected > 1) { m_bInMultiItemsOperation = TRUE; JobOpProgressDlgStart(FAX_JOB_OP_PAUSE, dwSelected); }
for (DWORD dwItem = 0; dwItem < dwSelected && !m_bJobOpCancel; ++dwItem) { iInd = refCtrl.GetNextItem (iInd, LVNI_SELECTED); if(iInd < 0) { CALL_FAIL (WINDOW_ERR, TEXT("CListCtrl::GetNextItem"), 0); break; } CFaxMsg* pJob = (CFaxMsg*) refCtrl.GetItemData (iInd); ASSERT_KINDOF(CJob, pJob); //
// Ask job to pause
//
DWORD dwRes = pJob->Pause (); if (ERROR_SUCCESS != dwRes) { PopupError (dwRes); CALL_FAIL (RPC_ERR, TEXT("CJob::Pause"), dwRes); //
// We exit upon first error
//
goto exit; }
//
// update the view
//
OnUpdate (NULL, UPDATE_HINT_UPDATE_ITEM, pJob);
if(m_bInMultiItemsOperation) { JobOpProgressDlgInc(); } }
exit: if(m_bInMultiItemsOperation) { m_bInMultiItemsOperation = FALSE; JobOpProgressDlgStop(); RecalcPossibleOperations(); } } // CFolderListView::OnFolderItemPause
void CFolderListView::OnFolderItemResume () /*++
Routine name : CFolderListView::OnFolderItemResume
Routine description:
Handles job resume commands
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::OnFolderItemResume"), TEXT("Type=%d"), m_Type);
CWaitCursor waitCursor;
//
// Iterate set of selected jobs, resuming each job in the set
//
CListCtrl &refCtrl = GetListCtrl(); DWORD dwSelected = refCtrl.GetSelectedCount(); ASSERTION (dwSelected);
if(dwSelected > 1) { m_bInMultiItemsOperation = TRUE; JobOpProgressDlgStart(FAX_JOB_OP_RESUME, dwSelected); }
int iInd = -1; for (DWORD dwItem = 0; dwItem < dwSelected && !m_bJobOpCancel; ++dwItem) { iInd = refCtrl.GetNextItem (iInd, LVNI_SELECTED); if(iInd < 0) { CALL_FAIL (WINDOW_ERR, TEXT("CListCtrl::GetNextItem"), 0); break; } CFaxMsg* pJob = (CFaxMsg*) refCtrl.GetItemData (iInd); ASSERT_KINDOF(CJob, pJob); //
// Ask job to resume
//
DWORD dwRes = pJob->Resume (); if (ERROR_SUCCESS != dwRes) { PopupError (dwRes); CALL_FAIL (RPC_ERR, TEXT("CJob::Resume"), dwRes); //
// We exit upon first error
//
goto exit; }
//
// update the view
//
OnUpdate (NULL, UPDATE_HINT_UPDATE_ITEM, pJob);
if(m_bInMultiItemsOperation) { JobOpProgressDlgInc(); } }
exit: if(m_bInMultiItemsOperation) { m_bInMultiItemsOperation = FALSE; JobOpProgressDlgStop(); RecalcPossibleOperations(); }
} // CFolderListView::OnFolderItemResume
void CFolderListView::OnFolderItemRestart () /*++
Routine name : CFolderListView::OnFolderItemRestart
Routine description:
Handles job restart commands
Author:
Eran Yariv (EranY), Jan, 2000
Arguments:
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::OnFolderItemRestart"), TEXT("Type=%d"), m_Type);
CWaitCursor waitCursor;
//
// Iterate set of selected jobs, restarting each job in the set
//
CListCtrl &refCtrl = GetListCtrl(); DWORD dwSelected = refCtrl.GetSelectedCount(); ASSERTION (dwSelected);
if(dwSelected > 1) { m_bInMultiItemsOperation = TRUE; JobOpProgressDlgStart(FAX_JOB_OP_RESTART, dwSelected); }
int iInd = -1; for (DWORD dwItem = 0; dwItem < dwSelected && !m_bJobOpCancel; ++dwItem) { iInd = refCtrl.GetNextItem (iInd, LVNI_SELECTED); if(iInd < 0) { CALL_FAIL (WINDOW_ERR, TEXT("CListCtrl::GetNextItem"), 0); break; } CFaxMsg* pJob = (CFaxMsg*) refCtrl.GetItemData (iInd); ASSERT_KINDOF(CJob, pJob); //
// Ask job to restart
//
DWORD dwRes = pJob->Restart (); if (ERROR_SUCCESS != dwRes) { PopupError (dwRes); CALL_FAIL (RPC_ERR, TEXT("CJob::Restart"), dwRes); //
// We exit upon first error
//
goto exit; }
//
// update the view
//
OnUpdate (NULL, UPDATE_HINT_UPDATE_ITEM, pJob);
if(m_bInMultiItemsOperation) { JobOpProgressDlgInc(); } }
exit: if(m_bInMultiItemsOperation) { m_bInMultiItemsOperation = FALSE; JobOpProgressDlgStop(); RecalcPossibleOperations(); }
} // CFolderListView::OnFolderItemRestart
void CFolderListView::OnChar( UINT nChar, UINT nRepCnt, UINT nFlags ) /*++
Routine name : CFolderListView::OnChar
Routine description:
The framework calls this member function when a keystroke translates to a nonsystem character
Arguments:
nChar [in] - Contains the character code value of the key. nRepCnt [in] - Contains the repeat count nFlags [in] - Contains the scan code
Return Value:
None.
--*/ { if(VK_TAB == nChar) { CMainFrame *pFrm = GetFrm(); if (!pFrm) { //
// Shutdown in progress
//
return; }
CLeftView* pLeftView = pFrm->GetLeftView(); if(pLeftView) { pLeftView->SetFocus(); } } else { CListView::OnChar(nChar, nRepCnt, nFlags); } }
afx_msg void CFolderListView::OnContextMenu( CWnd *pWnd, CPoint pos ) { DBG_ENTER(TEXT("CFolderListView::OnContextMenu"), TEXT("Type=%d"), m_Type);
CListCtrl &refCtrl = GetListCtrl(); DWORD dwSelected = refCtrl.GetSelectedCount();
if (!dwSelected) { //
// If no item is selected, this is equivalent to right-clicking an empty area in the list view
// which does nothing.
//
return; }
if (pos.x == -1 && pos.y == -1) { //
// Keyboard (VK_APP or Shift + F10)
//
//
// Pop the context menu near the mouse cursor
//
pos = (CPoint) GetMessagePos(); }
int iMenuResource = GetPopupMenuResource (); if(0 == iMenuResource) { ASSERTION_FAILURE; return; }
ScreenToClient(&pos);
CMenu mnuContainer; if (!mnuContainer.LoadMenu (iMenuResource)) { CALL_FAIL (RESOURCE_ERR, TEXT("CMenu::LoadMenu"), ERROR_GEN_FAILURE); return; } CMenu *pmnuPopup = mnuContainer.GetSubMenu (0); ASSERTION (pmnuPopup);
ClientToScreen(&pos); if (!pmnuPopup->TrackPopupMenu (TPM_LEFTALIGN, pos.x, pos.y, theApp.m_pMainWnd)) { CALL_FAIL (RESOURCE_ERR, TEXT("CMenu::TrackPopupMenu"), ERROR_GEN_FAILURE); } } // CFolderListView::OnContextMenu
void CFolderListView::SelectItemById ( DWORDLONG dwlMsgId ) /*++
Routine name : CFolderListView::SelectItemById
Routine description:
Selects an item in the list control, by its message id
Author:
Eran Yariv (EranY), May, 2001
Arguments:
dwlMsgId [in] - Message id
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::SelectItemById"), TEXT("Message id=%0xI64d"), dwlMsgId);
ASSERTION (dwlMsgId);
int iMsgIndex = FindItemIndexFromID (dwlMsgId); if (-1 == iMsgIndex) { //
// Message could not be found in the list.
// This usually happens when we handle a WM_CONSOLE_SELECT_ITEM message sent to the main frame
// but the folder is in the middle of refresh and the requested message might not be there yet.
//
// By setting m_dwlMsgToSelect = dwlMsgId we signal the OnFolderRefreshEnded() funtion to call us again
// once refresh has ended.
//
VERBOSE (DBG_MSG, TEXT("Item not found - doing nothing")); m_dwlMsgToSelect = dwlMsgId; return; } SelectItemByIndex (iMsgIndex); } // CFolderListView::SelectItemById
void CFolderListView::SelectItemByIndex ( int iMsgIndex ) /*++
Routine name : CFolderListView::SelectItemByIndex
Routine description:
Selects an item in the list control, by its list item index
Author:
Eran Yariv (EranY), May, 2001
Arguments:
dwlMsgId [in] - List item index
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::SelectItemByIndex"), TEXT("Index = %ld"), iMsgIndex);
CListCtrl &refCtrl = GetListCtrl(); ASSERTION (iMsgIndex >= 0 && iMsgIndex < refCtrl.GetItemCount());
OnSelectNone(); refCtrl.SetItemState (iMsgIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); refCtrl.EnsureVisible (iMsgIndex, FALSE); refCtrl.SetFocus(); //
// Make sure this item won't be selected again
//
m_dwlMsgToSelect = 0; } // CFolderListView::SelectItemByIndex
int CFolderListView::FindItemIndexFromID ( DWORDLONG dwlMsgId ) /*++
Routine name : CFolderListView::FindItemIndexFromID
Routine description:
Finds the list view item index of a message by a message id
Author:
Eran Yariv (EranY), May, 2001
Arguments:
dwlMsgId [in] - Message id
Return Value:
Item index. -1 if not found
--*/ { DBG_ENTER(TEXT("CFolderListView::FindItemIndexFromID"), TEXT("Message id=%0xI64d"), dwlMsgId);
CListCtrl &refCtrl = GetListCtrl(); int iItemCount = refCtrl.GetItemCount(); //
// We must traverse the entire list and look for the message that matches the id.
//
for (int iIndex = 0; iIndex < iItemCount; iIndex++) { CFaxMsg *pMsg = (CFaxMsg*)refCtrl.GetItemData (iIndex); if (dwlMsgId == pMsg->GetId()) { //
// Found it
//
return iIndex; } } return -1; } // CFolderListView::FindItemIndexFromID
INT_PTR CALLBACK CFolderListView::JobOpProgressDlgProc( HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
) /*++
Routine description:
Job operation progress dialog
Arguments:
HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
Return Value:
return TRUE if it processed the message
--*/
{ static CFolderListView* pFolderView = NULL;
switch (uMsg) { case WM_INITDIALOG: pFolderView = (CFolderListView*)lParam; return FALSE;
case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: pFolderView->m_bJobOpCancel = TRUE; ::EnableWindow(::GetDlgItem(hwndDlg, IDCANCEL), FALSE); return TRUE; } break; } return FALSE;
} // CFolderListView::JobOpProgressDlgProc
BOOL CFolderListView::JobOpProgressDlgStart( FAX_ENUM_JOB_OP opJob, DWORD dwItems ) /*++
Routine name : CFolderListView::JobOpProgressDlgStart
Routine description:
Open and initialize multi job operation dialog
Arguments:
opJob [in]- operation type FAX_ENUM_JOB_OP enum dwItems [in]- number of iterations
Return Value:
TRUE if success FALSE otherwise
--*/ { DBG_ENTER(TEXT("CFolderListView::JobOpProgressDlgStart"));
HWND hProgressDlg = CreateDialogParam(GetResourceHandle(), // handle to module
MAKEINTRESOURCE(IDD_FAX_PROGRESS), // dialog box template name
theApp.m_pMainWnd->m_hWnd, // handle to owner window
JobOpProgressDlgProc, // dialog box procedure
(LPARAM)this); // initialization value
if(!hProgressDlg) { CALL_FAIL (WINDOW_ERR, TEXT("CreateDialog"), GetLastError()); return FALSE; }
//
// Set title string
//
DWORD dwTitleID=0; TCHAR szTitle[MAX_PATH]={0}; switch(opJob) { case FAX_JOB_OP_PAUSE: dwTitleID = IDS_PROGRESS_PAUSE; break; case FAX_JOB_OP_RESUME: dwTitleID = IDS_PROGRESS_RESUME; break; case FAX_JOB_OP_RESTART: dwTitleID = IDS_PROGRESS_RESTART; break; case FAX_JOB_OP_DELETE: dwTitleID = IDS_PROGRESS_DELETE; break; default: ASSERTION_FAILURE; break; } if(LoadString(GetResourceHandle(), dwTitleID, szTitle, ARR_SIZE(szTitle))) { ::SetDlgItemText(hProgressDlg, IDC_PROGRESS_TITLE, szTitle); } else { CALL_FAIL (RESOURCE_ERR, TEXT("LoadString"), GetLastError()); }
//
// Init progress bar
//
m_dwJobOpPos = 0; m_dwJobOpItems = dwItems; ::SendDlgItemMessage(hProgressDlg, IDC_PROGRESS_BAR, PBM_SETRANGE32, 0, dwItems); ::SendDlgItemMessage(hProgressDlg, IDC_PROGRESS_BAR, PBM_SETSTEP, 1, 0);
theApp.m_pMainWnd->EnableWindow(FALSE);
m_hJobOpProgressDlg = hProgressDlg;
return TRUE;
} // CFolderListView::JobOpProgressDlgStart
void CFolderListView::JobOpProgressDlgInc() /*++
Routine name : CFolderListView::JobOpProgressDlgInc
Routine description:
Multi job operation progress dialog increment
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::JobOpProgressDlgInc"));
if(!m_hJobOpProgressDlg) { return; }
++m_dwJobOpPos; //
// Increment progress bar
//
::SendDlgItemMessage(m_hJobOpProgressDlg, IDC_PROGRESS_BAR, PBM_STEPIT, 0, 0);
//
// Compose and set progress string
//
TCHAR szFormat[MAX_PATH] = {0}; TCHAR szText[MAX_PATH] = {0}; DWORD dwParam[2];
dwParam[0] = m_dwJobOpPos; dwParam[1] = m_dwJobOpItems;
if(LoadString(GetResourceHandle(), IDS_PROGRESS_NUMBER, szFormat, ARR_SIZE(szFormat))) { if(FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, (LPCVOID)szFormat, 0, 0, szText, ARR_SIZE(szText), (va_list*)dwParam)) { ::SetDlgItemText(m_hJobOpProgressDlg, IDC_PROGRESS_NUMBER, szText); } else { CALL_FAIL (GENERAL_ERR, TEXT ("FormatMessage"), GetLastError()); } } else { CALL_FAIL (RESOURCE_ERR, TEXT ("LoadString(IDS_PROGRESS_NUMBER)"), GetLastError()); }
//
// MFC message pump
// Taken from MSDN Q99999
// INFO: Background Processing in an MFC Application
//
MSG msg; while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (!theApp.PreTranslateMessage(&msg)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } theApp.OnIdle(0); // updates user interface
theApp.OnIdle(1); // frees temporary objects
}
} // CFolderListView::JobOpProgressDlgInc
void CFolderListView::JobOpProgressDlgStop() /*++
Routine name : CFolderListView::JobOpProgressDlgStop
Routine description:
Close multi job operation progress dialog
Return Value:
None.
--*/ { DBG_ENTER(TEXT("CFolderListView::JobOpProgressDlgStop"));
if(!m_hJobOpProgressDlg) { return; }
::DestroyWindow(m_hJobOpProgressDlg); m_hJobOpProgressDlg = NULL; m_bJobOpCancel = FALSE; m_dwJobOpItems = 0; m_dwJobOpPos = 0;
theApp.ReturnFromModal();
} // CFolderListView::JobOpProgressDlgStop
|