此功能是记住用户的操作,在用户点击关闭时是真退出程序还是最小化到托盘,我们常见的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 ;
}

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

Duilib 实现窗口点击关闭确认退出提示的更多相关文章

  1. 页面点击关闭弹出提示js代码

    代码效果为: <script> window.onbeforeunload = function() { return "您好!\n我是abc\n —————————————— ...

  2. [Selenium]通过Selenium实现在当前浏览器窗口点击一个图标之后,弹出另外一个窗口,关闭这个窗口,再回到原来的窗口进行操作

    public void clickReportIcon(){ String initialWindowHandle = driver.getWindowHandle(); //保存原始的浏览器窗口 p ...

  3. VB.Net中确认退出对话框的实现

    实现方法分为两大类:窗体事件和控件事件,下面就一一展示: 一.FormClosing事件(又分以下几种方法) a. Private Sub frmPractise_FormClosing(ByVal ...

  4. Windows中点击“关闭”button发生了什么?

    对于Windows操作,当用户点击"关闭"button时,窗体函数就会收到一个WM_DESTROY消息. 窗体函数应该调用PostQuitMessage(0) 向消息队列插入一个W ...

  5. 简单数学算法demo和窗口跳转,关闭,弹框

     简单数学算法demo和窗口跳转,关闭,弹框demo <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&quo ...

  6. bootstrap 模态框禁用空白处点击关闭

    bootstrap 3 模态框为信息编辑窗口,默认点击空白处会自动关闭,但是有的时候这个功能需要关闭,比如编辑信息,一不小心点击了空白处,那就要重新编辑了. bootstrap 3 模态框禁用空白处点 ...

  7. WinForm------如何跳转另一个窗口,同时关闭当前窗口

    添加一个按钮,并为按钮添加点击事件(注:Frm_Main为需要跳转的窗口名字) private void Btn_OK_Click(object sender, EventArgs e) { //打开 ...

  8. Android alertdialog实现确认退出

    package com.example.alertdialog; import android.os.Bundle; import android.app.Activity; import andro ...

  9. JS关闭窗口或JS关闭页面的几种代码

    //JS定时自动关闭窗口 <script language="javascript"> <!-- function closewin(){ self.opener ...

随机推荐

  1. Run P4 without P4factory - A Simple Example In Tutorials. -2 附 simple_router源码

    /* Copyright 2013-present Barefoot Networks, Inc. Licensed under the Apache License, Version 2.0 (th ...

  2. C使用相关笔记

    #将c文件编译成动态库 //hello.c int hello_add(int a, int b) { return a + b; } gcc -O -c -fPIC -o hello.o hello ...

  3. 正则基础之——捕获组(capture group)

    1        概述 1.1     什么是捕获组 捕获组就是把正则表达式中子表达式匹配的内容,保存到内存中以数字编号或显式命名的组里,方便后面引用.当然,这种引用既可以是在正则表达式内部,也可以是 ...

  4. 学习mysql

    一 概述 1.什么是数据库 数据库就是数据的仓库. mysql是对数据库进行存储和指令操作的软件.这类软件成为数据管理系统Database Management System. 2.mysql的安装和 ...

  5. Java提高篇——equals()与hashCode()方法详解

    java.lang.Object类中有两个非常重要的方法: 1 2 public boolean equals(Object obj) public int hashCode() Object类是类继 ...

  6. 调用java rest ful 接口实例

    HttpWebRequest request = WebRequest.Create("http://192.168.0.99:8080/wzh-webservice/rest/login? ...

  7. JQuery1.11版本对prop和attr接口的含义分离导致问题分析

    问题背景 实验中, 在jquery1.7版本, attr("value")  和 val() 接口获取 input 控件的值, 都是一致的, 都是当前控件值. 但是 jquery1 ...

  8. RDIFramework.NET ━ .NET快速信息化系统开发框架钜献 V2.9 版本震撼发布

    RDIFramework.NET ━ .NET快速信息化系统开发框架钜献 V2.9 版本震撼发布 全新体验.全新感觉.2015钜献! 继上个版本“RDIFramework.NET V2.8版本发布”5 ...

  9. OleContainer控件介绍

    OLEContainer 控件的主要属性 1)  AllowInPlace              property AllowInPlace:Boolean;        这个属性用于决定启动O ...

  10. hadoop datanode启动失败

    问题导读: 1.Hadoop出现问题时,该如何入手查看问题?2.datanode无法启动,我们该怎么解决?3.如何动态加入DataNode或TaskTracker? 一.问题描述当我多次格式化文件系统 ...