精通 VC++ 實效編程280例 - 02 菜單和光標

菜單和關閉時重要的 Windows 資源之一。SDK 中,用 HCURSOR 和 HMENU 分別表示菜單和光標的句柄。MFC 中,CMenu 類封裝了菜單的功能。

23 動態添加和刪除菜單項

添加菜單項可以調用 CMenu::AppendMenu 或 CMenu::InserMenu 函數,刪除菜單項可以調用 CMenu::RemoveMenu 或 CMenu::DeleteMenu 函數,最后調用 CWnd::DrawMenuBar 函數重畫菜單。

  • CMenu::AppendMenu:在菜單末端添加菜單項。
  • CMenu::InserMenu:在菜單指定位置添加菜單項。
  • CMenu::RemoveMenu:移動菜單項,如果菜單項與彈出菜單相關聯,將不將銷毀彈出菜單的句柄,因此菜單可重用。
  • CMenu::DeleteMenu:刪除菜單項,如果菜單項與彈出菜單相關聯,將銷毀彈出菜單的句柄,并釋放其占用的內存。
#define ID_TEST_MENU                    10000
void CMainFrame::OnAppendMenu() 
{//獲得主菜單CMenu* pMenu = GetMenu();//獲得子菜單CMenu* pSubMenu = pMenu->GetSubMenu(4);if (pSubMenu->GetMenuItemCount() == 4){//在菜單末端添加菜單項pSubMenu->AppendMenu(MF_STRING,ID_TEST_MENU,_T("New Menu"));//重畫菜單DrawMenuBar();}
}void CMainFrame::OnInsertMenu() 
{//獲得主菜單CMenu* pMenu = GetMenu();//獲得子菜單CMenu* pSubMenu = pMenu->GetSubMenu(4);if (pSubMenu->GetMenuItemCount() == 4){//在菜單指定位置添加菜單項pSubMenu->InsertMenu(4,MF_BYPOSITION,ID_TEST_MENU,_T("New Menu"));//重畫菜單DrawMenuBar();}	
}void CMainFrame::OnRemoveMenu() 
{//獲得主菜單CMenu* pMenu = GetMenu();//獲得子菜單CMenu* pSubMenu = pMenu->GetSubMenu(4);if (pSubMenu->GetMenuItemCount() == 5){//刪除菜單項pSubMenu->RemoveMenu(4,MF_BYPOSITION);//重畫菜單DrawMenuBar();}
}void CMainFrame::OnDeleteMenu() 
{//獲得主菜單CMenu* pMenu = GetMenu();//獲得子菜單CMenu* pSubMenu = pMenu->GetSubMenu(4);if (pSubMenu->GetMenuItemCount() == 5){//刪除菜單項pSubMenu->DeleteMenu(4,MF_BYPOSITION);//重畫菜單DrawMenuBar();}
}
void CMainFrame::OnTestMenu() 
{AfxMessageBox(_T("測試菜單項命令"));	
}

24 在系統菜單中添加和刪除菜單項

在系統菜單中添加和刪除菜單項,首先調用 CWnd::GetSystemMenu 函數獲得系統菜單的指針,然后調用 CMenu::AppendMenu 或 CMenu::InsertMenu,CMenu::RemoveMenu 或 CMenu::DeleteMenu 函數添加和刪除菜單項,最后調用 CWnd::DrawMenuBar 函數重畫菜單。對于添加的菜單項,可以在 CWnd::OnSysCommand 重載函數中處理菜單命令。

//在resource.h文件中添加宏定義
#define ID_TEST_MENU					10000
BOOL CDemoDlg::OnInitDialog()
{CDialog::OnInitDialog();//...//獲得系統菜單CMenu* pMenu = GetSystemMenu(FALSE);//刪除系統菜單項pMenu->RemoveMenu(SC_MOVE,MF_STRING);//添加菜單項pMenu->InsertMenu(0,MF_BYPOSITION,ID_TEST_MENU,_T("New Menu"));//重畫菜單DrawMenuBar();return TRUE; 
}
void CDemoDlg::OnSysCommand(UINT nID, LPARAM lParam)
{if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else if(nID == ID_TEST_MENU){AfxMessageBox(_T("測試菜單項命令"));}else{CDialog::OnSysCommand(nID, lParam);}
}

25 禁用關閉按鈕

禁用關閉按鈕可以調用 CMenu::EnableMenuItem 函數。

BOOL CDemoDlg::OnInitDialog()
{CDialog::OnInitDialog();//...//獲得系統菜單CMenu* pMenu = GetSystemMenu(FALSE);//禁用關閉按鈕pMenu->EnableMenuItem(SC_CLOSE,MF_BYCOMMAND | MF_GRAYED);return TRUE;
}

26 啟用和禁用菜單項

可以在類的 UPDATE_COMMAND_UI 消息處理函數中調用 CCmdUI::Enable 函數,啟用和禁用菜單項。

//在CMainFrame類中添加成員變量
public:BOOL m_bEnable1;BOOL m_bEnable2;
//在CMainFrame類的構造函數中初始化成員變量
CMainFrame::CMainFrame()
{m_bEnable1 = TRUE;m_bEnable2 = FALSE;
}
//在CMainFrame類中為菜單項添加命令處理函數void CMainFrame::OnTestMenu1() 
{m_bEnable1 = FALSE;m_bEnable2 = TRUE;	
}void CMainFrame::OnUpdateTestMenu1(CCmdUI* pCmdUI) 
{//啟動或禁用菜單1pCmdUI->Enable(m_bEnable1);
}void CMainFrame::OnTestMenu2() 
{m_bEnable1 = TRUE;m_bEnable2 = FALSE;
}void CMainFrame::OnUpdateTestMenu2(CCmdUI* pCmdUI) 
{//啟動或禁用菜單2pCmdUI->Enable(m_bEnable2);
}

27 設置菜單項的檢查狀態

可以在類的 UPDATE_COMMAND_UI 消息處理函數中調用 CCmdUI::SetCheck 函數設置菜單項的檢查狀態(選中/不選中狀態)。

//在CMainFrame類中添加成員變量
public:int m_nCheck;
//在CMainFrame類的構造函數中初始化成員變量
CMainFrame::CMainFrame()
{m_nCheck = 0;
}
//在CMainFrame類中為菜單項添加命令處理函數
void CMainFrame::OnTestMenu() 
{if (m_nCheck == 0){m_nCheck = 1;}else{m_nCheck = 0;}}void CMainFrame::OnUpdateTestMenu(CCmdUI* pCmdUI) 
{//設置菜單項檢查狀態pCmdUI->SetCheck(m_nCheck);
}

28 快捷菜單

實現快捷菜單可以在 CWnd::OnContextMenu 重載函數中調用 CMenu::TrackPopupMenu 函數。

在資源中添加1個菜單資源,ID 為 IDR_MENU。在菜單資源中添加1個子菜單,并添加菜單項。

//在CDemoView類中重載CWnd::OnContextMenu函數
void CDemoView::OnContextMenu(CWnd* pWnd, CPoint point) 
{CMenu menu;//加載菜單if (!menu.LoadMenu(IDR_MENU)){return;}//獲得子菜單CMenu* pPopupMenu = menu.GetSubMenu(0);//彈出菜單pPopupMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,point.x,point.y,pWnd);
}
void CDemoView::OnTestMenu1() 
{AfxMessageBox(_T("快捷菜單項1命令"));
}void CDemoView::OnTestMenu2() 
{AfxMessageBox(_T("快捷菜單項2命令"));
}

29 獲取光標的坐標

可以在 WM_MOUSEMOVE 消息處理函數中獲得光標的位置。

//在CDemoView類中添加成員變量
public:CPoint m_Point;
//在類中添加WM_MOUSEMOVE消息處理函數
void CDemoView::OnMouseMove(UINT nFlags, CPoint point) 
{//保存光標坐標m_Point = point;//刷新客戶區Invalidate();CView::OnMouseMove(nFlags, point);
}
//在類中重載CView::OnDraw函數
void CDemoView::OnDraw(CDC* pDC)
{//獲得客戶區坐標CRect rect;GetClientRect(rect);//繪制十字光標pDC->MoveTo(0,m_Point.y);pDC->LineTo(rect.Width(),m_Point.y);pDC->MoveTo(m_Point.x,0);pDC->LineTo(m_Point.x,rect.Height());//輸出光標坐標CString strText = _T("");strText.Format(_T("%d,%d"),m_Point.x,m_Point.y);pDC->SetBkMode(TRANSPARENT);pDC->SetTextAlign(TA_RIGHT | TA_BOTTOM);pDC->TextOut(m_Point.x,m_Point.y,strText);
}

30 限制光標的移動范圍

限制光標的范圍可以調用 SDK 的 ClipCursor 函數。

//在CDemoView類中重載CView::OnDraw函數
void CDemoView::OnDraw(CDC* pDC)
{//獲得客戶區坐標CRect rect;GetClientRect(rect);rect.left = rect.left + rect.Width() / 4;rect.right = rect.right - rect.Width() / 4;rect.top = rect.top + rect.Height() / 4;rect.bottom = rect.bottom -rect.Height() / 4;//繪制光標移動范圍pDC->Rectangle(rect);
}
//在CDemoView類中分別添加WM_LBUTTONDOWN和WM_LBUTTONUP消息處理函數
void CDemoView::OnLButtonDown(UINT nFlags, CPoint point) 
{//獲得客戶區坐標CRect rect;GetClientRect(rect);rect.left = rect.left + rect.Width() / 4;rect.right = rect.right - rect.Width() / 4;rect.top = rect.top + rect.Height() / 4;rect.bottom = rect.bottom - rect.Height() /4;//映射屏幕坐標ClientToScreen(rect);//限制光標移動范圍ClipCursor(&rect);CView::OnLButtonDown(nFlags, point);
}void CDemoView::OnLButtonUp(UINT nFlags, CPoint point) 
{//光標自由移動ClipCursor(NULL);CView::OnLButtonUp(nFlags, point);
}

31 自定義光標

使用自定義光標,首先調用 CWinApp::LoadCursor函數加載光標,然后調用SDK的SetCursor函數設置光標。

//創建1個單文檔的應用程序,并添加2個光標資源,在CDemoView類中添加成員變量
public:HCURSOR m_hCursor;
//在CDemoView類中重載CView::OnInitialUpdate函數
void CDemo2View::OnInitialUpdate() 
{CView::OnInitialUpdate();//加載光標m_hCursor = AfxGetApp()->LoadCursor(IDC_CURSOR1);
}
//在CDemoView類中添加WM_SETCURSOR消息處理函數
BOOL CDemo2View::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{//設置光標::SetCursor(m_hCursor);return TRUE;
}
//在CDemoView類中分別添加WM_LBUTTONDOWN和WM_LBUTTONUP消息處理函數
void CDemo2View::OnLButtonDown(UINT nFlags, CPoint point) 
{//加載光標m_hCursor = AfxGetApp()->LoadCursor(IDC_CURSOR2);//設置光標::SetCursor(m_hCursor);CView::OnLButtonDown(nFlags, point);
}void CDemo2View::OnLButtonUp(UINT nFlags, CPoint point) 
{//加載光標m_hCursor = AfxGetApp()->LoadCursor(IDC_CURSOR1);//設置光標::SetCursor(m_hCursor);CView::OnLButtonUp(nFlags, point);
}

32 等待光標

啟動等待光標可以調用 CCmdTarget::BeginWaitCursor函數,結束等待光標可以調用CCmdTarget::EndWaitCursor函數。

void CDemo2View::OnLButtonUp(UINT nFlags, CPoint point) 
{//啟動等待光標BeginWaitCursor();//休眠Sleep(5000);//結束等待光標EndWaitCursor();CView::OnLButtonDown(nFlags,point);
}

  

?

