此功能是记住用户的操作,在用户点击关闭时是真退出程序还是最小化到托盘,我们常见的PC客户端都有此功能,例如:IMO客户端、网易云音乐
我自己的项目中也要实现此功能,在此总结一下,最终效果:
.h文件
#ifndef _CLOSEHINTDIALOG_H_
#define _CLOSEHINTDIALOG_H_ class CCloseHintDialog :public WindowImplBase
{
public:
CCloseHintDialog(); ~CCloseHintDialog(); public:
virtual LPCTSTR GetWindowClassName() const; virtual void OnFinalMessage(HWND hWnd); virtual CDuiString GetSkinFile(); virtual CDuiString GetSkinFolder(); virtual UILIB_RESOURCETYPE GetResourceType() const; virtual CControlUI* CreateControl(LPCTSTR pstrClassName); virtual LRESULT ResponseDefaultKeyEvent(WPARAM wParam); virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam); virtual void Notify(TNotifyUI& msg); virtual void OnClick(TNotifyUI& msg); virtual void InitWindow(); void OnPrepare(); public: COptionUI * m_pBtnYES; COptionUI * m_pBtnNO; COptionUI * m_pExitbtn; COptionUI * m_pMoveToTraybtn; CCheckBoxUI* m_pchkOption;
};
#endif//_CLOSEHINTDIALOG_H_
.cpp文件
#include "..\..\stdafx.h"
#include "CloseHintDialog.h" CCloseHintDialog::CCloseHintDialog()
:m_pBtnYES(NULL)
,m_pBtnNO(NULL)
,m_pExitbtn(NULL)
,m_pchkOption(NULL)
,m_pMoveToTraybtn(NULL)
{ } CCloseHintDialog::~CCloseHintDialog()
{ } LPCTSTR CCloseHintDialog::GetWindowClassName() const
{
return TEXT("CloseHintDialog");
} void CCloseHintDialog::OnFinalMessage(HWND hWnd)
{
CWindowWnd::OnFinalMessage(hWnd);
} CDuiString CCloseHintDialog::GetSkinFile()
{
return TEXT("xml//CloseHintDlg.xml");
} CDuiString CCloseHintDialog::GetSkinFolder()
{
return TEXT("");
} LRESULT CCloseHintDialog::ResponseDefaultKeyEvent(WPARAM wParam)
{
if (wParam == VK_RETURN)
{
return FALSE;
}
else if (wParam == VK_ESCAPE)
{
//Close();
return TRUE;
}
return FALSE;
} UILIB_RESOURCETYPE CCloseHintDialog::GetResourceType() const
{
return UILIB_FILE;
} CControlUI* CCloseHintDialog::CreateControl(LPCTSTR pstrClassName)
{
return NULL;
} void CCloseHintDialog::InitWindow()
{
m_pBtnYES = static_cast<COptionUI *>(m_PaintManager.FindControl(TEXT("yesbtn"))); m_pBtnNO = static_cast<COptionUI *>(m_PaintManager.FindControl(TEXT("nobtn"))); m_pExitbtn = static_cast<COptionUI *>(m_PaintManager.FindControl(TEXT("ExitDirectbtn"))); m_pMoveToTraybtn = static_cast<COptionUI *>(m_PaintManager.FindControl(TEXT("MoveInTraybtn"))); m_pchkOption = static_cast<CCheckBoxUI*>(m_PaintManager.FindControl(TEXT("chkOption"))); } void CCloseHintDialog::OnPrepare()
{ } void CCloseHintDialog::Notify(TNotifyUI& msg)
{
if( msg.sType == TEXT("windowinit") ) OnPrepare(); if(msg.sType == TEXT("click"))
{
if(msg.pSender->GetName()==TEXT("closebtn"))
{
Close(IDCLOSE);
}
else if(msg.pSender->GetName() == TEXT("yesbtn"))
{
Close(IDOK);
}
else if (msg.pSender->GetName() == _T("nobtn"))
{
Close(IDCANCEL);
}
}
WindowImplBase::Notify(msg);
} void CCloseHintDialog::OnClick(TNotifyUI& msg)
{
__super::OnClick(msg);
} //禁用双击标题栏窗口最大化
LRESULT CCloseHintDialog::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT lRes = ;
BOOL bHandled = TRUE; switch( uMsg )
{
case WM_NCLBUTTONDBLCLK:
//不做处理
{
return ;
}
break;
default:
bHandled = FALSE;
}
return WindowImplBase::HandleMessage(uMsg,wParam,lParam);
}
xml文件
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<Window size="370,170" caption="0,0,0,30" sizebox="0,0,0,0" roundcorner="1,1">
<Font name="微软雅黑" size="12" bold="false" italic="false" underline="false" />
<Font name="微软雅黑" size="14" bold="false" italic="false" underline="false" />
<VerticalLayout bkcolor="#FFFFFFFF" bkimage="file='image\closetitle.png'" >
<HorizontalLayout height="30" >
<Control width="10"/>
<Label textcolor="#FFFFFFFF" width="52" height="14" padding="0,5,0,0" />
<Control />
<Button name="closebtn" height="22" width="27" normalimage=" file='image\sysButton\close.png'" hotimage=" file='image\sysButton\close_hover.png'" pushedimage=" file='image\sysButton\close_pressed.png'"/>
</HorizontalLayout>
<VerticalLayout inset="54,8,0,0" bkcolor="#FFFFFFFF">
<Label name="msg_text" text="关闭主面板时:" height="22" align="left" textcolor="#FF333333" font="0"/>
<Option name="ExitDirectbtn" text="退出程序" height="22" width="180" padding="24,-5,0,0" textpadding="18,5,0,0" textcolor="#FF333333" align="left" selectedimage="file='image\Button\RadioBtnSel.png' source='0,0,12,12' dest='0,7,12,20'" normalimage="file='image\Button\RadioBtnNon.png' source='0,0,12,12' dest='0,7,12,20'" group="RadioBoxTest" selected="true" font="0"/>
<Option name="MoveInTraybtn" text="隐藏到任务通知栏,不退出程序" height="22" width="230" padding="24,0,0,0" textpadding="18,5,0,0" textcolor="#FF333333" align="left" selectedimage="file='image\Button\RadioBtnSel.png' source='0,0,12,12' dest='0,7,12,20'" normalimage="file='image\Button\RadioBtnNon.png' source='0,0,12,12' dest='0,7,12,20'" group="RadioBoxTest" font="0"/>
</VerticalLayout>
<HorizontalLayout height="49" bkcolor="#FFFFFFFF">
<Control width="10"/>
<CheckBox name="chkOption" width="14" height="32" padding="0,9,0,0" normalimage="file='image\CheckBox\ungouxuan.png' source='0,0,14,14' dest='0,7,14,21'" selectedimage="file='image\CheckBox\gouxuan.png' source='0,0,14,14' dest='0,7,14,21'"/>
<Label text="下次不再提示(A)" width="90" height="32" padding="5,7,0,0" textcolor="#FF333333" font="0"/>
<Control />
<Button name="yesbtn" text="是(Y)" height="22" width="74" padding="0,13,0,0" textcolor="#FF333333" align="center" normalimage="file='image\Button\yes_or_no.jpg'" hotimage=" file='image\Button\yes_or_no-green.png'" pushedimage="file='image\Button\yes_or_no.jpg'" font="0"/>
<Button name="nobtn" text="否(N)" height="22" width="74" padding="5,13,0,0" textcolor="#FF333333" align="center" normalimage="file='image\Button\yes_or_no.jpg'" hotimage=" file='image\Button\yes_or_no-green.png'" pushedimage="file='image\Button\yes_or_no.jpg'" font="0"/>
<Control width="10"/>
</HorizontalLayout>
<HorizontalLayout height="5" bkcolor="#FFEDF3FC"/>
</VerticalLayout>
</Window>
1.最小化托盘原理: 首先要将窗口隐藏,然后在右下角绘制托盘图标
2.恢复的原理:将窗口显示
在点击关闭按钮响应函数里面处理:
bool OnExitConfirm()
{
bool bResult = false;
//从配置文件中读取用户设置
TCHAR cofigValue[MAX_PATH];
CString tszModule = CommonUtils::GetModuleDirectory();
tszModule+="\\config.ini";
::GetPrivateProfileString(L"Setting",L"ExitDirect",L"Error",cofigValue,MAX_PATH,tszModule); if (_tcsicmp(cofigValue,_T("Error")) == )//配置文件里面没有
{
CCloseHintDialog closeHintBox;
closeHintBox.Create(this->GetHWND(), _T("CloseHintDialog"), UI_WNDSTYLE_EX_FRAME, WS_EX_WINDOWEDGE);
closeHintBox.CenterWindow(); if(closeHintBox.ShowModal()== IDOK)
{
if (closeHintBox.m_pchkOption->GetCheck())//勾选
{
if(closeHintBox.m_pExitbtn->IsSelected())
{
CString strExit;
strExit.Format(L"%d",);
::WritePrivateProfileString(L"Setting",L"ExitDirect",strExit,tszModule); Close(IDCLOSE); bResult = true; return bResult; }
else if (closeHintBox.m_pMoveToTraybtn->IsSelected())
{
CString strExit;
strExit.Format(L"%d",);
::WritePrivateProfileString(L"Setting",L"ExitDirect",strExit,tszModule); ::ShowWindow(this->GetHWND(),SW_HIDE); return bResult;
}
}
else//不勾选
{
if(closeHintBox.m_pExitbtn->IsSelected())
{
Close(IDCLOSE); bResult = true; return bResult;
}
else if (closeHintBox.m_pMoveToTraybtn->IsSelected())
{
::ShowWindow(this->GetHWND(),SW_HIDE);
return bResult;
}
}
}
else
{
return bResult;
}
}
else
{
if (_tcsicmp(cofigValue,_T("")) == )
{
Close(IDCLOSE); bResult = true; return bResult;
}
else if (_tcsicmp(cofigValue,_T("")) == )
{
::ShowWindow(this->GetHWND(),SW_HIDE);
return bResult;
}
} return bResult;
}
恢复界面函数
LRESULT CMainFrameWnd::OnTrayNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if(wParam == )
{
switch(lParam)
{
... case WM_LBUTTONDBLCLK:
{
::ShowWindow(this->GetHWND(),SW_SHOW);//显示窗口
}
break;
}
}
return ;
}