findtaskdlg.cpp
来自「管理项目进度工具的原代码」· C++ 代码 · 共 1,310 行 · 第 1/3 页
CPP
1,310 行
// FindTaskDlg.cpp : implementation file
//
#include "stdafx.h"
#include "todolist.h"
#include "FindTaskDlg.h"
#include "..\shared\deferwndmove.h"
#include "..\shared\dlgunits.h"
#include "..\shared\enstring.h"
#include "..\shared\dialoghelper.h"
#include "..\shared\misc.h"
#include <multimon.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
enum { COL_TASK, COL_MATCH, COL_PATH };
const int MATCH_COLWIDTH = 50;
struct SEARCHFIELD
{
UINT nIDWhat;
FIND_WHAT nWhat;
UINT nIDColumn;
int nAlign;
};
static SEARCHFIELD SEARCHFIELDS[] =
{
{ IDS_FTD_TITLECOMMENTS,FW_TITLECOMMENTS, 0, LVCFMT_LEFT },
{ IDS_FTD_PRIORITY, FW_PRIORITY, IDS_TDLBC_PRIORITY, LVCFMT_RIGHT },
{ IDS_FTD_PERCENT, FW_PERCENTDONE, IDS_TDLBC_PERCENT, LVCFMT_RIGHT },
{ IDS_FTD_TIMEEST, FW_TIMEEST, IDS_TDLBC_TIMEEST, LVCFMT_RIGHT },
{ IDS_FTD_TIMESPENT, FW_TIMESPENT, IDS_TDLBC_TIMESPENT, LVCFMT_RIGHT },
{ IDS_FTD_STARTDATE, FW_STARTDATE, IDS_TDLBC_STARTDATE, LVCFMT_RIGHT },
{ IDS_FTD_DUEDATE, FW_DUEDATE, IDS_TDLBC_DUEDATE, LVCFMT_RIGHT },
{ IDS_FTD_DONEDATE, FW_DONEDATE, IDS_TDLBC_DONEDATE, LVCFMT_RIGHT },
{ IDS_FTD_ALLOCTO, FW_ALLOCTO, IDS_TDLBC_ALLOCTO, LVCFMT_LEFT },
{ IDS_FTD_ALLOCBY, FW_ALLOCBY, IDS_TDLBC_ALLOCBY, LVCFMT_LEFT },
{ IDS_FTD_STATUS, FW_STATUS, IDS_TDLBC_STATUS, LVCFMT_LEFT },
{ IDS_FTD_CATEGORY, FW_CATEGORY, IDS_TDLBC_CATEGORY, LVCFMT_LEFT },
{ IDS_FTD_ID, FW_TASKID, IDS_TDLBC_ID, LVCFMT_RIGHT },
{ IDS_FTD_FLAG, FW_FLAG, 0, LVCFMT_LEFT },
{ IDS_FTD_CREATEDATE, FW_CREATIONDATE, IDS_TDLBC_CREATEDATE, LVCFMT_LEFT },
{ IDS_FTD_CREATEDBY, FW_CREATEDBY, IDS_TDLBC_CREATEDBY, LVCFMT_LEFT },
{ IDS_FTD_RISK, FW_RISK, IDS_TDLBC_RISK, LVCFMT_RIGHT },
{ IDS_FTD_LASTMOD, FW_LASTMOD, IDS_TDLBC_MODIFYDATE, LVCFMT_RIGHT },
{ IDS_FTD_EXTID, FW_EXTERNALID, IDS_TDLBC_EXTERNALID, LVCFMT_RIGHT },
{ IDS_FTD_COST, FW_COST, IDS_TDLBC_COST, LVCFMT_RIGHT },
{ IDS_FTD_VERSION, FW_VERSION, IDS_TDLBC_VERSION, LVCFMT_LEFT },
// add new fields on the end
};
const UINT FIELDCOUNT = sizeof(SEARCHFIELDS) / sizeof(SEARCHFIELD);
const SEARCHFIELD* GetSearchField(FIND_WHAT nWhat)
{
int nField = FIELDCOUNT;
while (nField--)
{
if (SEARCHFIELDS[nField].nWhat == nWhat)
return &SEARCHFIELDS[nField];
}
// else
return NULL;
}
const int TABSTOPS = 20;
const DWORD HEADERROW = 0xffffffff;
const UINT WM_FTD_SELECTITEM = (WM_APP+1);
/////////////////////////////////////////////////////////////////////////////
// CFindTaskDlg dialog
CFindTaskDlg::CFindTaskDlg(CWnd* pParent /*=NULL*/)
: CDialog(CFindTaskDlg::IDD, pParent),
m_pageTimeEst(FALSE, FALSE),
m_pageTimeSpent(FALSE, FALSE),
m_pageCost(FALSE, FALSE),
m_pageTaskID(TRUE, FALSE),
m_pageVersion(0),
m_bDockable(FALSE),
m_bSearchResults(FALSE),
m_nCurSel(-1)
{
m_sResultsLabel.LoadString(IDS_FTD_RESULTS);
//{{AFX_DATA_INIT(CFindTaskDlg)
m_bAutoSelectSingles = FALSE;
//}}AFX_DATA_INIT
m_bAllTasklists = AfxGetApp()->GetProfileInt("FindTasks", "SearchAllTaskLists", FALSE);
m_bIncludeDone = AfxGetApp()->GetProfileInt("FindTasks", "IncludeDoneTasks", FALSE);
m_nFindOption = (FIND_WHAT)max(FW_TITLECOMMENTS, (int)AfxGetApp()->GetProfileInt("FindTasks", "LastFindOption", FW_TITLECOMMENTS));
m_bAutoSelectSingles = AfxGetApp()->GetProfileInt("FindTasks", "AutoSelectSingles", FALSE);
CPropertyPage* pPages[] =
{
// same order as SEARCHFIELDS
&m_pageTitleComments, &m_pagePriority, &m_pagePercent, &m_pageTimeEst,
&m_pageTimeSpent, &m_pageStartDate, &m_pageDueDate, &m_pageDoneDate,
&m_pageAllocTo, &m_pageAllocBy, &m_pageStatus, &m_pageCategory,
&m_pageTaskID, &m_pageFlag, &m_pageCreationDate, &m_pageCreatedBy,
&m_pageRisk, &m_pageLastMod, &m_pageExtID, &m_pageCost, &m_pageVersion
};
for (int nField = 0; nField < FIELDCOUNT; nField++)
{
const SEARCHFIELD& field = SEARCHFIELDS[nField];
m_host.AddPage(pPages[nField], CEnString(field.nIDWhat), field.nWhat);
}
}
CFindTaskDlg::~CFindTaskDlg()
{
}
void CFindTaskDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CFindTaskDlg)
DDX_Control(pDX, IDC_FINDOPTION, m_cbFindOptions);
DDX_Control(pDX, IDC_RESULTS, m_lcResults);
DDX_CBIndex(pDX, IDC_TASKLISTOPTIONS, m_bAllTasklists);
DDX_Text(pDX, IDC_RESULTSLABEL, m_sResultsLabel);
DDX_Check(pDX, IDC_INCLUDEDONE, m_bIncludeDone);
DDX_CBIndex(pDX, IDC_FINDOPTION, m_nSelFindIndex);
DDX_Check(pDX, IDC_AUTOSELECTSINGLES, m_bAutoSelectSingles);
DDX_Check(pDX, IDC_SEARCHRESULTS, m_bSearchResults);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CFindTaskDlg, CDialog)
//{{AFX_MSG_MAP(CFindTaskDlg)
ON_BN_CLICKED(IDC_FIND, OnFind)
ON_WM_CLOSE()
ON_WM_SIZE()
ON_WM_DESTROY()
ON_CBN_SELCHANGE(IDC_FINDOPTION, OnSelchangeFindoption)
ON_WM_GETMINMAXINFO()
ON_BN_CLICKED(IDC_SELECTALL, OnSelectall)
ON_COMMAND(ID_DOCKRIGHT, OnDockright)
ON_UPDATE_COMMAND_UI(ID_DOCKRIGHT, OnUpdateDockright)
ON_COMMAND(ID_DOCKLEFT, OnDockleft)
ON_UPDATE_COMMAND_UI(ID_DOCKLEFT, OnUpdateDockleft)
ON_COMMAND(ID_UNDOCK, OnUndock)
ON_UPDATE_COMMAND_UI(ID_UNDOCK, OnUpdateUndock)
ON_COMMAND(ID_DOCKBELOW, OnDockbelow)
ON_UPDATE_COMMAND_UI(ID_DOCKBELOW, OnUpdateDockbelow)
ON_BN_CLICKED(IDC_SEARCHRESULTS, OnSearchresults)
ON_WM_SETCURSOR()
ON_NOTIFY(LVN_ITEMCHANGING, IDC_RESULTS, OnItemchangingResults)
//}}AFX_MSG_MAP
ON_NOTIFY(LVN_ITEMACTIVATE, IDC_RESULTS, OnItemActivated)
ON_NOTIFY(NM_CUSTOMDRAW, IDC_RESULTS, OnCustomDraw)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////////////
BOOL CFindTaskDlg::Initialize(CWnd* pParent, BOOL bDockable)
{
ASSERT (pParent || !bDockable);
if (!pParent && bDockable)
return FALSE;
if (GetSafeHwnd())
return TRUE;
m_bDockable = bDockable;
if (!Create(IDD_FIND_DIALOG, pParent))
return FALSE;
return TRUE;
}
void CFindTaskDlg::SetPriorityColors(const CDWordArray& aColors)
{
m_pagePriority.SetPriorityColors(aColors);
}
BOOL CFindTaskDlg::OnInitDialog()
{
CDialog::OnInitDialog();
m_host.Create(IDC_PAGEHOST, this);
// build combobox of pages
int nPages = m_host.GetPageCount();
for (int nPage = 0; nPage < nPages; nPage++)
{
int nIndex = m_cbFindOptions.InsertString(nPage, m_host.GetPageTitle(nPage));
m_cbFindOptions.SetItemDataPtr(nIndex, m_host.GetPage(nPage));
// init active page
if (m_nFindOption == (int)m_host.GetPageItemData(nPage))
{
m_nSelFindIndex = nIndex;
m_cbFindOptions.SetCurSel(nIndex);
m_host.SetActivePage(nPage);
}
}
// toolbar
if (m_toolbar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP))
{
if (m_toolbar.LoadToolBar(IDR_FINDDLG))
m_toolbar.SetImage(IDB_FIND16, RGB(255, 0, 255));
}
m_tbHelper.Initialize(&m_toolbar, this);
// very important - turn OFF all the auto positioning and sizing
// by default have no borders
UINT nStyle = m_toolbar.GetBarStyle();
nStyle &= ~(CCS_NORESIZE | CCS_NOPARENTALIGN | CBRS_BORDER_ANY);
nStyle |= (CBRS_SIZE_FIXED | CBRS_TOOLTIPS | CBRS_FLYBY);
m_toolbar.SetBarStyle(nStyle);
CRect rToolbar;
GetDlgItem(IDC_TOOLBAR)->GetWindowRect(rToolbar);
ScreenToClient(rToolbar);
m_toolbar.MoveWindow(rToolbar);
// subclass the results header ctrl to allow locking
CWnd* pHeader = m_lcResults.GetHeaderCtrl();
if (pHeader)
m_hdrResults.SubclassWindow(pHeader->GetSafeHwnd());
// gripper
// position resize icon as close to bottom left as pos
GetDlgItem(IDC_GRIPPER)->ModifyStyle(0, SBS_SIZEGRIP | SBS_SIZEBOXTOPLEFTALIGN | WS_CLIPSIBLINGS);
CDeferWndMove(1).OffsetCtrl(this, IDC_GRIPPER, 1, 2);
// setup up result list
m_lcResults.InsertColumn(COL_TASK, "Task", LVCFMT_LEFT, 200);
m_lcResults.InsertColumn(COL_MATCH, "", LVCFMT_LEFT, MATCH_COLWIDTH);
m_lcResults.InsertColumn(COL_PATH, "Path", LVCFMT_LEFT, 100);
m_lcResults.SetExtendedStyle(m_lcResults.GetExtendedStyle() | LVS_EX_ONECLICKACTIVATE | LVS_EX_UNDERLINEHOT);
m_lcResults.SetHotCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
GetDlgItem(IDC_SELECTALL)->EnableWindow(FALSE);
CenterWindow();
LoadSettings();
m_toolbar.RefreshButtonStates();
ResizeDlg();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CFindTaskDlg::LoadSettings()
{
// restore column widths
m_lcResults.SetColumnWidth(COL_MATCH, AfxGetApp()->GetProfileInt("FindTasks", "MatchColWidth", MATCH_COLWIDTH));
m_lcResults.SetColumnWidth(COL_PATH, AfxGetApp()->GetProfileInt("FindTasks", "PathColWidth", 100));
InitFieldColumn();
if (m_bDockable)
{
DM_POS nPos = DMP_UNDOCKED, nLastPos = DMP_RIGHT;
DWORD dwTopLeft = (DWORD)AfxGetApp()->GetProfileInt("FindTasks", "TopLeft", -1);
DWORD dwBottomRight = (DWORD)AfxGetApp()->GetProfileInt("FindTasks", "BottomRight", -1);
if (dwBottomRight != -1 && dwTopLeft != -1)
{
nPos = (DM_POS)AfxGetApp()->GetProfileInt("FindTasks", "DockPos", DMP_UNDOCKED);
nLastPos = (DM_POS)AfxGetApp()->GetProfileInt("FindTasks", "LastDockPos", DMP_RIGHT);
CRect rect(GET_X_LPARAM(dwTopLeft), GET_Y_LPARAM(dwTopLeft),
GET_X_LPARAM(dwBottomRight), GET_Y_LPARAM(dwBottomRight));
// ensure this intersects with the desktop
if (NULL != MonitorFromRect(rect, MONITOR_DEFAULTTONULL))
MoveWindow(rect);
}
// use the default size of the page host to initialize the
// docked width/height
CSize rDef = GetMinDockedSize(nPos);
int nWidthDocked = AfxGetApp()->GetProfileInt("FindTasks", "DockedWidth", rDef.cx);
int nWidthDockedMax = AfxGetApp()->GetProfileInt("FindTasks", "DockedWidthMax", -1);
int nHeightDocked = AfxGetApp()->GetProfileInt("FindTasks", "DockedHeight", rDef.cy);
int nHeightDockedMax = AfxGetApp()->GetProfileInt("FindTasks", "DockedHeightMax", -1);
m_dockMgr.Initialize(GetParent(), this, nPos, nLastPos,
nWidthDocked, nWidthDockedMax, nHeightDocked, nHeightDockedMax);
}
}
CSize CFindTaskDlg::GetMinDockedSize(DM_POS nPos)
{
// start with Host size
CRect rHost;
m_host.GetWindowRect(rHost);
ScreenToClient(rHost);
// and RHS of find button
CRect rFind;
GetDlgItem(IDC_FIND)->GetWindowRect(rFind);
ScreenToClient(rFind);
rHost.right = rFind.right;
if (nPos == DMP_BELOW)
rHost.right += CDlgUnits(this).ToPixelsX(40); // so the results list is visible
else
rHost.bottom += CDlgUnits(this).ToPixelsY(40); // so the results list is visible
// add border
int nBorder = CDlgUnits(this).ToPixelsX(7);
rHost.InflateRect(nBorder, nBorder);
// allow for non-client border
rHost.left = rHost.top = 0;
CalcWindowRect(rHost);
return rHost.Size();
}
BOOL CFindTaskDlg::Show(BOOL bShow)
{
if (!GetSafeHwnd())
return FALSE;
if (bShow)
{
// reset m_bSearchResults if dialog was previously hidden
if (!IsWindowVisible())
{
m_bSearchResults = FALSE;
UpdateData(FALSE);
}
m_toolbar.RefreshButtonStates();
ShowWindow(SW_SHOW);
SetForegroundWindow(); // give it the focus
// activate the current page
m_host.GetActivePage()->OnSetActive();
}
else
ShowWindow(SW_HIDE);
return TRUE;
}
void CFindTaskDlg::AddResult(LPCTSTR szTask, LPCTSTR szMatch, LPCTSTR szPath, BOOL bDone, DWORD dwItemData, int nTaskList)
{
if (GetSafeHwnd())
{
int nPos = m_lcResults.GetItemCount();
// add result
int nIndex = m_lcResults.InsertItem(nPos, szTask);
m_lcResults.SetItemText(nIndex, COL_PATH, szPath);
if (szMatch && lstrlen(szMatch))
m_lcResults.SetItemText(nIndex, COL_MATCH, szMatch);
m_lcResults.UpdateWindow();
// map identifying data
FTDRESULT res;
res.dwItemData = dwItemData;
res.nTaskList = nTaskList;
res.bDone = bDone;
DWORD dwKey = m_lcResults.GetItemCount();
m_lcResults.SetItemData(nIndex, dwKey);
m_mapResults[dwKey] = res;
// update 'found' count
m_sResultsLabel.Format(IDS_FTD_SOMERESULTS, m_mapResults.GetCount());
UpdateData(FALSE);
// focus first item added
if (!GetDlgItem(IDC_SELECTALL)->IsWindowEnabled())
{
SelectItem(nIndex);
// update 'search results' button' state
m_toolbar.RefreshButtonStates();
// enable 'select all' button
GetDlgItem(IDC_SELECTALL)->EnableWindow(TRUE);
}
}
}
void CFindTaskDlg::AddHeaderRow(LPCTSTR szText, BOOL bSpaceAbove)
{
int nPos = m_lcResults.GetItemCount();
// add space above?
if (bSpaceAbove)
{
int nIndex = m_lcResults.InsertItem(nPos, "");
m_lcResults.SetItemData(nIndex, HEADERROW);
nPos++;
}
// add result
int nIndex = m_lcResults.InsertItem(nPos, szText);
m_lcResults.SetItemData(nIndex, HEADERROW);
// bold font for rendering
if (m_fontBold.GetSafeHandle() == NULL)
Misc::CreateFont(m_fontBold, (HFONT)m_lcResults.SendMessage(WM_GETFONT), MFS_BOLD);
}
BOOL CFindTaskDlg::GetSearchAllTasklists()
{
if (GetSafeHwnd())
UpdateData();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?