📄 tasktree.cpp
字号:
HRESULT AddItemToTree(LPWSTR lpszSubject, long nInsertID, long nParentID)
{
HWND hwndTV = GetDlgItem(g_hWnd, IDC_TREE_VIEW);
TVITEM tvi = {0};
TVINSERTSTRUCT tvins = {0};
static HTREEITEM hPrev = (HTREEITEM)TVI_FIRST;
static HTREEITEM hPrevRootItem = NULL;
HRESULT hr = S_OK;
// make sure lpszItem is not null
CBR(lpszSubject != NULL);
tvi.mask = TVIF_TEXT | TVIF_IMAGE
| TVIF_SELECTEDIMAGE | TVIF_PARAM;
// Set the text of the item.
//It is safe to cast WSTR to TSTR because Windows CE only uses Unicode
tvi.pszText = (LPTSTR) lpszSubject;
tvi.cchTextMax = ARRAYSIZE(tvi.pszText);
// Save the item's unique ID in the item's application-defined
// data area.
tvi.lParam = (LPARAM)nInsertID;
tvins.item = tvi;
tvins.hInsertAfter = hPrev;
// Set the parent item based on nParentID.
// if GetItemByID returns NULL, then the item is inserted at the root
hPrevRootItem = GetItemByID(NULL, nParentID);
tvins.hParent = hPrevRootItem;
// Add the item to the tree-view control.
hPrev = (HTREEITEM)SendMessage(hwndTV,
TVM_INSERTITEM,
0,
(LPARAM)(LPTVINSERTSTRUCT)&tvins);
hr = S_OK;
Error:
return hr;
}
///////////////////////////////////////////////////////////////////////////////
// CreateNewTask
//
// Create a Task given subject and parent ID
//
// Arguments:
// [IN] LPWSTR subject - subject of the item to add
// [IN] long nParentID - OID of the item's parent
//
// Return Values:
// IItem* - a pointer to the newly created IITem object (Task)
//
HRESULT CreateNewTask(LPWSTR pszSubject, long nParentID, IItem **ppItem)
{
HRESULT hr = E_FAIL;
IDispatch * pDisp = NULL;
IItem * pItem = NULL;
CEPROPVAL rgPropval[PROP_ARRAY_SIZE] = {0};
// make sure subject is not null
CPR(pszSubject);
CPR(ppItem);
CBR(g_polApp != NULL);
// create a new item
hr = g_polApp->CreateItem(olTaskItem, &pDisp);
CHR(hr);
CPR(pDisp);
// get the IItem interface the newly created item
hr = pDisp->QueryInterface(IID_IItem, (LPVOID*)&pItem);
CHR(hr);
CPR(pItem);
// set the itm props
for(int i = 0; i < PROP_ARRAY_SIZE; i++)
{
rgPropval[i].propid = g_rgPropIDs[i];
}
rgPropval[PARENT].val.lVal = nParentID;
rgPropval[OID].val.lVal = 0;
rgPropval[SUBJECT].val.lpwstr = pszSubject;
hr = pItem->SetProps(0, PROP_ARRAY_SIZE, rgPropval);
CHR(hr);
hr = pItem->Save();
CHR(hr);
*ppItem = pItem;
Error:
RELEASE_OBJ(pDisp);
if(FAILED(hr))
{
RELEASE_OBJ(pItem);
}
return hr;
}
///////////////////////////////////////////////////////////////////////////////
// AddNewTaskToTree
//
// Update tree view with the new task
//
// Arguments:
// [IN] IItem *pItem - a Task to add to the tree-view
//
// Return Values:
// HRESULT - S_OK if created succesfully, S_FAIL - otherwise
//
HRESULT AddNewTaskToTree(IItem *pItem)
{
HRESULT hr = S_OK;
CEPROPVAL * pPropVals = NULL;
HANDLE hHeap = GetProcessHeap();
ULONG cbBuffer = 0;
// make sure pItem is not null
CPR(pItem);
hr = pItem->GetProps(g_rgPropIDs, CEDB_ALLOWREALLOC, ARRAYSIZE(g_rgPropIDs), &pPropVals, &cbBuffer, hHeap);
CHR(hr);
CPR(pPropVals);
// now that we have prop values for a specific item call AddItemToTree
hr = AddItemToTree(pPropVals[SUBJECT].val.lpwstr, // subject
pPropVals[OID].val.lVal , // OID
pPropVals[PARENT].val.lVal); // parent
CHR(hr);
Error:
HEAP_FREE(hHeap, pPropVals);
return hr;
}
///////////////////////////////////////////////////////////////////////////////
// InitListBox
//
// Append a list drop-down box with a subject and an OID associated with it
//
// Arguments:
// [IN] LPWSTR subject - a Task subject to add to the list drop-down menu
// [IN] long OID - an ID of the Task
// Return Values:
// HRESULT - S_OK if created succesfully, S_FAIL - otherwise
HRESULT InitListBox(LPWSTR pszSubject, long lOID)
{
HRESULT hr = S_OK;
HWND hwnd = ::GetDlgItem(g_hWnd, IDC_PARENT);
// adds a subject of an existing task to the list drop-down
int idx = (int)SendMessage(hwnd, CB_ADDSTRING, 0, (LPARAM)pszSubject);
CBR(idx >= 0);
// associates OID with the list item
SendMessage(hwnd, CB_SETITEMDATA, idx, (LPARAM)lOID);
Error:
return hr;
}
///////////////////////////////////////////////////////////////////////////////
// GetNewTaskParent
//
// Get an OID of the parent task from the combobox
//
// Arguments:
// None
//
// Return Values:
// long oid - an oid asso
long GetNewTaskParent()
{
HWND hwnd = ::GetDlgItem(g_hWnd, IDC_PARENT);
// retreives an index of the currently selected item
int idx = (int)SendMessage(hwnd, CB_GETCURSEL, 0, 0);
// retreives data associated with this list item
long oid = SendMessage(hwnd, CB_GETITEMDATA, idx, 0);
return oid;
}
///////////////////////////////////////////////////////////////////////////////
// RefreshItems
//
// Refreshes the entire TaskTree dialog
// Loops through a collection of tasks and uppends them
// to the tree and list controls
//
// Arguments:
// None
//
// Return Values:
// HRESULT - S_OK if refreshed succesfully, S_FAIL - otherwise
HRESULT RefreshItems(void)
{
HRESULT hr = S_OK;
HWND hwndTV = GetDlgItem(g_hWnd, IDC_TREE_VIEW);
// declare a reference to a generic PIM item collection
IPOutlookItemCollection * pItems;
IDispatch * pDisp = NULL;
IItem * pItem = NULL;
// declare a reference to a generic PIM item folder
IFolder * pFolder = NULL;
int cItems = 0; // count of items in the Task collection
CEPROPVAL * pPropVals = NULL;
HANDLE hHeap = GetProcessHeap();
ULONG cbBuffer = 0;
// reset content of the tree structure
CBR(TreeView_DeleteAllItems(hwndTV));
// reset content of the list box
SendMessage(::GetDlgItem(g_hWnd, IDC_PARENT), CB_RESETCONTENT , 0, 0);
CBR(g_polApp != NULL);
// Use the generic PIM item folder to get the Tasks folder
hr = g_polApp->GetDefaultFolder(olFolderTasks, &pFolder);
CHR(hr);
CPR(pFolder);
// Use the Tasks folder to get the collection of Task items
hr = pFolder->get_Items(&pItems);
CHR(hr);
CPR(pItems);
// sort collection by OID in ascending order so that we don't
// try to create children before their parents
hr = pItems->Sort(_T("[OID]"), FALSE);
CHR(hr);
// Get the count of Items in the pItems collection
hr = pItems->get_Count(&cItems);
CHR(hr);
// loop through task items and populate drop-down list and tree view
for(int i = 1; i < (cItems + 1); i++)
{
hr = pItems->Item(i, (IDispatch **) &pDisp);
CHR(hr);
CPR(pDisp);
hr = pDisp->QueryInterface(IID_IItem, (LPVOID*)&pItem);
CHR(hr);
CPR(pItem);
cbBuffer = 0;
hr = pItem->GetProps(g_rgPropIDs, CEDB_ALLOWREALLOC, ARRAYSIZE(g_rgPropIDs), &pPropVals, &cbBuffer, hHeap);
CHR(hr);
CPR(pPropVals);
// populate the list box with tasks
hr = InitListBox(pPropVals[SUBJECT].val.lpwstr, // subject
pPropVals[OID].val.lVal); // OID
CHR(hr);
// now that we have prop values for a specific item call AddItemToTree
hr = AddItemToTree(pPropVals[SUBJECT].val.lpwstr, pPropVals[OID].val.lVal , pPropVals[PARENT].val.lVal);
CHR(hr);
HEAP_FREE(hHeap, pPropVals);
RELEASE_OBJ(pItem);
RELEASE_OBJ(pDisp);
}
// this is for the case when we want to create a task without a parent
hr = InitListBox(cszNoParent, 0);
CHR(hr);
Error:
HEAP_FREE(hHeap, pPropVals);
RELEASE_OBJ(pItem);
RELEASE_OBJ(pFolder);
RELEASE_OBJ(pDisp);
RELEASE_OBJ(pItems);
return hr;
}
///////////////////////////////////////////////////////////////////////////////
// ProcessMainMenu
//
// Interprets main menu commands
//
// Arguments:
// [IN] HWND hDlg - handle to the wondow dialog
// [IN] WORD wLo - command sent to the main menu
//
// Return Values:
// HRESULT - S_OK if success, S_FAIL - otherwise
HRESULT ProcessMainMenu(HWND hDlg, WORD wLo)
{
HRESULT hr = S_OK;
WCHAR pszSubject[MAX_LOADSTRING];
IItem * pItem = NULL;
long lOID = 0;
switch(wLo)
{
case IDOK: // for the foo button
case IDM_EXIT:
DestroyWindow (hDlg);
PostQuitMessage(0);
break;
case IDM_ACTION_REFRESH:
RefreshItems();
break;
case IDM_ACTION_NEW_TASK:
// retreive contents of the subject and parent controls
GetDlgItemText(g_hWnd, IDC_NEW_SUBJECT, pszSubject, ARRAYSIZE(pszSubject));
// call create new task
hr = CreateNewTask(pszSubject, GetNewTaskParent(), &pItem);
CHR(hr);
CPR(pItem);
// append it to the tree
hr = AddNewTaskToTree(pItem);
CHR(hr);
// append it to the list drop-down
hr = pItem->get_Oid(&lOID);
CHR(hr);
//populate the list
hr = InitListBox(pszSubject, lOID);
CHR(hr);
break;
}
Error:
RELEASE_OBJ(pItem);
return hr;
}
///////////////////////////////////////////////////////////////////////////////
// DlgMainProc
//
// Interprets main menu commands
//
// Arguments:
// [IN] HWND hDlg - handle of the window that receives the message
// [IN] UINT message - message identifier
// [IN] WPARAM wParam - data that come with the message
// [IN] LPARAM lParam - data that come with the message
//
// Return Values:
// LRESULT
LRESULT CALLBACK DlgMainProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
HRESULT hr = S_OK;
switch(message)
{
case WM_CLOSE:
EndDialog(hDlg,0);
DestroyWindow (hDlg);
break;
case WM_DESTROY:
hr = g_polApp->Logoff();
PostQuitMessage(0);
break;
case WM_INITDIALOG:
g_hWnd = hDlg;
hr = g_polApp->Logon((long)g_hWnd);
CHR(hr);
InitSKMenu(hDlg, ID_BTNBARRES);
SetDlgItemText(hDlg, IDC_NEW_SUBJECT, TEXT("Tap here to add a new task"));
// Initialize property IDs for a PIM item and create a custom property Parent
hr = InitProps();
CHR(hr);
RefreshItems();
UpdateWindow(hDlg);
break;
case WM_COMMAND:
ProcessMainMenu(hDlg, LOWORD(wParam));
break;
default:
return DefWindowProc(hDlg, message, wParam, lParam);
}
Error:
if(FAILED(hr))
{
ShowHR(hr);
}
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -