1. 程式人生 > >MFC對話方塊初始化執行時如何隱藏,托盤圖示,工作列圖示的相關問題

MFC對話方塊初始化執行時如何隱藏,托盤圖示,工作列圖示的相關問題

花了兩三天在搞這些啊,順便看了看MFC對話方塊的機制。

一、托盤圖示

1. 新增托盤訊息定義;在dlg類中新增變數,托盤訊息響應函式的宣告;在dlg類的cpp中手動新增托盤訊息對映

	#define WM_NOTIFYICON WM_USER+5
	NOTIFYICONDATA nd;
	LONG CxxDlg::OnNotifyIcon(WPARAM wParam, LPARAM lParam);
	//}}AFX_MSG_MAP
	ON_MESSAGE(WM_NOTIFYICON, OnNotifyIcon)
END_MESSAGE_MAP()

2. 在dlg類的初始化函式BOOL CxxDlg::OnInitDialog()中,設計NotifyIcon結構並向系統shell新增托盤圖示
	nd.cbSize= sizeof (NOTIFYICONDATA);
	nd.hWnd= m_hWnd;
	nd.uID= IDR_MAINFRAME;
	nd.uFlags= NIF_ICON|NIF_MESSAGE|NIF_TIP;
	nd.uCallbackMessage= WM_NOTIFYICON;
	nd.hIcon= m_hIcon;
	strcpy(nd.szTip, "Init Agent");

	Shell_NotifyIcon(NIM_ADD, &nd);

3. 在ClassWizard中重寫dlg類的OnClose函式,並加入刪除托盤圖示語句

void CxxDlg::OnClose()
{
	Shell_NotifyIcon(NIM_DELETE, &nd); 
	
	CDialog::OnClose();
	DestroyWindow();	//一般要手動呼叫該函式才會使退出生效
}
4. 建立選單及選單響應函式
void CxxDlg::OnTrayShow() 
{
	ShowWindow( SW_SHOWNORMAL);
}
void CxxDlg::OnTrayHide() 
{
	ShowWindow( SW_HIDE);
}
void CxxDlg::OnTrayExit() 
{
	this->OnClose();
}
5.設計托盤訊息響應函式,即訊息響應與popup選單程式設計
LONG CxxDlg::OnNotifyIcon(WPARAM wParam, LPARAM lParam)
{
	// 響應在托盤圖示上的單擊
	//wParam中是響應訊息的圖示ID,lParam中則是Windows的訊息
    switch ( lParam )
    {
	case WM_RBUTTONDOWN:
		{
			// 使用者在托盤圖示上單擊滑鼠右鍵,彈出選單	
			CMenu pMenu;
			if (pMenu.LoadMenu(IDR_TRAY))
			{
				CMenu* pPopup = pMenu.GetSubMenu(0);
				ASSERT(pPopup != NULL);
				CPoint Point;
				if (IsWindowVisible())// 根據對話方塊視窗的狀態對相關選單項使能
				{
					pPopup->EnableMenuItem(ID_TRAY_SHOW,MF_BYCOMMAND | \
					MF_DISABLED | MF_GRAYED);
				}
				else
					pPopup->EnableMenuItem(ID_TRAY_HIDE,MF_BYCOMMAND | 
					MF_DISABLED | MF_GRAYED);
				// 確定滑鼠位置以便在該位置附近顯示選單
				GetCursorPos( &Point );
				SetForegroundWindow();
				pPopup->TrackPopupMenu(TPM_RIGHTALIGN | TPM_RIGHTBUTTON, Point.x, Point.y, this);
			}
		}
		break;
	case WM_LBUTTONDBLCLK:
	case WM_LBUTTONDOWN:
		if (IsWindowVisible())	ShowWindow( SW_HIDE);
		else	ShowWindow( SW_SHOWNORMAL);
		break;
    }
    return 0;
}      
微笑此節完成。

二、工作列按鈕

1.在dlg類的初始化函式OnInitDialog()函式中新增下面這句,使對話方塊不在系統工作列中顯示。

ModifyStyleEx(WS_EX_APPWINDOW, WS_EX_TOOLWINDOW);//改變樣式為從app視窗到工具窗,從而不會在工作列中顯示。
2.在需要顯示對話方塊的函式中新增下句,使對話方塊顯示在系統工作列中。
ModifyStyleEx(WS_EX_TOOLWINDOW, WS_EX_APPWINDOW);


三、初始化執行時即隱藏

假如永遠都不需要顯示,解決方案不少。比較經濟的是直接在dlg類現有的OnPaint()函式中新增ShowWindow(SW_HIDE);。

