关于系统托盘问题

danxuezx ASUS 开发组长/高级工程师/技术专家  2010-07-03 01:10:25
想做一个具有下面行为的窗口:

双击之后不弹出窗口,只出现在系统托盘中。
单击系统托盘图标后再弹出窗口,但在任务栏中不要出现。

这个大概是怎样的思路?
...全文
120 点赞 收藏 23
写回复
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
C瓜哥 2010-07-04
VC++6.0需要改ShellAPI.h

////
//// Tray notification definitions
////
…………………………
////
//// End Tray Notification Icons
////

改成
////
//// Tray notification definitions
////
typedef struct _NOTIFYICONDATAA {
DWORD cbSize;
HWND hWnd;
UINT uID;
UINT uFlags;
UINT uCallbackMessage;
HICON hIcon;
#if (_WIN32_IE < 0x0500)
CHAR szTip[64];
#else
CHAR szTip[128];
#endif
#if (_WIN32_IE >= 0x0500)
DWORD dwState;
DWORD dwStateMask;
CHAR szInfo[256];
union {
UINT uTimeout;
UINT uVersion;
} DUMMYUNIONNAME;
CHAR szInfoTitle[64];
DWORD dwInfoFlags;
#endif
#if (_WIN32_IE >= 0x600)
GUID guidItem;
#endif
} NOTIFYICONDATAA, *PNOTIFYICONDATAA;
typedef struct _NOTIFYICONDATAW {
DWORD cbSize;
HWND hWnd;
UINT uID;
UINT uFlags;
UINT uCallbackMessage;
HICON hIcon;
#if (_WIN32_IE < 0x0500)
WCHAR szTip[64];
#else
WCHAR szTip[128];
#endif
#if (_WIN32_IE >= 0x0500)
DWORD dwState;
DWORD dwStateMask;
WCHAR szInfo[256];
union {
UINT uTimeout;
UINT uVersion;
} DUMMYUNIONNAME;
WCHAR szInfoTitle[64];
DWORD dwInfoFlags;
#endif
#if (_WIN32_IE >= 0x600)
GUID guidItem;
#endif
} NOTIFYICONDATAW, *PNOTIFYICONDATAW;
#ifdef UNICODE
typedef NOTIFYICONDATAW NOTIFYICONDATA;
typedef PNOTIFYICONDATAW PNOTIFYICONDATA;
#else
typedef NOTIFYICONDATAA NOTIFYICONDATA;
typedef PNOTIFYICONDATAA PNOTIFYICONDATA;
#endif // UNICODE
#define NOTIFYICONDATAA_V1_SIZE FIELD_OFFSET(NOTIFYICONDATAA, szTip[64])
#define NOTIFYICONDATAW_V1_SIZE FIELD_OFFSET(NOTIFYICONDATAW, szTip[64])
#ifdef UNICODE
#define NOTIFYICONDATA_V1_SIZE NOTIFYICONDATAW_V1_SIZE
#else
#define NOTIFYICONDATA_V1_SIZE NOTIFYICONDATAA_V1_SIZE
#endif
#define NOTIFYICONDATAA_V2_SIZE FIELD_OFFSET(NOTIFYICONDATAA, guidItem)
#define NOTIFYICONDATAW_V2_SIZE FIELD_OFFSET(NOTIFYICONDATAW, guidItem)
#ifdef UNICODE
#define NOTIFYICONDATA_V2_SIZE NOTIFYICONDATAW_V2_SIZE
#else
#define NOTIFYICONDATA_V2_SIZE NOTIFYICONDATAA_V2_SIZE
#endif
#if (_WIN32_IE >= 0x0500)
#define NIN_SELECT (WM_USER + 0)
#define NINF_KEY 0x1
#define NIN_KEYSELECT (NIN_SELECT | NINF_KEY)
#endif
#if (_WIN32_IE >= 0x0501)
#define NIN_BALLOONSHOW (WM_USER + 2)
#define NIN_BALLOONHIDE (WM_USER + 3)
#define NIN_BALLOONTIMEOUT (WM_USER + 4)
#define NIN_BALLOONUSERCLICK (WM_USER + 5)
#endif
#define NIM_ADD 0x00000000
#define NIM_MODIFY 0x00000001
#define NIM_DELETE 0x00000002
#if (_WIN32_IE >= 0x0500)
#define NIM_SETFOCUS 0x00000003
#define NIM_SETVERSION 0x00000004
#define NOTIFYICON_VERSION 3
#endif
#define NIF_MESSAGE 0x00000001
#define NIF_ICON 0x00000002
#define NIF_TIP 0x00000004
#if (_WIN32_IE >= 0x0500)
#define NIF_STATE 0x00000008
#define NIF_INFO 0x00000010
#endif
#if (_WIN32_IE >= 0x600)
#define NIF_GUID 0x00000020
#endif
#if (_WIN32_IE >= 0x0500)
#define NIS_HIDDEN 0x00000001
#define NIS_SHAREDICON 0x00000002
// says this is the source of a shared icon
// Notify Icon Infotip flags
#define NIIF_NONE 0x00000000
// icon flags are mutually exclusive
// and take only the lowest 2 bits
#define NIIF_INFO 0x00000001
#define NIIF_WARNING 0x00000002
#define NIIF_ERROR 0x00000003
#define NIIF_ICON_MASK 0x0000000F
#if (_WIN32_IE >= 0x0501)
#define NIIF_NOSOUND 0x00000010
#endif
#endif
SHSTDAPI_(BOOL) Shell_NotifyIconA(DWORD dwMessage, PNOTIFYICONDATAA lpData);
SHSTDAPI_(BOOL) Shell_NotifyIconW(DWORD dwMessage, PNOTIFYICONDATAW lpData);
#ifdef UNICODE
#define Shell_NotifyIcon Shell_NotifyIconW
#else
#define Shell_NotifyIcon Shell_NotifyIconA
#endif // !UNICODE
////
//// End Tray Notification Icons
////
回复
danxuezx 2010-07-04
[Quote=引用 14 楼 cnzdgs 的回复:]
不要用模态对话框,自己创建窗口,不显示,再执行消息循环,并添加相应的代码以便在适当的条件下退出程序。
[/Quote]
前辈的名人标识帅气透了!!
回复
danxuezx 2010-07-04
[Quote=引用 12 楼 zwfgdlc 的回复:]
引用 10 楼 danxuezx 的回复:
这个我也有试过,关键是它还是会出现在任务栏里。


C/C++ code

Shell_NotifyIcon(NIM_ADD,&nid);




C/C++ code
Shell_NotifyIcon(NIM_DELETE,&nid);

就不出现在任务栏了。
[/Quote]
这个肯定达不到想要的效果。


[Quote=引用 14 楼 cnzdgs 的回复:]
不要用模态对话框,自己创建窗口,不显示,再执行消息循环,并添加相应的代码以便在适当的条件下退出程序。
[/Quote]
刚好看到一个例子是通过这种方法来做的。这是最简单合理的方法了吗?
回复
cnzdgs 2010-07-04
CSDN出问题了,09年度勋章计算了两次,所以才有了名人勋章,说不定那天就收回去了。
回复
danxuezx 2010-07-04
非常感谢各位前辈的指点,我终于明白其中的道理了。
回复
danxuezx 2010-07-04
[Quote=引用 20 楼 oyljerry 的回复:]
DoModal你显示的代码很多由MFC控制的,你用Create方式,就可以方便的控制自己ShowWindow的时机,根据你的需要来决定什么时候显示,隐藏
[/Quote]
原来是这样的,我明白了。非常感谢您的指点。


又一位名人,羡慕……


回复
oyljerry 2010-07-04
[Quote=引用 15 楼 danxuezx 的回复:]

引用 12 楼 zwfgdlc 的回复:
引用 10 楼 danxuezx 的回复:
这个我也有试过,关键是它还是会出现在任务栏里。


C/C++ code

Shell_NotifyIcon(NIM_ADD,&amp;nid);




C/C++ code
Shell_NotifyIcon(NIM_DELETE,&amp;nid);

就不出……
[/Quote]
DoModal你显示的代码很多由MFC控制的,你用Create方式,就可以方便的控制自己ShowWindow的时机,根据你的需要来决定什么时候显示,隐藏
回复
Eleven 2010-07-04
如果要隐藏对话框,可以重载虚函数DefWindowProc,在里面
if(WM_NCPAINT == message)
{
ShowWindow(m_bShow ? SW_SHOW : SW_HIDE);//m_bShow为该对话框类的BOOL类型变量,
//用来显示或者隐藏对话框。。。
}
...
回复
Eleven 2010-07-04
[Quote=引用 10 楼 danxuezx 的回复:]
引用 2 楼 rebort_q 的回复:
C/C++ code

