赞助

Duilib 实现窗口点击关闭确认退出提示

此功能是记住用户的操作,在用户点击关闭时是真退出程序还是最小化到托盘,我们常见的PC客户端都有此功能,例如:IMO客户端、网易云音乐

  

 

我自己的项目中也要实现此功能,在此总结一下,最终效果:

.h文件

 1 #ifndef _CLOSEHINTDIALOG_H_
 2 #define _CLOSEHINTDIALOG_H_
 3 
 4 class CCloseHintDialog :public WindowImplBase
 5 {
 6 public:
 7     CCloseHintDialog();
 8 
 9     ~CCloseHintDialog();
10 
11 public:
12     virtual LPCTSTR GetWindowClassName() const;
13 
14     virtual void OnFinalMessage(HWND hWnd);
15 
16     virtual CDuiString GetSkinFile();
17 
18     virtual CDuiString GetSkinFolder();
19 
20     virtual UILIB_RESOURCETYPE GetResourceType() const;
21 
22     virtual CControlUI* CreateControl(LPCTSTR pstrClassName);
23 
24     virtual LRESULT ResponseDefaultKeyEvent(WPARAM wParam);
25 
26     virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam); 
27 
28     virtual void Notify(TNotifyUI& msg);
29 
30     virtual void OnClick(TNotifyUI& msg);
31 
32     virtual void InitWindow();
33 
34     void OnPrepare();
35 
36 public:
37 
38     COptionUI  * m_pBtnYES;
39 
40     COptionUI * m_pBtnNO;
41 
42     COptionUI  * m_pExitbtn;
43 
44     COptionUI  * m_pMoveToTraybtn;
45 
46     CCheckBoxUI* m_pchkOption;
47 };
48 #endif//_CLOSEHINTDIALOG_H_

.cpp文件

  1 #include "..\..\stdafx.h"
  2 #include "CloseHintDialog.h"
  3 
  4 CCloseHintDialog::CCloseHintDialog()
  5     :m_pBtnYES(NULL)
  6     ,m_pBtnNO(NULL)
  7     ,m_pExitbtn(NULL)
  8     ,m_pchkOption(NULL)
  9     ,m_pMoveToTraybtn(NULL)
 10 {
 11 
 12 }
 13 
 14 CCloseHintDialog::~CCloseHintDialog()
 15 {
 16 
 17 }
 18 
 19 LPCTSTR CCloseHintDialog::GetWindowClassName() const
 20 {
 21     return TEXT("CloseHintDialog");
 22 }
 23 
 24 void CCloseHintDialog::OnFinalMessage(HWND hWnd)
 25 {
 26     CWindowWnd::OnFinalMessage(hWnd);
 27 }
 28 
 29 CDuiString CCloseHintDialog::GetSkinFile()
 30 {
 31     return TEXT("xml//CloseHintDlg.xml");
 32 }
 33 
 34 CDuiString CCloseHintDialog::GetSkinFolder()
 35 {
 36     return TEXT("");
 37 }
 38 
 39 LRESULT CCloseHintDialog::ResponseDefaultKeyEvent(WPARAM wParam)
 40 {
 41     if (wParam == VK_RETURN)
 42     {
 43         return FALSE;
 44     }
 45     else if (wParam == VK_ESCAPE)
 46     {
 47         //Close();
 48         return TRUE;
 49     }
 50     return FALSE;
 51 }
 52 
 53 UILIB_RESOURCETYPE CCloseHintDialog::GetResourceType() const
 54 {
 55     return UILIB_FILE;
 56 }
 57 
 58 CControlUI* CCloseHintDialog::CreateControl(LPCTSTR pstrClassName)
 59 {
 60     return NULL;
 61 }
 62 
 63 void CCloseHintDialog::InitWindow()
 64 {
 65     m_pBtnYES = static_cast<COptionUI *>(m_PaintManager.FindControl(TEXT("yesbtn")));
 66 
 67     m_pBtnNO = static_cast<COptionUI *>(m_PaintManager.FindControl(TEXT("nobtn")));
 68 
 69     m_pExitbtn = static_cast<COptionUI *>(m_PaintManager.FindControl(TEXT("ExitDirectbtn")));
 70 
 71     m_pMoveToTraybtn = static_cast<COptionUI *>(m_PaintManager.FindControl(TEXT("MoveInTraybtn")));
 72 
 73     m_pchkOption =  static_cast<CCheckBoxUI*>(m_PaintManager.FindControl(TEXT("chkOption")));
 74 
 75 }
 76 
 77 void CCloseHintDialog::OnPrepare()
 78 {
 79 
 80 }
 81 
 82 void CCloseHintDialog::Notify(TNotifyUI& msg)
 83 {
 84     if( msg.sType == TEXT("windowinit") ) OnPrepare();
 85 
 86     if(msg.sType == TEXT("click"))
 87     {
 88         if(msg.pSender->GetName()==TEXT("closebtn"))
 89         {
 90             Close(IDCLOSE);
 91         }
 92         else if(msg.pSender->GetName() == TEXT("yesbtn"))
 93         {
 94             Close(IDOK);
 95         }
 96         else if (msg.pSender->GetName() == _T("nobtn"))
 97         {
 98             Close(IDCANCEL);
 99         }
100     }
101     WindowImplBase::Notify(msg);
102 }
103 
104 void CCloseHintDialog::OnClick(TNotifyUI& msg)
105 {
106     __super::OnClick(msg);
107 }
108 
109 //禁用双击标题栏窗口最大化
110 LRESULT CCloseHintDialog::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
111 {
112     LRESULT lRes = 0;
113     BOOL bHandled = TRUE;
114 
115     switch( uMsg ) 
116     {
117     case WM_NCLBUTTONDBLCLK:
118         //不做处理
119         {
120             return 0;
121         }
122         break;
123     default:
124         bHandled = FALSE;
125     }
126     return WindowImplBase::HandleMessage(uMsg,wParam,lParam);
127 }

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.恢复的原理:将窗口显示

