📄 duallistmanager.cpp
字号:
///////////////////////////////////////////////////////////////////////////////
//
// Filename: DualListManager.cpp
//
// AUTHOR : Copyright (C) Steve Aube, February 2000
// SteveAube@yahoo.com
//
// You can reuse and redistribute this code, provided this
// header is kept as is.
//
// Description: This class is intended to handle moving item between two
// listboxes. One list represents the list of available items
// and the other represents the list of choosen items. This
// class is intended to be a member of CDialog, CFormView or
// CPropertyPage. All the parent class has to do is properly
// initialize this class and call a couple of member functions
// and this class will take care of the following things:
// - If the "Add" button is pressed the selected item(s) are
// moved from the available list to the choosen list.
// - If the "Add All" button is pressed all of the items in
// are moved from the available list to the choosen list.
// - If the "Remove" button is pressed the selected item(s)
// are moved from the choosen list to the available list.
// - If the "Remove All" button is pressed all of the items in
// are moved from the choosen list to the available list.
// - If the "Move Up" button is pressed the selected item(s)
// in the choosen list are moved up in the list by one.
// This button can be pressed repeatedly until all of the
// selected items have reached the top of the list. When
// that occurs the button is disabled.
// - If the "Move Down" button is pressed the selected item(s)
// in the choosen list are moved down in the list by one.
// - Allows double clicking on an item to move it to the
// opposite list.
// - When item(s) are moved from one list to another the
// item that was moved is selected in the list it was moved
// to. The list that had the item removed selects the item
// that is at the location of the first item that was moved.
// If the item at the bottom of the list is moved the item
// immediately above it is selected. If the last item in
// the list is removed there is no selection.
// - Enabling/disabling of buttons - when items are moved
// between lists and up and down in the choosen list the
// availability of buttons changes. For instance if an item
// is moved to the top of the choosen list the "Move Up"
// button doesn't make sense. When this occurs the "Move Up"
// button is automatically disabled.
// - Keyboard support - disabling a button that has the focus
// causes problems for keyboard users. This code checks to
// see if a button has the focus before it disables it. If
// it does the focus is forwarded to the next avaiabled
// control.
//
// How to use this class:
// - Add a member variable of this class type to the dialog
// box, property page or form view where you want to use it.
// - From the initialization method (OnInitDialog() for a
// dialog box and a property page and OnInitialUpdate() for
// a view) do the following things in this order:
// - Add the items to the available and choosen lists with
// the calls AddItemToAvailableList(...) and
// AddItemToChoosenList(...). The first parameter is the
// name of the item and the second parameter is a unique
// identifier for the item.
// - Call InitializeControls(...) with a pointer the parent
// window and the IDs of all of the controls.
// - Override OnCmdMsg(...)
//
// Notes:
// - If you don't need certain features (like the ability to
// move an item up or down in the choosen list) simply
// provide a NULL value for that id. The rest of the class
// will continue work correctly. The IDs for the two lists
// are required since a dual list manager doesn't make sense
// unless it has two lists to work with.
// - This code will work with single, multiple and extended
// listboxes.
// - The order of the controls doesn't matter. You can put
// the choosen list on the left, right, top or bottom of the
// selected list. Just make sure you supply the control IDs
// in the right order.
//
// Implementation details:
// This class keeps track of the items in both listboxes in
// internal CArrays. The names associated with the items
// are tracked in a CMap and the item data value is used as
// the key. Keeping these separate lists simplfies moving
// items and keeping track of selection state.
//
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DualListManager.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
///////////////////////////////////////////////////////////////////////////////
//
// Method: CDualListManager
//
// Purpose: Constructor - initializes member data
//
// Inputs:
//
// void
//
// Outputs:
//
// None
//
// Return value:
//
// None
//
// Exceptions: None
//
///////////////////////////////////////////////////////////////////////////////
CDualListManager::CDualListManager(void)
: m_pWndParent(NULL)
, m_iIDAvailableList(0)
, m_iIDChoosenList(0)
, m_iIDAddButton(0)
, m_iIDAddAllButton(0)
, m_iIDRemoveButton(0)
, m_iIDRemoveAllButton(0)
, m_iIDMoveUpButton(0)
, m_iIDMoveDownButton(0)
, m_bAvailableListSingleSelType(0)
, m_bChoosenListSingleSelType(0)
, m_bIsCur(false)
{
}
///////////////////////////////////////////////////////////////////////////////
//
// Method: ~CDualListManager
//
// Purpose: Destructor - detach the listbox handles
//
// Inputs:
//
// void
//
// Outputs:
//
// None
//
// Return value:
//
// None
//
// Exceptions: None
//
///////////////////////////////////////////////////////////////////////////////
CDualListManager::~CDualListManager(void)
{
m_ctrlAvailableList.Detach();
m_ctrlChoosenList.Detach();
}
///////////////////////////////////////////////////////////////////////////////
//
// Method: InitializeControls
//
// Should be called from the initialization method
// (OnInitDialog() for a dialog box and a property page and
// OnInitialUpdate() for a view). Before calling this method
// the client code should add the listbox items to the two
// lists with calls to AddItemToAvailableList(...) and
// AddItemToChoosenList(...).
//
// This method sets up this class to handle all of the
// messages for the given controls.
// Inputs:
//
// CWnd* pWndParent - pointer to the parent window (should be a CDialog
// CPropertyPage, CFormView etc.)
//
// int iIDAvailableList - resource id of the available listbox
//
// int iIDChoosenList - resource id of the choosen listbox
//
// int iIDAddButton - resource id of the add button
//
// int iIDAddAllButton - resource id of the add all button
//
// int iIDRemoveButton - resource id of the remove button
//
// int iIDRemoveAllButton - resource id of the remove all button
//
// int iIDMoveUpButton - resource id of the up button
//
// int iIDMoveDownButton - resource id of the down button
//
// Outputs:
//
// None
//
// Return value:
//
// void
//
// Exceptions: None
//
///////////////////////////////////////////////////////////////////////////////
void CDualListManager::InitializeControls(CWnd* pWndParent,
int iIDAvailableList,
int iIDChoosenList,
int iIDAddButton,
int iIDAddAllButton,
int iIDRemoveButton,
int iIDRemoveAllButton,
int iIDMoveUpButton,
int iIDMoveDownButton,
bool bIsCur)
{
// Hold on to all of the passed in parameters.
m_pWndParent = pWndParent;
m_iIDAvailableList = iIDAvailableList;
m_iIDChoosenList = iIDChoosenList;
m_iIDAddButton = iIDAddButton;
m_iIDAddAllButton = iIDAddAllButton;
m_iIDRemoveButton = iIDRemoveButton;
m_iIDRemoveAllButton = iIDRemoveAllButton;
m_iIDMoveUpButton = iIDMoveUpButton;
m_iIDMoveDownButton = iIDMoveDownButton;
m_bAvailableListSingleSelType = FALSE;
m_bChoosenListSingleSelType = FALSE;
m_bIsCur = bIsCur;
// This class doesn't make sense unless a parent window and two listboxes
// are supplied. It also doesn't make sense without at least some of the
// other controls. However, there is no specific set of controls that are
// required so no checks are done here.
ASSERT(m_pWndParent);
ASSERT(m_iIDAvailableList);
ASSERT(m_iIDChoosenList);
// Attach the control items to the windows. The lists have to exist and we
// access them continually so having a listbox control just simplifies this
// code.
HWND h=m_pWndParent->GetDlgItem(m_iIDAvailableList)->GetSafeHwnd();
m_ctrlAvailableList.Attach(h);//m_pWndParent->GetDlgItem(m_iIDAvailableList)->GetSafeHwnd());
m_ctrlChoosenList.Attach(m_pWndParent->GetDlgItem(m_iIDChoosenList)->GetSafeHwnd());
// Check to see whether each list is a single or multi select listbox
m_bAvailableListSingleSelType = (m_ctrlAvailableList.GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) ) ? FALSE: TRUE ;
m_bChoosenListSingleSelType = (m_ctrlChoosenList.GetStyle() & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) ) ? FALSE: TRUE ;
// Re-fill the listboxes with the contents of the array
FillListboxes();
// Select the first item in each of the listboxes
SelectLBItem(m_ctrlAvailableList, 0);
SelectLBItem(m_ctrlChoosenList, 0);
// Now enable/disable the move buttons based on the contents and selction
// state of the listbox controls.
EnableButtons(bIsCur);
}
///////////////////////////////////////////////////////////////////////////////
//
// Method: AddItemToAvailableList
//
// Purpose: Adds the passed in item to the array of items identified
// as being currently available for selection. Also adds the
// item to the map so the name can be looked up later.
//
// Inputs:
//
// LPCTSTR lpszItem
//
// long lItemData
//
// Outputs:
//
// None
//
// Return value:
//
// void
//
// Exceptions: None
//
///////////////////////////////////////////////////////////////////////////////
void CDualListManager::AddItemToAvailableList(LPCTSTR lpszItem, long lItemData)
{
m_ArrayAvailable.Add(lItemData);
m_KeyMap.SetAt(lItemData, lpszItem);
}
///////////////////////////////////////////////////////////////////////////////
//
// Method: AddItemToChoosenList
//
// Purpose: Adds the passed in item to the array of items identified
// as being currently choosen. Also adds the item to the
// map so the name can be looked up later.
//
// Inputs:
//
// LPCTSTR lpszItem
//
// long lItemData
//
// Outputs:
//
// None
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -