Don't close menu(s) on certain operations

In several cases we don't want menu(s) to close when an action on menu was
done. For example on drag-n-drop or menu item deletion (where confirmation
dialog is shown).

In such situations `s_bPreventClosing` was set to true (and then back to
false when closing was allowed again).
Though original code honored this variable only in certain situations and
typically (at least on Win10) menus were hidden/closed despite of it.

This patch changes the behavior and menus(s) are not closed when
`s_bPreventClosing` is set to true.
Basically now menu(s) stay visible until there is an action that changes
active window.

Following functionality was also removed because it is not needed now:

* CMenuContainer::HideTemp
* COwnerWindow::OnClear
  WM_CLEAR was sent to the window only by already removed `HideTemp`
This commit is contained in:
ge0rdi
2019-10-13 17:31:58 +02:00
committed by ge0rdi
parent f33cd60b84
commit fe47f841e7
6 changed files with 16 additions and 68 deletions

View File

@@ -248,7 +248,6 @@ bool CMenuContainer::DragOutApps( const CItemManager::ItemInfo *pInfo )
s_bDragFromTree=false;
if (!m_bDestroyed)
KillTimer(TIMER_DRAG);
HideTemp(false);
s_bPreventClosing=false;
if (s_bDragClosed)
@@ -343,7 +342,6 @@ bool CMenuContainer::DragOut( int index, bool bApp )
if (!m_bDestroyed)
KillTimer(TIMER_DRAG);
s_bDragMovable=false;
HideTemp(false);
s_bPreventClosing=false;
if (s_bDragClosed)
@@ -863,8 +861,6 @@ HRESULT STDMETHODCALLTYPE CMenuContainer::Drop( IDataObject *pDataObj, DWORD grf
s_bPreventClosing=true;
AddRef();
pTarget->Drop(pDataObj,grfKeyState,pt,pdwEffect);
if (!bOld)
HideTemp(false);
s_bPreventClosing=bOld;
for (std::vector<CMenuContainer*>::iterator it=s_Menus.begin();it!=s_Menus.end();++it)
if (!(*it)->m_bDestroyed)

View File

@@ -2396,7 +2396,6 @@ void CMenuContainer::ActivateItem( int index, TActivateType type, const POINT *p
}
}
DestroyMenu(menu2);
HideTemp(false);
s_bPreventClosing=false;
PITEMID_CHILD newPidl=NULL;
@@ -2485,7 +2484,6 @@ void CMenuContainer::ActivateItem( int index, TActivateType type, const POINT *p
Invalidate();
if (m_HotItem<0) SetHotItem(index);
}
HideTemp(false);
s_bPreventClosing=false;
}
SetContextItem(-1);
@@ -2742,7 +2740,6 @@ void CMenuContainer::ActivateItem( int index, TActivateType type, const POINT *p
else
SetFocus();
}
HideTemp(false);
s_bPreventClosing=false;
s_HotPos=GetMessagePos();
res=CMD_RENAME;
@@ -2802,8 +2799,7 @@ void CMenuContainer::ActivateItem( int index, TActivateType type, const POINT *p
if (bRefresh || bRefreshMain)
info.fMask|=CMIC_MASK_NOASYNC; // wait for delete/link commands to finish so we can refresh the menu
if ((type!=ACTIVATE_MENU && type!=ACTIVATE_DELETE) || GetWinVersion()<WIN_VER_WIN8)
s_bPreventClosing=true;
s_bPreventClosing=true;
for (std::vector<CMenuContainer*>::iterator it=s_Menus.begin();it!=s_Menus.end();++it)
(*it)->EnableWindow(FALSE); // disable all menus
bool bAllPrograms=s_bAllPrograms;
@@ -2880,7 +2876,6 @@ void CMenuContainer::ActivateItem( int index, TActivateType type, const POINT *p
else
SetFocus();
}
HideTemp(false);
s_bPreventClosing=false;
if (!bKeepOpen && !bRefresh && !bRefreshMain)

View File

@@ -6365,11 +6365,6 @@ LRESULT CMenuContainer::OnRefresh( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL
return 0;
}
void CMenuContainer::HideTemp( bool bHide )
{
::PostMessage(g_OwnerWindow,WM_CLEAR,bHide,0);
}
LRESULT CMenuContainer::OnActivate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
if (LOWORD(wParam)!=WA_INACTIVE)
@@ -6379,6 +6374,9 @@ LRESULT CMenuContainer::OnActivate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOO
return 0;
}
#ifndef PREVENT_CLOSING
if (s_bPreventClosing)
return 0;
if (lParam)
{
// check if another menu window is being activated
@@ -6389,24 +6387,15 @@ LRESULT CMenuContainer::OnActivate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOO
if ((HWND)lParam==g_OwnerWindow || (HWND)lParam==g_TopWin7Menu)
return 0;
if (s_bPreventClosing && (::GetWindowLong((HWND)lParam,GWL_EXSTYLE)&WS_EX_TOPMOST))
return 0;
}
// a non-top-most window tries to activate while we are still here
if (s_bPreventClosing && (!g_TopWin7Menu || !s_bAllPrograms))
HideTemp(true);
else
{
for (std::vector<CMenuContainer*>::reverse_iterator it=s_Menus.rbegin();it!=s_Menus.rend();++it)
if ((*it)->m_hWnd && !(*it)->m_bDestroyed)
{
(*it)->PostMessage(WM_CLOSE);
(*it)->m_bClosing=true;
}
if (g_TopWin7Menu && s_bAllPrograms) ::PostMessage(g_TopWin7Menu,WM_CLOSE,0,0);
}
for (std::vector<CMenuContainer*>::reverse_iterator it=s_Menus.rbegin();it!=s_Menus.rend();++it)
if ((*it)->m_hWnd && !(*it)->m_bDestroyed)
{
(*it)->PostMessage(WM_CLOSE);
(*it)->m_bClosing=true;
}
if (g_TopWin7Menu && s_bAllPrograms) ::PostMessage(g_TopWin7Menu,WM_CLOSE,0,0);
#endif
return 0;

