bug fix for vista in multi-selection tree
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@49631 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -52,6 +52,40 @@
|
|||||||
// get HTREEITEM from wxTreeItemId
|
// get HTREEITEM from wxTreeItemId
|
||||||
#define HITEM(item) ((HTREEITEM)(((item).m_pItem)))
|
#define HITEM(item) ((HTREEITEM)(((item).m_pItem)))
|
||||||
|
|
||||||
|
|
||||||
|
// older SDKs are missing these
|
||||||
|
#ifndef TVN_ITEMCHANGINGA
|
||||||
|
|
||||||
|
#define TVN_ITEMCHANGINGA (TVN_FIRST-16)
|
||||||
|
#define TVN_ITEMCHANGINGW (TVN_FIRST-17)
|
||||||
|
|
||||||
|
typedef struct tagNMTVITEMCHANGE
|
||||||
|
{
|
||||||
|
NMHDR hdr;
|
||||||
|
UINT uChanged;
|
||||||
|
HTREEITEM hItem;
|
||||||
|
UINT uStateNew;
|
||||||
|
UINT uStateOld;
|
||||||
|
LPARAM lParam;
|
||||||
|
} NMTVITEMCHANGE;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// this global variable is used on vista systems for preventing unwanted
|
||||||
|
// item state changes in the vista tree control. It is only used in
|
||||||
|
// multi-select mode on vista systems.
|
||||||
|
|
||||||
|
static HTREEITEM gs_unlockItem = NULL;
|
||||||
|
|
||||||
|
class TreeItemUnlocker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TreeItemUnlocker(HTREEITEM item) { gs_unlockItem = item; }
|
||||||
|
~TreeItemUnlocker() { gs_unlockItem = NULL; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// private functions
|
// private functions
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -65,6 +99,8 @@ static bool IsItemSelected(HWND hwndTV, HTREEITEM hItem)
|
|||||||
tvi.stateMask = TVIS_SELECTED;
|
tvi.stateMask = TVIS_SELECTED;
|
||||||
tvi.hItem = hItem;
|
tvi.hItem = hItem;
|
||||||
|
|
||||||
|
TreeItemUnlocker unlocker(hItem);
|
||||||
|
|
||||||
if ( !TreeView_GetItem(hwndTV, &tvi) )
|
if ( !TreeView_GetItem(hwndTV, &tvi) )
|
||||||
{
|
{
|
||||||
wxLogLastError(wxT("TreeView_GetItem"));
|
wxLogLastError(wxT("TreeView_GetItem"));
|
||||||
@@ -81,6 +117,8 @@ static bool SelectItem(HWND hwndTV, HTREEITEM hItem, bool select = true)
|
|||||||
tvi.state = select ? TVIS_SELECTED : 0;
|
tvi.state = select ? TVIS_SELECTED : 0;
|
||||||
tvi.hItem = hItem;
|
tvi.hItem = hItem;
|
||||||
|
|
||||||
|
TreeItemUnlocker unlocker(hItem);
|
||||||
|
|
||||||
if ( TreeView_SetItem(hwndTV, &tvi) == -1 )
|
if ( TreeView_SetItem(hwndTV, &tvi) == -1 )
|
||||||
{
|
{
|
||||||
wxLogLastError(wxT("TreeView_SetItem"));
|
wxLogLastError(wxT("TreeView_SetItem"));
|
||||||
@@ -804,6 +842,8 @@ bool wxTreeCtrl::DoGetItem(wxTreeViewItem *tvItem) const
|
|||||||
|
|
||||||
void wxTreeCtrl::DoSetItem(wxTreeViewItem *tvItem)
|
void wxTreeCtrl::DoSetItem(wxTreeViewItem *tvItem)
|
||||||
{
|
{
|
||||||
|
TreeItemUnlocker unlocker(tvItem->hItem);
|
||||||
|
|
||||||
if ( TreeView_SetItem(GetHwnd(), tvItem) == -1 )
|
if ( TreeView_SetItem(GetHwnd(), tvItem) == -1 )
|
||||||
{
|
{
|
||||||
wxLogLastError(wxT("TreeView_SetItem"));
|
wxLogLastError(wxT("TreeView_SetItem"));
|
||||||
@@ -2564,6 +2604,36 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
// Vista's tree control has introduced some problems with our
|
||||||
|
// multi-selection tree. When TreeView_SelectItem() is called,
|
||||||
|
// the wrong items are deselected.
|
||||||
|
|
||||||
|
// Fortunately, Vista provides a new notification, TVN_ITEMCHANGING
|
||||||
|
// that can be used to regulate this incorrect behavior. The
|
||||||
|
// following messages will allow only the unlocked item's selection
|
||||||
|
// state to change
|
||||||
|
case TVN_ITEMCHANGINGA:
|
||||||
|
case TVN_ITEMCHANGINGW:
|
||||||
|
{
|
||||||
|
// we only need to handles these in multi-select trees
|
||||||
|
if ( HasFlag(wxTR_MULTIPLE) )
|
||||||
|
{
|
||||||
|
// get info about the item about to be changed
|
||||||
|
NMTVITEMCHANGE* info = (NMTVITEMCHANGE*)lParam;
|
||||||
|
if (info->hItem != gs_unlockItem)
|
||||||
|
{
|
||||||
|
// item's state is locked, don't allow the change
|
||||||
|
// returning 1 will disallow the change
|
||||||
|
*result = 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// allow the state change
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
// NB: MSLU is broken and sends TVN_SELCHANGEDA instead of
|
// NB: MSLU is broken and sends TVN_SELCHANGEDA instead of
|
||||||
// TVN_SELCHANGEDW in Unicode mode under Win98. Therefore
|
// TVN_SELCHANGEDW in Unicode mode under Win98. Therefore
|
||||||
// we have to handle both messages:
|
// we have to handle both messages:
|
||||||
|
Reference in New Issue
Block a user