在点击关闭按钮响应函数里面处理:

 1 bool OnExitConfirm()
 2 {
 3     bool bResult = false;
 4     //从配置文件中读取用户设置
 5     TCHAR cofigValue[MAX_PATH];
 6     CString tszModule = CommonUtils::GetModuleDirectory();
 7     tszModule+="\\config.ini";
 8     ::GetPrivateProfileString(L"Setting",L"ExitDirect",L"Error",cofigValue,MAX_PATH,tszModule);
 9 
10     if (_tcsicmp(cofigValue,_T("Error")) == 0)//配置文件里面没有
11     {
12         CCloseHintDialog closeHintBox;
13         closeHintBox.Create(this->GetHWND(), _T("CloseHintDialog"), UI_WNDSTYLE_EX_FRAME, WS_EX_WINDOWEDGE);
14         closeHintBox.CenterWindow();
15 
16         if(closeHintBox.ShowModal()== IDOK)
17         {
18             if (closeHintBox.m_pchkOption->GetCheck())//勾选
19             {
20                 if(closeHintBox.m_pExitbtn->IsSelected())
21                 {
22                     CString strExit;
23                     strExit.Format(L"%d",1);
24                     ::WritePrivateProfileString(L"Setting",L"ExitDirect",strExit,tszModule);
25 
26                     Close(IDCLOSE);
27 
28                     bResult = true;
29 
30                     return bResult;
31 
32                 }
33                 else if (closeHintBox.m_pMoveToTraybtn->IsSelected())
34                 {
35                     CString strExit;
36                     strExit.Format(L"%d",0);
37                     ::WritePrivateProfileString(L"Setting",L"ExitDirect",strExit,tszModule);
38 
39                     ::ShowWindow(this->GetHWND(),SW_HIDE);
40 
41                     return bResult;
42                 }
43             }
44             else//不勾选
45             {
46                 if(closeHintBox.m_pExitbtn->IsSelected())
47                 {
48                     Close(IDCLOSE);
49 
50                     bResult = true;
51 
52                     return bResult;
53                 }
54                 else if (closeHintBox.m_pMoveToTraybtn->IsSelected())
55                 {
56                     ::ShowWindow(this->GetHWND(),SW_HIDE);
57                     return bResult;
58                 }
59             }
60         }
61         else
62         {
63             return bResult;
64         }
65     }
66     else
67     {
68         if (_tcsicmp(cofigValue,_T("1")) == 0)
69         {
70             Close(IDCLOSE);
71 
72             bResult = true;
73 
74             return bResult;
75         }
76         else if (_tcsicmp(cofigValue,_T("0")) == 0)
77         {
78             ::ShowWindow(this->GetHWND(),SW_HIDE);
79             return bResult;
80         }
81     }
82 
83     return bResult;
84 }

 

恢复界面函数

 1 LRESULT CMainFrameWnd::OnTrayNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
 2 {
 3     if(wParam == 1000)
 4     {
 5         switch(lParam)
 6         {
 7                ...
 8 
 9         case WM_LBUTTONDBLCLK:
10             {
11                 ::ShowWindow(this->GetHWND(),SW_SHOW);//显示窗口
12             }
13             break;
14         }
15     }
16     return 0;
17 }

 转载:http://blog.sina.com.cn/s/blog_845245d101017djr.html

posted @ 2016-11-02 14:43  车臣  阅读(4570)  评论(0编辑  收藏  举报