📄 itemview.cpp
字号:
// Sort the list:
SortList ();
// Now that we have added all of the items, we can let the
// view repaint itself:
SetRedraw (true);
}
break;
// Need to update view due to re-added items:
case HINT_READD_ITEM:
{
// This will be accomplished by simply causing a repaint of the
// item icons currently in view.
// Get reference to our list control:
CListCtrl &cList = GetListCtrl ();
int nTopIndex;
CRect rc;
CRect rcitem;
// Get view rectangle:
cList.GetClientRect (&rc);
// Get index of first visible item:
nTopIndex = cList.GetTopIndex ();
// Get rectangle bounding the first visible item's icon:
cList.GetItemRect (nTopIndex, &rcitem, LVIR_ICON);
// Adjust the view rectangle to invalidate all item icons areas:
rc.right = rcitem.right;
rc.left = rcitem.left;
// Invalidate the area to force a repaint of item icons:
cList.InvalidateRect (&rc);
}
break;
// Need to update view due to closed project or new server selection:
case HINT_CLOSE_PROJECT:
case HINT_SELECT_SERVER:
// pHint will be NULL if HINT_CLOSE_PROJECT and will contain a
// pointer to a CKServer object if HINT_SELECT_SERVER. (Not
// used in either case.)
// No items should be displayed after project is closed of if
// a server is selected. (Items are displayed only when a group
// is selected.) Delete any items in list control.
if (GetListCtrl ().GetItemCount () > 0)
DeleteAllItems ();
break;
// Need to update view due to new group selection:
case HINT_SELECT_GROUP:
{
// pHint points to the newly selected CKGroup object.
// Hint pointer must have been set for us to proceed:
if (pHint != NULL)
{
// Get pointer to newly selected CKGroup:
CKGroup *pGroup = (CKGroup *) pHint;
// Get reference to our list control:
CListCtrl &cList = GetListCtrl ();
// Postpone redrawing until we are done. This will make
// things go faster and look smoother.
SetRedraw (false);
// Delete any items that are currently in the list:
if (cList.GetItemCount () > 0)
DeleteAllItems ();
// Insert all items that belong to the selected group:
// Start with head of linked list of items in group and
// work our way to the end.
CKItem *pItem = pGroup->GetItemHead ();
// Add each item in linked list until we hit the end
// (indicated by a NULL pointer).
while (pItem)
{
// Insert item:
Insert (pItem);
// Get pointer to next item in linked list:
pItem = pItem->GetNext ();
}
// Update the item count. (This is one of the responsibilities
// we took on by using a virtual list view. See comments in
// PreCreateWindow().) Set flags to prevent the scroll position
// from changing and to prevent the list control from repainting
// unless affected items are in view.
cList.SetItemCountEx (m_cnSortedItems, LVSICF_NOSCROLL | LVSICF_NOINVALIDATEALL);
// Sort the list:
SortList ();
// Now that we are done adding items, we can let the view
// repaint itself:
SetRedraw (true);
}
}
break;
// Need to update view due to refresh view request:
case HINT_REFRESH_ITEMVIEW:
// Force a repaint of whole view:
GetListCtrl ().Invalidate (false);
GetListCtrl ().UpdateWindow ();
break;
// Perform default processing:
default:
CView::OnUpdate (pSender, lHint, pHint);
break;
}
}
// **************************************************************************
// OnDraw
//
// Description:
// OnDraw event handler. This function needs to be implemented since it is
// declared as a pure virtual function in base class. We don't need to do
// anything with it in this case.
//
// Parameters:
// none
//
// Returns:
// void
// **************************************************************************
void CKItemView::OnDraw (CDC *pDC)
{
// This is how we get our document object in case we need to do something
// with this function at some point:
CDocument* pDoc = GetDocument ();
}
// **************************************************************************
// 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 CKItemView::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);
}
/////////////////////////////////////////////////////////////////////////////
// CKItemView mouse handlers
/////////////////////////////////////////////////////////////////////////////
// **************************************************************************
// OnRButtonDown ()
//
// Description:
// Process right button click messages for this view. Select item and
// display an appropriate popup menu.
//
// Parameters:
// UINT uFlags Indicates whether various virtual keys are down.
// CPoint point Specifies the x and y coordinates of the cursor.
// These coordinates are always relative to the
// upper-left corner of the window.
//
// Returns:
// void
// **************************************************************************
void CKItemView::OnRButtonDown (UINT nFlags, CPoint point)
{
// Create a menu object, to be filled in shortly:
CMenu cMenu;
// 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);
// If hit was on an item (index not equal to -1, and LVHT_ONITEM flag set),
// then select item and unselect all others:
if (nItem >= 0 && (uHitFlags & LVHT_ONITEM))
{
// If item is not selected, we have work to do:
if (!cList.GetItemState (nItem, LVIS_SELECTED))
{
// Get index of first selected item. (-1 means start search from
// beginning of list, flags mean search through list by index
// for selected items).
int nSelIndex = cList.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);
// If we found a selected item (nSelIndex not -1), then unselect
// it and look for another selected item. Continue until all
// items have been examined:
while (nSelIndex >= 0)
{
// Unselect item:
cList.SetItemState (nSelIndex, ~LVIS_SELECTED, LVIS_SELECTED);
// Get index of next selected item:
nSelIndex = cList.GetNextItem (nSelIndex, LVNI_ALL | LVNI_SELECTED);
}
// Select and give focus to the item hit on:
cList.SetItemState (nItem, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
}
}
// Else just unselect all items:
else
{
// Get index of first selected item:
int nSelIndex = cList.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);
// If we found a selected item, unselect it and continue searching for
// and unselecting items until all have been unselected:
while (nSelIndex >= 0)
{
// Unselect item:
cList.SetItemState (nSelIndex, ~LVIS_SELECTED, LVIS_SELECTED);
// Get next selected item:
nSelIndex = cList.GetNextItem (nSelIndex, LVNI_ALL | LVNI_SELECTED);
}
}
// Convert hit point to screen coordinates:
ClientToScreen (&point);
// Create a popup menu:
if (cMenu.CreatePopupMenu ())
{
// Get pointer to main menu. We will use it to get text for popup:
CMenu *pMainMenu = AfxGetMainWnd ()->GetMenu ();
// Create a string to contain menu item text:
CString strMenuText;
// Define flags to so that popup menu items will get text from pointer
// to null terminated string.
int nFlags = MF_ENABLED | MF_STRING;
// Get pointer to selected group object:
CKGroup *pSelGroup = GetSelectedGroup ();
// If we get a valid group pointer, add menu items that allow for
// items to be added or pasted
if (pSelGroup != NULL)
{
// Add Add New Item menu item:
pMainMenu->GetMenuString (ID_EDIT_NEWITEM, strMenuText, MF_BYCOMMAND);
cMenu.AppendMenu (nFlags, ID_EDIT_NEWITEM, strMenuText);
// If item data is in clipboard, and no items are selected,
// allow paste:
if (IsClipboardFormatAvailable (CF_ITEM) && !cList.GetSelectedCount ())
{
// Add separator:
cMenu.AppendMenu (MF_SEPARATOR);
// Add Paste menu item:
pMainMenu->GetMenuString (ID_EDIT_PASTE, strMenuText, MF_BYCOMMAND);
cMenu.AppendMenu (nFlags, ID_EDIT_PASTE, strMenuText);
}
}
// If at least one item is selected, allow for item management
// and item read and write:
if (cList.GetSelectedCount () > 0)
{
// Check that selected group pointer is set (debug only):
ASSERT (pSelGroup != NULL);
// Add separator:
cMenu.AppendMenu (MF_SEPARATOR);
// Add these menu items only if selected group is valid:
if (pSelGroup->IsValid ())
{
// If item management is supported by selected group:
if (pSelGroup->IsIItemMgtSupported ())
{
// Add Set Items Active menu item:
pMainMenu->GetMenuString (ID_TOOLS_SET_ACTIVE, strMenuText, MF_BYCOMMAND);
cMenu.AppendMenu (nFlags, ID_TOOLS_SET_ACTIVE, strMenuText);
// Add Set Items Inactive menu item:
pMainMenu->GetMenuString (ID_TOOLS_SET_INACTIVE, strMenuText, MF_BYCOMMAND);
cMenu.AppendMenu (nFlags, ID_TOOLS_SET_INACTIVE, strMenuText);
}
// If synchronous i/o is supported by selected group:
if (pSelGroup->IsISyncIOSupported ())
{
// Add separator:
cMenu.AppendMenu (MF_SEPARATOR);
// Add Sync Read From Cache menu item:
pMainMenu->GetMenuString (ID_TOOLS_SYNC_READ_CACHE, strMenuText, MF_BYCOMMAND);
cMenu.AppendMenu (nFlags, ID_TOOLS_SYNC_READ_CACHE, strMenuText);
// Add Sync Read From Device menu item:
pMainMenu->GetMenuString (ID_TOOLS_SYNC_READ_DEVICE, strMenuText, MF_BYCOMMAND);
cMenu.AppendMenu (nFlags, ID_TOOLS_SYNC_READ_DEVICE, strMenuText);
// Add Sync Write menu item:
pMainMenu->GetMenuString (ID_TOOLS_SYNC_WRITE, strMenuText, MF_BYCOMMAND);
cMenu.AppendMenu (nFlags, ID_TOOLS_SYNC_WRITE, strMenuText);
}
// If asynchronous i/o 1.0 is supported by selected group:
// (Make sure update method was not set for 2.0)
if (pSelGroup->IsIAsyncIOSupported () && (pSelGroup->GetUpdateMethod () != OPC_20_DATACHANGE))
{
// Add separator:
cMenu.AppendMenu (MF_SEPARATOR);
// Add Async 1.0 Read From Cache menu item:
pMainMenu->GetMenuString (ID_TOOLS_ASYNC10_READ_CACHE, strMenuText, MF_BYCOMMAND);
cMenu.AppendMenu (nFlags, ID_TOOLS_ASYNC10_READ_CACHE, strMenuText);
// Add Async 1.0 Read From Device menu item:
pMainMenu->GetMenuString (ID_TOOLS_ASYNC10_READ_DEVICE, strMenuText, MF_BYCOMMAND);
cMenu.AppendMenu (nFlags, ID_TOOLS_ASYNC10_READ_DEVICE, strMenuText);
// Add Async 1.0 Refresh From Cache menu item:
pMainMenu->GetMenuString (ID_TOOLS_ASYNC10_REFRESH_CACHE, strMenuText, MF_BYCOMMAND);
cMenu.AppendMenu (nFlags, ID_TOOLS_ASYNC10_REFRESH_CACHE, strMenuText);
// Add Async 1.0 Refresh From Device menu item:
pMainMenu->GetMenuString (ID_TOOLS_ASYNC10_REFRESH_DEVICE, strMenuText, MF_BYCOMMAND);
cMenu.AppendMenu (nFlags, ID_TOOLS_ASYNC10_REFRESH_DEVICE, strMenuText);
// Add Async 1.0 Write menu item:
pMainMenu->GetMenuString (ID_TOOLS_ASYNC10_WRITE, strMenuText, MF_BYCOMMAND);
cMenu.AppendMenu (nFlags, ID_TOOLS_ASYNC10_WRITE, strMenuText);
}
// If asynchronous i/o 2.0 is supported and is being used:
if (pSelGroup->IsIAsyncIO2Supported () && (pSelGroup->GetUpdateMethod () == OPC_20_DATACHANGE))
{
// Add separator:
cMenu.AppendMenu (MF_SEPARATOR);
// Add Async 2.0 Read (only from device) menu item:
pMainMenu->GetMenuString (ID_TOOLS_ASYNC20_READ_DEVICE, strMenuText, MF_BYCOMMAND);
cMenu.AppendMenu (nFlags, ID_TOOLS_ASYNC20_READ_DEVICE, strMenuText);
// Add Async 2.0 Refresh From Cache menu item:
pMainMenu->GetMenuString (ID_TOOLS_ASYNC20_REFRESH_CACHE, strMenuText, MF_BYCOMMAND);
cMenu.AppendMenu (nFlags, ID_TOOLS_ASYNC20_REFRESH_CACHE, strMenuText);
// Add Async 2.0 Refresh From Device menu item:
pMainMenu->GetMenuString (ID_TOOLS_ASYNC20_REFRESH_DEVICE, strMenuText, MF_BYCOMMAND);
cMenu.AppendMenu (nFlags, ID_TOOLS_ASYNC20_REFRESH_DEVICE, strMenuText);
// Add Async 2.0 Write menu item:
pMainMenu->GetMenuString (ID_TOOLS_ASYNC20_WRITE, strMenuText, MF_BYCOMMAND);
cMenu.AppendMenu (nFlags, ID_TOOLS_ASYNC20_WRITE, strMenuText);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -