Posted on 2006-12-13 16:18
奔跑的阿甘 阅读(805)
评论(0) 编辑 收藏 引用 所属分类:
SDK/MFC
如何实现模式对话框程序启动时的系统栏显示
Michael Wednesday, December 13, 2006
在实际工作中,需要用到一些类似状态监控的程序,它们往往在一启动时就要最小化到系统栏上.
这里涉及到两个问题:1)如何在启动时隐藏主窗口; 2)用托盘实现系统栏显示.
模式对话框和非模式对话框的区别在于是否自身拥有一个消息循环,对于模式对话框程序,要实现程序启动时的隐藏,一个比较完美(无闪烁地隐藏)的做法如下
1
BOOL CMyApp::InitInstance()
2

{
3
// 
4
5
CMyDlg* pDlg = new CMyDlg;
6
if (pDlg->Create(IDD_MY_DIALOG))
{
7
m_pMainWnd = pDlg;
8
Run();
9
if (pDlg)
{
10
delete pDlg;
11
pDlg = NULL;
12
}
13
}
14
return FALSE;
15
}
这里使用CWnd::Create()函数来创建一非模式对话框,同时添加了消息循环的处理Run(). 因为pDlg(属性为非visible)并没有调用ShowWindow(),所以创建后为隐藏状态.
关于托盘的显示只要调用WINDOWS的SHELL API即可.
以下代码用于添加一托盘:
1
NOTIFYICONDATA nc;
2
nc.cbSize=sizeof(NOTIFYICONDATA);
3
nc.hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);
4
nc.hWnd=m_hWnd;
5
lstrcpy(nc.szTip,"Hi!");
6
nc.uCallbackMessage=WM_NC;
7
nc.uFlags=NIF_ICON | NIF_MESSAGE | NIF_TIP;
8
nc.uID=IDC_NC;
9
Shell_NotifyIcon(NIM_ADD,&nc); 以下代码用于删除一托盘:
1
NOTIFYICONDATA nc;
2
nc.cbSize=sizeof(NOTIFYICONDATA);
3
nc.hWnd=m_hWnd;
4
nc.uCallbackMessage=WM_NC;
5
nc.uFlags=NIF_ICON | NIF_MESSAGE | NIF_TIP;
6
nc.uID=IDC_NC;
7
Shell_NotifyIcon(NIM_DELETE,&nc); 托盘图标的消息定义及响应函数如下:
//定义消息码
#define WM_NC 1001
#define IDC_NC 1002
//定义消息映射
ON_MESSAGE(WM_NC,OnNc)
//定义消息处理函数声明
afx_msg void OnNc(WPARAM wParam,LPARAM IParam);
//定义消息处理函数实现
1
void CMyDlg::OnNc(WPARAM wParam,LPARAM IParam)
2

{
3
if ((IParam == WM_LBUTTONDOWN) || (IParam == WM_RBUTTONDOWN))
4
{
5
CMenu menu;
6
menu.LoadMenu(IDR_MENU1);
7
CMenu* pPopup=menu.GetSubMenu(0);
8
::SetMenuDefaultItem(pPopup->m_hMenu,0,TRUE);
9
CPoint Point;
10
GetCursorPos(&Point);
11
pPopup->TrackPopupMenu(TPM_LEFTALIGN,Point.x,Point.y,AfxGetMainWnd(),NULL);
12
}
13
} 最后很关键的是,因为我们采用了非模式框来隐藏窗口,当对话框退出后,我们需要调用PostQuitMessage()来发送WM_QUIT消息给应用程序从而结束消息循环退出整个程序.
[全文完]