下文討論前提:視窗完好的存在,只是初始化執行之後不顯示出來,但後來仍可以調動出來。最優的解決方案就是在視窗響應函式中重寫WM_NCPAINT訊息的處理過程,見後文。

如果不嚴格要求,即允許初始化執行時一閃而過的現象,那麼解決方案如下:

0. 改用非模態對話方塊。在app類的InitInstance裡面Create非模態dlg,再ShowWindow(SW_HIDE); 並呼叫訊息迴圈函式

	CxxDlg dlg;
	m_pMainWnd = &dlg;
	dlg.Create( IDD_INITAGENT_DIALOG );
	dlg.ShowWindow(SW_HIDE);
	INT_PTR nResponse = dlg.RunModalLoop();


如果要求最開始根本不出現視窗,有以下幾種處理:

1. 見上帖6#。重寫dlg類的DefWindowProc()函式,對WM_NCPAINT訊息進行改變。

LRESULT CxxDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
	static int i=3;		//此處因為多一次恢復工作列按鈕的操作,故2+1->3;如果使用非模態對話方塊,則少一次ShowWindow,即i<- 2
	// TODO: Add your specialized code here and/or call the base class
	if(message==WM_NCPAINT && i)
	{
		if(i==1)	//這一次需要是使用者呼叫的,用來先恢復視窗在系統工作列的顯示。
			ModifyStyleEx(WS_EX_TOOLWINDOW, WS_EX_APPWINDOW);
		else	//最開始的一或兩次WM_NCPAINT是由系統呼叫的,在此加以阻止。
			ShowWindow(SW_HIDE);
		i--;
		return 0;
	}
	return CDialog::DefWindowProc(message, wParam, lParam);	//無視其作用
}
2.見上帖11#。重寫WM_WINDOWPOSCHANGING訊息,改變某些指示標誌。(未測試。貌似需手工新增訊息對映)
3. 見http://bbs.csdn.net/topics/360201943#post-371035442,13#。在dlg類的OnInitDialog()中新增修改顯示狀態的程式碼並呼叫,此後視窗不再出現,故預計視窗難以恢復(未測試如何恢復視窗)。

相關推薦

MFC對話方塊初始執行如何隱藏托盤圖示工作圖示相關問題

花了兩三天在搞這些啊,順便看了看MFC對話方塊的機制。 一、托盤圖示 1. 新增托盤訊息定義;在dlg類中新增變數,托盤訊息響應函式的宣告;在dlg類的cpp中手動新增托盤訊息對映 #define WM_NOTIFYICON WM_USER+5 NOTIFYICON

MFC開啟資料夾對話方塊初始開啟路徑

使用MFC開發程式時,有時需要選擇資料夾,可使用SHBrowseForFolder解決,但此方法並不支援初始化選擇路徑。 開啟資料夾對話方塊,程式碼如下: BROWSEINFO bi; TCHAR Buffer[MAX_PATH]; bi.hwndOwner = NU

MFC對話方塊初始問題_從一個“斷言”報警說起

1.問題描述 在進行MFC開發時,希望將介面變得美觀。因而調整了一下對話方塊上的字型與顏色。如果僅有一個對話方塊,那麼直接把這些初始化的程式碼放到OnInitDialog()函式中就好。然而,我們

新增RichEdit控制元件導致MFC對話方塊程式無法執行的解決方法

解決辦法: 在應用程式類(App類)中的InitInstance函式體內新增以下語句: AfxInitRichEdit();         對應1.0版本 如果有2.0版本需要新增如下 AfxInitRichEdit2(); 對應2.0 版本 說明: 新增RichEdit控制元件後,在呼叫對話方塊函式Do

swing 自定義最小按鈕後實現點選工作圖示使窗體重新顯示

jf.setUndecorated(true); // 去掉視窗的裝飾 jf.getRootPane().setWindowDecorationStyle(JRootPane.NONE)

MFC模式和非模式對話方塊裡 及關閉最小

void CMFC5Dlg::OnBnClickedButton1() { // TODO: 在此新增控制元件通知處理程式程式碼 CAboutDlg dlg; dlg.DoModal(); } void CMFC5Dlg::OnBnClickedButton2() { // TOD

轉:幾種MFC對話方塊隱藏方法

修改CXXAPP中的InitInstance函式,將原來的模態對話方塊改為非模態對話方塊,及修改 view plaincopy to clipboardprint?INT_PTR nResponse = dlg.DoModal();  INT_PTR nResponse = dlg.DoMo

MFC對話方塊最小托盤程式設計實現步驟

以工程為例說明過程:此程式程式設計環境是VS2008,在除錯過程中,將字符集修改為“使用多位元組字符集”(專案->屬性->配置屬性->字符集)。 例如新建一個MFC對話方塊工程Dialogtest,程式實現的功能是,修改對話方塊標題欄上預設的圖示,在程式中改為新增的資源

MFC對話方塊程式啟動的時候直接隱藏、在工作不顯示圖示

2011-06-19 以前做一個專案,要求程式啟動的時候主對話方塊是隱藏的。當時不知道怎麼做,修改視窗風格、視窗類、OnInitDialog裡ShowWindow、Create函式、WM_CREATE訊息、PreCreateWindow等等都嘗試了,沒什麼用,相當鬱悶。後來有

MFC對話方塊最小托盤

1、在資源中的Icon中匯入一個自己喜歡的圖示,ID命名為IDR_MAINFRAME,將先前的IDR_MAINFRAME的圖示刪除掉; 2、在自己的Dialog標頭檔案中定義一個變數  NOTIFYICONDATA m_nid,關於該結構體的具體資訊可以查閱MSDN; 3、新

VC++MFC對話方塊應用程式實現程式最小到系統托盤

轉自:http://blog.sina.com.cn/s/blog_6b23bc700100pqrm.html  現在使用系統托盤圖示的程式越來越多,尤其是需要長時間執行的程式。這並不是什麼高深的技術,純當做個筆記。  第一步:定義一個 NOTIFYICONDATA 結構

RT-Thread 讀後感5 ——初始執行緒棧

執行緒第一次執行的時候,載入到CPU暫存器的引數就放線上程棧裡面,改函式 rt_hw_stack_init()在cpuport.c中實現。具體代 碼如下: /* 初始化執行緒棧 */ rt_uint8_t *rt_hw_stack_init(void *tentry,

MFC對話方塊裡不能響應按鍵事件的解決辦法 -- 有感

我在做一對話方塊上有按鍵,我將按鍵 按鍵顯示時(visible = true) ,不能響應OnKeyDown函式,所以我參考了 https://blog.csdn.net/fancw/article/details/10007081 怎麼改的: BOOL ADlg::PreTrans

微信開發者工具初始專案進去報錯:小程式重啟耗時過久請確認業務邏輯中是否有複雜運算或者死迴圈

              如圖上,為錯誤原因。   之前用開發者工具用的好好地,前些日子又版本更新,升級了一下,然後開啟專案就出現上面的問題。當時以為電腦出啥問題了,也沒當回事。今天再次開啟開發者工具,發現還是出現上面的問題。一臉懵,新建專案,啥都沒做竟然出問題。網上一查同樣的問題一大堆。

MFC原理第三講.RTTI執行型別識別

一丶什麼是RTTI     RTTI. 執行時的時候型別的識別. 執行時型別資訊程式.能夠使用基類(父類)指標 或者引用 來檢查這些指標或者引用所指的物件. 實際派生的型別   簡單來說就是 使用父類指標檢查這個物件是屬於哪個類. 1.本篇部落格需要弄清的問題   1

MFC對話方塊程式設計雜談

區分BITMAP、CBitmap和HBITMAP ①BITMAP   BITMAP是一個結構體,封裝著bitmap的一些資訊。定義了邏輯點陣圖的寬高、顏色格式和位值。 ②CBitmap   CBitmap是MFC中封裝bitmap的類,包含著被點陣圖的

CEF方面的研究(四) CEF嵌入MFC對話方塊關閉崩潰問題解決辦法

RT、相信有不少朋友在開發過程中都遇到了,關閉崩潰或者關閉後開啟電腦工作管理員,還有程序存在的問題。 這個問題把我也是快折騰瘋了,畢竟存在這類崩潰或者資源解除安裝不掉的問題是不能用入專案中的,蛋疼的困擾了我半個多月的時間,當我把後面的東西全部做完時,又不得不拐過頭來解決他,

初始執行緒池引發的NoClassDefFoundError 異常分析

今天說的異常是一個很不常見的異常,至少我不經常見到這個異常。首先先看下NoClassDefFoundError官方定義 :Java Virtual Machine is not able to find a particular class at runtime which was available at

MFC對話方塊新增選單欄

1. 開發環境是VS2013 2. 新增具體步驟     ①建立一個基於對話方塊的MFC專案;     ②在資源檢視中,在專案名稱上右鍵 --->新增---->資源,出現以下對話方塊,選中“menu”,點選新建,系統會自動生成men

Greenplum初始資料庫出現gpadmin-[ERROR]:-gpstart error: Do not have enough valid segments to start the arr

啟動初始化greenplum資料庫報錯資訊如下所示 [[email protected] gpAdminLogs]$ gpstart 20181018:01:09:27:043309 gpstart:mdw:gpadmin-[INFO]:-Starting gps