View File

@@ -957,7 +957,6 @@ private:
friend LRESULT CALLBACK SubclassTopMenuProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData );
friend HRESULT CreatePinLink( PCIDLIST_ABSOLUTE sourcePidl, const wchar_t *name, const wchar_t *iconPath, int iconIndex );
static void HideTemp( bool bHide );
static void AddMRUShortcut( const wchar_t *path );
static void AddMRUAppId( const wchar_t *appid );
static void DeleteMRUShortcut( const wchar_t *path );

View File

@@ -1601,8 +1601,6 @@ HRESULT CProgramsTree::Drop( IDataObject *pDataObj, DWORD grfKeyState, POINTL pt
CMenuContainer::s_bPreventClosing=true;
m_pOwner->AddRef();
pTarget->Drop(pDataObj,grfKeyState,pt,pdwEffect);
if (!bOld)
CMenuContainer::HideTemp(false);
CMenuContainer::s_bPreventClosing=bOld;
for (std::vector<CMenuContainer*>::iterator it=CMenuContainer::s_Menus.begin();it!=CMenuContainer::s_Menus.end();++it)
if (!(*it)->m_bDestroyed)

View File

@@ -292,7 +292,6 @@ public:
// message handlers
BEGIN_MSG_MAP( COwnerWindow )
MESSAGE_HANDLER( WM_ACTIVATE, OnActivate )
MESSAGE_HANDLER( WM_CLEAR, OnClear )
MESSAGE_HANDLER( WM_SYSCOLORCHANGE, OnColorChange )
MESSAGE_HANDLER( WM_SETTINGCHANGE, OnSettingChange )
MESSAGE_HANDLER( WM_DISPLAYCHANGE, OnDisplayChange )
@@ -304,7 +303,7 @@ protected:
if (LOWORD(wParam)!=WA_INACTIVE)
return 0;
if (CMenuContainer::s_bPreventClosing && lParam && (::GetWindowLongPtr((HWND)lParam,GWL_EXSTYLE)&WS_EX_TOPMOST))
if (CMenuContainer::s_bPreventClosing)
return 0;
// check if another menu window is being activated
@@ -313,41 +312,13 @@ protected:
if ((*it)->m_hWnd==(HWND)lParam)
return 0;
if (CMenuContainer::s_bPreventClosing)
{
CMenuContainer::HideTemp(true);
}
else
{
for (std::vector<CMenuContainer*>::reverse_iterator it=CMenuContainer::s_Menus.rbegin();it!=CMenuContainer::s_Menus.rend();++it)
if (!(*it)->m_bDestroyed)
(*it)->PostMessage(WM_CLOSE);
}
for (std::vector<CMenuContainer*>::reverse_iterator it=CMenuContainer::s_Menus.rbegin();it!=CMenuContainer::s_Menus.rend();++it)
if (!(*it)->m_bDestroyed)
(*it)->PostMessage(WM_CLOSE);
return 0;
}
LRESULT OnClear( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
bool bHide=(wParam!=0); // hide or destroy
if (CMenuContainer::s_bTempHidden!=bHide)
{
CMenuContainer::s_bTempHidden=bHide;
if (bHide && CMenuContainer::s_UserPicture.m_hWnd)
CMenuContainer::s_UserPicture.ShowWindow(SW_HIDE);
for (std::vector<CMenuContainer*>::iterator it=CMenuContainer::s_Menus.begin();it!=CMenuContainer::s_Menus.end();++it)
{
if ((*it)->m_hWnd && !(*it)->m_bDestroyed)
{
(*it)->m_bClosing=true;
if (!bHide)
(*it)->PostMessage(WM_CLOSE);
else
(*it)->ShowWindow(SW_HIDE);
}
}
}
return 0;
}
LRESULT OnColorChange( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{