轉載于:https://www.cnblogs.com/iwanc/archive/2013/06/09/2987866.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/376610.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/376610.shtml
英文地址,請注明出處:http://en.pswp.cn/news/376610.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

POJ 1860: Currency Exchange 【SPFA】

套匯問題,從源點做SPFA,如果有一個點入隊次數大于v次(v表示點的個數)則圖中存在負權回路,能夠套匯,如果不存在負權回路,則判斷下源點到自身的最長路是否大于自身,使用SPFA時松弛操作…

python腳本:判斷字符是否為中文

# 判斷字符是否為中文 def is_chinese(ch):if u\u4e00 < ch < u\u9fff:return Trueelse:return False

Android 廣播 Broadcast學習

Android Broadcast 廣播 進程內本地廣播 如果你是在你的應用之內使用廣播&#xff0c;即不需要跨進程&#xff0c;考慮使用LocalBroadcastManager &#xff0c;這樣更有效率&#xff08;因為不需要跨進程通信&#xff09;&#xff0c;并且你不用考慮一些其他應用可以發送或接收…

python:將時間戳轉換成格式化日期

import time # 將時間戳轉換成格式化日期 def timestamp_to_str(timestampNone, format%Y-%m-%d %H:%M:%S):if timestamp:time_tuple time.localtime(timestamp) # 把時間戳轉換成時間元祖result time.strftime(format, time_tuple) # 把時間元祖轉換成格式化好的時間retur…

WebApp 里Meta標簽大全

1.先說說mate標簽里的viewport&#xff1a; viewport即可視區域&#xff0c;對于桌面瀏覽器而言&#xff0c;viewport指的就是除去所有工具欄、狀態欄、滾動條等等之后用于看網頁的區域。對于傳統WEB頁面來說&#xff0c;980的寬度在iphone上顯示是很正常的&#xff0c;也是滿屏…

python:封裝CRUD操作

# 封裝數據庫操作 def SELECT(db, cursor, sql):try:# 執行SQL語句db.ping(reconnectTrue)cursor.execute(sql)# 獲取所有記錄列表results cursor.fetchall()logging.debug("select commit")except:logging.error(sql)logging.error("select 語句執行出錯"…

我的osu游戲程序設計(oo)

osu是一款社區元素為主旨的音樂游戲,由澳大利亞人Dean Herbert (peppy)獨立制作并運行. 游戲的方法簡單,就是 1. 圈圈(Circle)&#xff1a;圈圈(Circle) 50。沒打中顯示X,并減少生命值。圈中序號的最后一個的300、100會顯示為激300、喝100。2.滑條(Slider) : 在開始端點擊按住不…

影像數據庫調研

參考Paul Graham比較各種編程語言的方法&#xff0c;我們比較各種數據庫的特點如下&#xff1a; Oracle: 我們需要企業級數據庫。 MySQL: Oracle不開源。 PostgreSQL: MySQL的功能不夠多。 SQLite: 你可以把我嵌入到任何地方。這樣&#xff0c;4種數據庫夠大家用了。 MongoDB: …

linux進程間通信快速入門【三】:信號量(XSI、POSIX以及PV原語)

文章目錄XSIsemgetsemop、semtimedopsemctl基于共享內存demo修改XSI信號量的限制PV原語PV控制并發進程數POSIX信號量使用posix命名信號量使用posix匿名信號量參考在前兩篇文章中我們使用的racingdemo都沒有對臨界區代碼進行加鎖&#xff0c;這里我們介紹以下信號量的使用。Linu…

QTableWidget的使用詳細介紹和美工總結(轉)

基本外觀設置 FriendTable->setFrameShape(QFrame::NoFrame); //設置邊框 FriendTable->setHorizontalHeaderLabels(HeadList); 設置表頭 FriendTable->setSelectionMode(QAbstractItemView::SingleSelection); 設置選擇的模式為單選擇 FriendTable->setSelect…

Android programming on Mac 之安裝Eclipse

1.安裝包在此鏈接下載&#xff1a; http://developer.android.com/sdk/index.html google GoAgent翻墻不好用&#xff0c;更新了host文件也不行&#xff0c;整了半天&#xff0c;還是一怒之下續簽了vpn賬號。早知如此&#xff0c;何必折騰。~~~~(>_<)~~~~ 更新文件時…

c++關于虛表的一些筆記

文章目錄1、虛函數表指針2、多態構成的條件3、重載、重寫、重定義 三者區別4、繼承與虛函數5、單繼承中的虛函數表無虛函數覆蓋有虛函數覆蓋6、單繼承中的虛函數表無虛函數覆蓋有虛函數覆蓋參考看《深度探索c對象模型》的時候對虛表有了點疑惑&#xff0c;正好網上有些文章解除…

4、在Shell程序中的使用變量

學習目標變量的賦值變量的訪問變量的輸入 12-4-1 變量的賦值在Shell編程中&#xff0c;所有的變量名都由字符串組成&#xff0c;并且不需要對變量進行聲明。要賦值給一個變量&#xff0c;其格式如下&#xff1a;變量名值。注意&#xff1a;等號()前后沒有空格例如&#xff1a; …

C語言技巧:把單一元素的數組放在末尾,struct可以擁有可變大小的數組

《C 對象模型》第19頁有這樣一句話 C程序員的巧計有時候卻成為c程序員的陷阱。例如把單一元素的數組放在一個struct的末尾&#xff0c;于是每個struct objects可以擁有可變數組的數組&#xff1a; struct mumble {/* stuff */char pc[1]; };//從文件或標準輸入裝置中取得一個…

探討C++ 變量生命周期、棧分配方式、類內存布局、Debug和Release程序的區別(二)...

看此文&#xff0c;務必需要先了解本文討論的背景&#xff0c;不多說&#xff0c;給出鏈接&#xff1a; 探討C 變量生命周期、棧分配方式、類內存布局、Debug和Release程序的區別&#xff08;一&#xff09; 本文會以此問題作為討論的實例&#xff0c;來具體討論以下四個問題&a…

后臺系統可擴展性學習筆記(一)概要

文章目錄系統大致架構可擴展性負載均衡器與會話保持引入冗余增強系統可用性緩存減輕數據庫壓力異步處理參考系統大致架構 當一個用戶請求從客戶端出發&#xff0c;經過網絡傳輸&#xff0c;達到 Web 服務層&#xff0c;接著進入應用層&#xff0c;最后抵達數據層&#xff0c;它…

poj 3728(LCA + dp)

題目鏈接&#xff1a;http://poj.org/problem?id3728 思路&#xff1a;題目的意思是求樹上a -> b的路徑上的最大收益&#xff08;在最小值買入&#xff0c;在最大值賣出&#xff09;。 我們假設路徑a - > b 之間的LCA(a, b) f, 并且另up[a]表示a - > f之間的最大收益…

成功之路

1、每天都要有進步&#xff0c;都要有新知識的收獲。 2、工作認真負責&#xff0c;高效的完成&#xff0c;多總結。 3、自己多練習一些感興趣的東西&#xff0c;實踐&#xff01;&#xff01;&#xff01; 4、寫博客。 5、百度、騰訊、阿里是目標&#xff0c;差距還很大&#x…

后臺系統可擴展性學習筆記(二)權衡取舍

文章目錄性能與可擴展性延遲與吞吐量可用性與一致性一致性模式可用性模式可用性衡量參考系統設計中也面臨許多權衡取舍&#xff1a;性能與可擴展性延遲與吞吐量可用性與一致性 性能與可擴展性 可擴展&#xff0c;意味著服務能以加資源的方式成比例地提升性能&#xff0c;性能…

iOS中使用子線程的完整方法

第一步&#xff1a;開啟子線程 //開啟子線程到網絡上獲取數據myFirstThread [[NSThread alloc]initWithTarget:self selector:selector(thread1GetData) object:nil];[myFirstThread setName:"第一個子線程,用于獲取網絡數據"];[myFirstThread start]; 第二步&…