void MinIcon
{
NOTIFYICONDATA nid;
nid.cbSize=(DWORD)sizeof(NOTIFYICONDATA);
nid.hWnd=this->m_hWnd;
nid.uID=IDR_MAINFRAME;
nid.uFlags=NIF_ICON|NIF_MESSAGE|NIF……
[/Quote]

在OnInitDialog函数中调用
ModifyStyleEx(WS_EX_APPWINDOW, WS_EX_TOOLWINDOW);修改对话框风格以后,就不会出现在任务栏了。。
回复
cnzdgs 2010-07-03
不要用模态对话框,自己创建窗口,不显示,再执行消息循环,并添加相应的代码以便在适当的条件下退出程序。
回复
m_nAdrs 2010-07-03
想让程序运行, 但是别人看不到?
回复
zwfgdlc 2010-07-03
[Quote=引用 10 楼 danxuezx 的回复:]
这个我也有试过,关键是它还是会出现在任务栏里。
[/Quote]

Shell_NotifyIcon(NIM_ADD,&nid);


Shell_NotifyIcon(NIM_DELETE,&nid);  

就不出现在任务栏了。
回复
向立天 2010-07-03
[Quote=引用 9 楼 danxuezx 的回复:]
引用 3 楼 xianglitian 的回复:
托盘你会创建吧
这个不多说了
启动不现实窗口可以通过启动命令行控制
因为双击一定是不传入命令行参数的
所以可以通过这个实现启动时窗口隐藏
至于隐藏任务栏按钮我是这么实现的
做一个隐藏的父窗口
然后将显示的窗口作为它的子窗口

这个应该能够解决,但感觉有更合理的做法。
[/Quote]
你无非就是想做QQ的效果么
spy++看看QQ的窗口风格
不过我当时模拟的时候就是用的我说的方法
我知道QQ没有父窗口不过我觉得有一个MainFrame其实做东西挺方便的
回复
danxuezx 2010-07-03
[Quote=引用 2 楼 rebort_q 的回复:]
C/C++ code

void MinIcon
{
NOTIFYICONDATA nid;
nid.cbSize=(DWORD)sizeof(NOTIFYICONDATA);
nid.hWnd=this->m_hWnd;
nid.uID=IDR_MAINFRAME;
nid.uFlags=NIF_ICON|NIF_MESSAGE|NIF_T……
[/Quote]
这个我也有试过,关键是它还是会出现在任务栏里。
回复
danxuezx 2010-07-03
[Quote=引用 3 楼 xianglitian 的回复:]
托盘你会创建吧
这个不多说了
启动不现实窗口可以通过启动命令行控制
因为双击一定是不传入命令行参数的
所以可以通过这个实现启动时窗口隐藏
至于隐藏任务栏按钮我是这么实现的
做一个隐藏的父窗口
然后将显示的窗口作为它的子窗口
[/Quote]
这个应该能够解决,但感觉有更合理的做法。
回复
danxuezx 2010-07-03
[Quote=引用 4 楼 oyljerry 的回复:]
双击就直接创建系统托盘,自己ShowWindow(SW_HIDE) 隐藏界面好了
托盘点击时,获取WM_LBUTTONUP等点击消息,然后ShowWindow(SW_SHOW)显示窗口好了
[/Quote]
您说的这个是在什么时候创建系统托盘呢?


我目前是在OnInitDialog里。但是在这里调用ShowWindow(SW_HIDE)不起作用。
回复
MoXiaoRab 2010-07-03
APP里面不要ShowModal不就好了。
回复
雪影 2010-07-03
[Quote=引用 4 楼 oyljerry 的回复:]
双击就直接创建系统托盘,自己ShowWindow(SW_HIDE) 隐藏界面好了
托盘点击时,获取WM_LBUTTONUP等点击消息,然后ShowWindow(SW_SHOW)显示窗口好了
[/Quote]

up
回复
stonewater 2010-07-03
基本上楼上的综合起来就能解决你的问题了,顶下
回复
oyljerry 2010-07-03
双击就直接创建系统托盘,自己ShowWindow(SW_HIDE) 隐藏界面好了
托盘点击时,获取WM_LBUTTONUP等点击消息,然后ShowWindow(SW_SHOW)显示窗口好了
回复
发动态
发帖子
VC/MFC
创建于2007-09-28

1.5w+

社区成员

VC/MFC相关问题讨论
申请成为版主
社区公告
暂无公告