📄 tyopcclientview.cpp
字号:
rc.top = rcitem.top;
// Force a repaint of the area:
cList.InvalidateRect (&rc, FALSE);
}
}
break;
// Use default processing of all other event types:
default:
CListView::OnTimer (nIDEvent);
break;
}
}
// **************************************************************************
// OnToolHitTest ()
//
// Description:
// Called to determine if the point is over a tool. Return the ID of the
// tool found (Documentaion says return 1 if found, otherwise -1. After
// researching this, we found that this is not the case. We need to return
// a unique ID for each tool found or -1 if no tool is found.) Tool in our
// case refers to an item/subitem cell.
//
// Parameters:
// CPoint cPoint Location of cursor.
// TOOLINFO *pTI Structure containing information about a
// tool in a ToolTip control.
//
// Returns:
// int - ID of the tool found or -1 if no tool found.
// **************************************************************************
int CViewOPCItem::OnToolHitTest (CPoint cPoint, TOOLINFO *pTI) const
{
int nRow = 0;
int nCol = 0;
// Get the (sub)item cell that the point resides in:
CRect rc;
nRow = GetCellRectFromPoint (cPoint, rc, &nCol);
// If no cell was hit (indicated by nRow = -1), or if the cell does
// not require a tool tip (entire text can fit in cell), then
// return -1 (no tool found).
if ((nRow == -1) || !(RequireCellToolTip (nRow, nCol, rc)))
return (-1);
// If we make it here, then the hit was in a cell that requires a
// tool tip to display entire text.
// Fill the toolinfo structure (function's out parameter):
// Handle to the window that contains the tool (i.e. this view):
pTI->hwnd = m_hWnd;
// Compute a unique tool ID from row and cell. Ten least significant
// bits will be the column number (up to 1023 columns), remaining 22
// bits will be the row number (up 4194303 to rows). Add one to make
// ID non-zero since the list view will automatically create a tip
// with ID zero.
pTI->uId = (UINT)((nRow << 10) + (nCol & 0x3FF) + 1);
// Get tool text through callback (TTN_NEEDTEXT notification)
pTI->lpszText = LPSTR_TEXTCALLBACK;
// Tool boundary:
pTI->rect = rc; // tool rect boundary
// Return the ID of the tool:
return (pTI->uId);
}
// **************************************************************************
// GetCellRectFromPoint ()
//
// Description:
// Return the cell boundaries that a point resides in, along with the
// associated list control row and column.
//
// Parameters:
// CPoint &cPoint Point.
// CRect &rc Rectangle that defines cell cPoint resides in.
// int *pCol Column cPoint resides in.
//
// Returns:
// int - The row cPoint resides in, or -1 if not in a cell.
// **************************************************************************
int CViewOPCItem::GetCellRectFromPoint (CPoint &cPoint, CRect &rc, int *pCol) const
{
int nCol = 0;
int nRow = 0;
int nBottom = 0;
int cnColumns = 0;
// Get reference to our list control:
CListCtrl &cList = GetListCtrl ();
// Get the row number of top item:
nRow = cList.GetTopIndex ();
// Compute the row number of bottom item:
nBottom = nRow + cList.GetCountPerPage ();
// Make sure bottom row number is valid:
if (nBottom > cList.GetItemCount ())
nBottom = cList.GetItemCount ();
// Get the number of columns (better be NUMCOLUMNS):
CHeaderCtrl* pHeader = (CHeaderCtrl*) GetDlgItem (0);
cnColumns = pHeader->GetItemCount ();
// Determine which row the hit occurred. Loop over visible rows:
for (; nRow <= nBottom; nRow++)
{
// Get bounding rect of item:
cList.GetItemRect (nRow, &rc, LVIR_BOUNDS);
// If the point falls in bounds, we found the row:
if (rc.PtInRect (cPoint))
{
// Now find the column. Loop over columns:
for (nCol = 0; nCol < cnColumns; nCol++)
{
// Get the width of column:
int nColWidth = cList.GetColumnWidth (nCol);
// If the within the column boundaries, we found the column:
if (cPoint.x >= rc.left && cPoint.x <= (rc.left + nColWidth))
{
// At this point, rc will describe all but the right
// boundary of the cell. The top and bottom we set
// when we found the row. The left boundary was set
// when we checked this column.
// Now get client area. We will use it later:
CRect rcClient;
GetClientRect (&rcClient);
// Set the column number for output, provided pointer
// was set by colling function:
if (pCol)
*pCol = nCol;
// Adjust right boundary so that rc now full describes
// the cell:
rc.right = rc.left + nColWidth;
// Adjust the right boundary again to ensure that it does
// not exceed client area:
if (rc.right > rcClient.right)
rc.right = rcClient.right;
// We have everything we need now, so return:
return (nRow);
}
// Adjust the left boundary so we can check the next column:
rc.left += nColWidth;
}
}
}
// If we make it here, then hit was not over a cell. Return
// -1 to indicate this:
return (-1);
}
// **************************************************************************
// RequireCellToolTip ()
//
// Description:
// Determins if a cell tool tip is required. Tool tip is required if cell
// is too narrow to display its full text.
//
// Parameters:
// int nRow Row number of cell.
// int nCol Column number of cell.
// CRect rc Rectangle that bounds the cell.
//
// Return:
// bool - true if tool tip is requred.
// **************************************************************************
bool CViewOPCItem::RequireCellToolTip (int nRow, int nCol, CRect rc) const
{
// Get reference to our list control:
CListCtrl &cList = GetListCtrl ();
// Get cell text:
CString strText;
strText = cList.GetItemText (nRow, nCol);
// Create a device context so we can get the cell text extent:
CWindowDC dc (&cList);
// Set the current font:
dc.SelectObject (cList.GetFont ());
// Get the size of the text (given device context and font):
CSize size = dc.GetTextExtent (strText);
// If the string is longer then the column width, then we will return
// true (need tool tip). Otherwise we will return false. Subtract
// twenty from cell's width for column buffering.
return (size.cx >= (rc.right - rc.left - 20));
}
void CViewOPCItem::OnItemClick(NMHDR* pNMHDR, LRESULT* pResult)
{
HD_NOTIFY *phdn = (HD_NOTIFY *) pNMHDR;
// TODO: Add your control notification handler code here
*pResult = 0;
}
void CViewOPCItem::PreSubclassWindow()
{
// TODO: Add your specialized code here and/or call the base class
CListView::PreSubclassWindow();
// Enable tooltips:
EnableToolTips (TRUE);
}
void CViewOPCItem::OnColumnClick(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
// Create a wait cursor object. This will cause the wait cursor,
// usually an hourglass, to be displayed. When this object goes
// out of scope, its destructor will restore the previous cursor
// type.
CWaitCursor wc;
// Get column index from message notification structure:
WORD wColumn = ((NM_LISTVIEW *)pNMHDR)->iSubItem;
// Record change in sorting parameters:
// If same sort column selected, toggle the sort order:
if (wColumn == sm_wSortColumn)
sm_wSortOrder = !sm_wSortOrder;
// Else sort using data in new sort column:
else
sm_wSortColumn = wColumn;
// Sort the list using new column and order settings:
SortItems ();
*pResult = 0;
}
void CViewOPCItem::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CListView::OnRButtonDown(nFlags, point);
// TRACE("CViewOPCItem::OnRButtonDown()---1\n");
// Get reference to our list control:
CListCtrl &cList = GetListCtrl ();
// See if the click was on an item. Return value will be item index hit
// was on, or -1 if hit was not on an item. Additional information will
// also be loaded into flags parameter.
UINT uHitFlags;
int nItem = cList.HitTest (point, &uHitFlags);
BOOL bCurSelItemState=false; //当前选择项状态
if (nItem >= 0 && (uHitFlags & LVHT_ONITEM)) //
bCurSelItemState=cList.GetItemState (nItem, LVIS_SELECTED);
// int nFlags=0;
if(!(nFlags & MK_CONTROL) //没有使用MK_CONTROL
&&!(nFlags & MK_SHIFT) //没有使用MK_SHIFT
&& !bCurSelItemState //当前项没有选择
)
{ //清除选择标记
int nSelIndex = cList.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);
while (nSelIndex >= 0)
{
//清除选择标记:
cList.SetItemState (nSelIndex, ~LVIS_SELECTED, LVIS_SELECTED);
nSelIndex = cList.GetNextItem (nSelIndex, LVNI_ALL | LVNI_SELECTED);
}
}
//
if (nItem >= 0 && (uHitFlags & LVHT_ONITEM)) //
if (!cList.GetItemState (nItem, LVIS_SELECTED)) //没有选中
cList.SetItemState (nItem, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
int uSelectedCount=cList.GetSelectedCount ();
TRACE("CViewOPCItem::OnRClick()--uSelectedCount=%d\n",uSelectedCount);
DWORD dwSelItem=SEL_BRANCH_OPCITEM_NULL;
switch(uSelectedCount)
{
case 0:
dwSelItem=SEL_BRANCH_OPCITEM_NULL;
break;
case 1:
dwSelItem=SEL_BRANCH_OPCITEM_ONE;
break;
default:
dwSelItem=SEL_BRANCH_OPCITEM_MORE;
}
//设定选择级数
CTYOPCClientDoc* pDoc=(CTYOPCClientDoc*)GetDocument();
ASSERT(pDoc);
pDoc->SetSelBranch (dwSelItem);
//加载相应的菜单:
CMenu cMenuUp;
CMenu* pMenu;
cMenuUp.LoadMenu (IDR_MAINFRAME);
pMenu=cMenuUp.GetSubMenu (2)->GetSubMenu(4); //加载菜单
if(pMenu==NULL)
return;
CPoint cPtScreen=point;
// GetCursorPos(&cPtScreen);
ClientToScreen(&cPtScreen);
//必须在CListView::OnRButtonDown(nFlags, point)之后调用,或在OnRClick(NMHDR* pNMHDR, LRESULT* pResult)实现
//TrackPopupMenu----
pMenu->TrackPopupMenu(
TPM_LEFTALIGN | TPM_RIGHTBUTTON,
cPtScreen.x, cPtScreen.y,
AfxGetMainWnd ());
// TRACE("CViewOPCItem::OnRButtonDown()---2\n");
}
void CViewOPCItem::GetSelOPCItem(CStringArray &strSelItems)
{
CListCtrl &cList = GetListCtrl ();
int nSelIndex = cList.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);
// CStringArray strSelItems;
CString strText;
while (nSelIndex >= 0)
{
strText=cList.GetItemText(nSelIndex,1);
strSelItems.Add (strText);
nSelIndex = cList.GetNextItem (nSelIndex, LVNI_ALL | LVNI_SELECTED);
}
TRACE("CViewOPCItem::GetSelOPCItem():SelItemCount=%d\n",strSelItems.GetUpperBound ()+1);
//设定选择级数
// CTYOPCClientDoc* pDoc=(CTYOPCClientDoc*)GetDocument();
// ASSERT(pDoc);
// pDoc->SetSelOPCItem (strArrSel);
}
void CViewOPCItem::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CListView::OnLButtonDown(nFlags, point);
// GetSelOPCItem(); //将当前选中的项传递给DOC
}
void CViewOPCItem::OnOPCItemAsync20Write()
{
// TODO: Add your command handler code here
CStringArray strSelItems;
GetSelOPCItem(strSelItems);
//2.弹出修改对话框
CDlgOPCItemWrite Dlg(this);
Dlg.SetWriteItem ((CTYOPCClientDoc*)GetDocument(),strSelItems);
Dlg.DoModal ();
}
void CViewOPCItem::OnRClick(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
*pResult = 0;
return;
//将鼠标点转换为屏幕坐标系:
CPoint cPtScreen,point;
GetCursorPos(&cPtScreen);
// ClientToScreen (&cPtScreen);
point = cPtScreen;
// Get reference to our list control:
CListCtrl &cList = GetListCtrl ();
cList.ScreenToClient(&point);
CRect rect;
cList.GetClientRect(rect);
if(!rect.PtInRect (point))
return;
// See if the click was on an item. Return value will be item index hit
// was on, or -1 if hit was not on an item. Additional information will
// also be loaded into flags parameter.
UINT uHitFlags;
int nItem = cList.HitTest (point, &uHitFlags);
BOOL bCurSelItemState=false; //当前选择项状态
if (nItem >= 0 && (uHitFlags & LVHT_ONITEM)) //
bCurSelItemState=cList.GetItemState (nItem, LVIS_SELECTED);
int nFlags=0;
if(!(nFlags & MK_CONTROL) //没有使用MK_CONTROL
&&!(nFlags & MK_SHIFT) //没有使用MK_SHIFT
&& !bCurSelItemState //当前项没有选择
)
{ //清除选择标记
int nSelIndex = cList.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);
while (nSelIndex >= 0)
{
//清除选择标记:
cList.SetItemState (nSelIndex, ~LVIS_SELECTED, LVIS_SELECTED);
nSelIndex = cList.GetNextItem (nSelIndex, LVNI_ALL | LVNI_SELECTED);
}
}
//
if (nItem >= 0 && (uHitFlags & LVHT_ONITEM)) //
if (!cList.GetItemState (nItem, LVIS_SELECTED)) //没有选中
cList.SetItemState (nItem, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
int uSelectedCount=cList.GetSelectedCount ();
TRACE("CViewOPCItem::OnRClick()--uSelectedCount=%d\n",uSelectedCount);
DWORD dwSelItem=SEL_BRANCH_OPCITEM_NULL;
switch(uSelectedCount)
{
case 0:
dwSelItem=SEL_BRANCH_OPCITEM_NULL;
break;
case 1:
dwSelItem=SEL_BRANCH_OPCITEM_ONE;
break;
default:
dwSelItem=SEL_BRANCH_OPCITEM_MORE;
}
// GetSelOPCItem(); //将当前选中的项传递给DOC
//设定选择级数
CTYOPCClientDoc* pDoc=(CTYOPCClientDoc*)GetDocument();
ASSERT(pDoc);
if(pDoc->GetSelBranch()==SEL_BRANCH_OPCGROUP)
pDoc->SetSelBranch (dwSelItem);
//加载相应的菜单:
CMenu cMenuUp;
CMenu* pMenu;
cMenuUp.LoadMenu (IDR_MAINFRAME);
pMenu=cMenuUp.GetSubMenu (2)->GetSubMenu(4); //加载菜单
if(pMenu==NULL)
return;
TRACE("CViewOPCItem::OnRClick()---1\n");
pMenu->TrackPopupMenu(
TPM_LEFTALIGN | TPM_RIGHTBUTTON,
cPtScreen.x, cPtScreen.y,
AfxGetMainWnd ());
TRACE("CViewOPCItem::OnRClick()---2\n");
*pResult = 0;
}
void CViewOPCItem::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
*pResult = 0;
CListCtrl &cList = GetListCtrl ();
int nSelCount=cList.GetSelectedCount ();
if(nSelCount!=1)
return;
int nItem = -1;
nItem = cList.GetNextItem(nItem, LVNI_SELECTED);
ASSERT(nItem != -1);
COPCItem *pItem = (COPCItem *)sm_pSortedItems [nItem];
if(pItem)
{
//得到选择组
CTYOPCClientDoc* pDoc=(CTYOPCClientDoc*)GetDocument();
ASSERT(pDoc);
COPCGroup* pGroup=pDoc->m_cOPCMgt.GetSelOPCGroup ();
CDlgOPCItemProperty dlg(pGroup,pItem);
if(IDOK==dlg.DoModal())
{
Invalidate();
pDoc->SetModifiedFlag (TRUE);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -