亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C > 正文

ON_COMMAND_RANGE多個按鈕響應一個函數的解決方法

2020-01-26 15:28:26
字體:
來源:轉載
供稿:網友

本文描述了ON_COMMAND_RANGE多個按鈕響應一個函數的解決方法。

開發人員需要注意在自定義消息響應函數的聲明過程中,一定要注意參數的形式,稍微一疏忽就會導致莫須有的錯誤,具體以ON_COMMAND_RANGE為例說下。

1.聲明消息響應函數:在要添加的工程上添加函數afx_msg void OnButtonPort();

2.消息映射:

BEGIN_MESSAGE_MAP(CXXXDlg, CDialog)//{{AFX_MSG_MAP(CXXXDlg)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_TIMER()//}}AFX_MSG_MAP//這里的IDC_BUTTON_PORT_1和 IDC_BUTTON_START_ALL之間有很多個Button,并且ID連續ON_COMMAND_RANGE(IDC_BUTTON_PORT_1, IDC_BUTTON_START_ALL, OnButtonPort)ON_WM_DEVICECHANGE()END_MESSAGE_MAP()

3.映射函數的實現:實現你自己的響應函數 void CXXXDlg::OnButtonPort()

注:此代碼DEBUG OK,Relase異常,不可直接參考,且聽下面分解:

DEBUG通過,不料Release卻直接崩潰,寫了這么多年的CODE還真第一次遇到這種情況,為什么ON_COMMAND_RANGE Debug正常,Release不正常呢?

先MSDN:

Use this macro to map a contiguous range of command IDs to a single message handler function.ON_COMMAND_RANGE(id1, id2, memberFxn )Parametersid1Command ID at the beginning of a contiguous range of command IDs.id2Command ID at the end of a contiguous range of command IDs.memberFxnThe name of the message-handler function to which the commands are mapped.RemarksThe range of IDs starts with id1 and ends with id2.Use ON_COMMAND_RANGE to map a range of command IDs to one member function. Use ON_COMMAND to map a single command to a member function. Only one message-map entry can match a given command ID. That is, you can't map a command to more than one handler. For more information on mapping message ranges, see Handlers for Message-Map Ranges.There is no automatic support for message map ranges, so you must place the macro yourself.

MSDN也沒有特別說明要注意什么的,我覺得我用的也很正常,于是在網上又搜了一大會,有一個網友非常專業的解釋的原因,具體網址是:http://yiyunscu.blog.163.com/blog/static/3626332020099802057982/

以下是轉載內容:

該網友定義如下:

afx_msg void OnCommandMy(WPARAM wParam, LPARAM lParam );

申明只適用于ON_COMMAND消息的函數申明, 而ON_COMMAND_RANGE的函數申明在MSDN中建議寫成這樣:
OnCommandMy(UINT nID);
通過switch(nID) case **:進行針對不同菜單進行消息響應.
nID就是菜單傳入消息的ID號, 奇怪的是, 在Debug版本下, 先前的申明方式運行完全正常, 查閱了MSDN, 找出了可能的原因:

 Handler functions for single commands normally take no parameters. With the exception of update handler functions, handler functions for message-map ranges require an extra parameter, nID, of type UINT. This parameter is the first parameter. The extra parameter accommodates the extra command ID needed to specify which command the user actually chose.

針對單個Command消息響應函數可以不帶參數, 但是對于多個Command消息如ON_COMMAND_RANGE申明的消息響應需要將函數參數列表中的第一個參數定義為UINT nID, 指明command 的ID號, 按照MSDN的理解, ON_COMMAND_RANGE也可以像ON_COMMAND那樣在消息響應函數中定義兩個參數, 如afx_msg void OnCommandMy(WPARAM wParam, LPARAM lParam );在Debug和Release下, 編譯不會出現問題, 在Debug下運行也不會出現問題, 但是在Release下面卻出現內存錯誤, 所以可以帶多個參數感覺只能在Debug下可以行的能, 在Release下就沒失效了.
查閱相關的資料并利用VC查看相應的匯編代碼發現, 應該是函數調用和返回時棧操作不平衡導致Release版本下出現了內存錯誤的問題, ON_COMMAND_RANGE在MFC默認的消息響應函數中, 參數只有一個, 如:

#define ON_COMMAND_RANGE(id, idLast, memberFxn) / { WM_COMMAND, CN_COMMAND, (WORD)id, (WORD)idLast, AfxSig_vw, / (AFX_PMSG)(void (AFX_MSG_CALL CCmdTarget::*)(UINT))&memberFxn }, // ON_COMMAND_RANGE(id, idLast, OnFoo) is the same as //  ON_CONTROL_RANGE(0, id, idLast, OnFoo)

函數調用過程中, 會將傳入的參數進行壓棧操作, 因為MFC默認的傳入參數只有一個, 因此調用OnCommandMy時會有系統傳入的一個消息參數進行壓棧操作. 在函數返回時, 應該進行出棧操作, 并且保證調用完成后棧維持平衡, 否則會出現可能的內存錯誤.在DEBUG上沒有出現內存錯誤在于在調用OnCommandMy函數返回時編譯器在返回代碼處添加了如下的匯編代碼:

pop edipop esipop ebxadd esp, 48hcmp ebp, espcall __chkesp (0041e680)mov esp, ebppop ebpret 8(兩個參數出棧)

此匯編代碼的作用就是在函數返回時檢查調用中和調用返回時的棧是否一致, 如果不一致, 就強制平棧操作, 因為在這個調用過程中, 傳入OnCommandMy的消息參數只有一個(只是申明成兩個, 實際只有一個參數傳入), 所以存在棧不一致的情況, 但是強制平棧可以避免由此引起的錯誤.
在Release版本下, 就沒有了檢測棧的操作,
只是簡單的下面幾句匯編代碼完成出棧操作:

mov esp, ebppop ebpret 8兩個參數出棧)

可以明顯看到, Release下出現了棧操作不平衡的情況, 即入棧數小于出棧數, 從而導致棧區地址錯誤, 當其它函數兩次對棧區進行地址訪問時就極有可能出現內存錯誤的現象了.
所以, 平時寫程序時在Debug下高度完成之后, 最好還在Release下看一下, 因為有些時候, Debug下對函數參數的檢查不是那么嚴格, 并且在棧的操作上, Debug可以幫助我們解決很多隱藏的問題, 但是Release下就不會了. 另外在自定義的消息響應函數中, Debug和Release都不會對響應函數的參數列表與MFC默認參數列表進行一致性檢測, 從而可能隱藏重大的內存出錯的可能性, 導致最終軟件在Release下運行可能發生崩潰.

終于明白了,原來是ON_COMMAND_RANGE只能帶一個參數,帶兩個或不帶都會異常所以重新定義:

afx_msg void OnButtonPort(UINT nID);

而且此nID就是你點擊的按鈕ID值,再也不用之前的麻煩代碼了

CWnd *pWnd = GetFocus();int nPortID = pWnd->GetDlgCtrlID() ;

問題解決!

附加:

1、ON_COMMAND(ID_VIEW_CUSTOMIZE, OnViewCustomize)==>void CMainFrame::OnViewCustomize();或void CMainFrame::OnViewCustomize(WPARAM wParam, LPARAM lParam);

2、ON_REGISTERED_MESSAGE(AFX_WM_RESETTOOLBAR, OnToolbarReset)==>afx_msg LRESULT CMainFrame::OnToolbarReset(WPARAM /*wp*/,LPARAM);

3、ON_COMMAND_RANGE(ID_SHORTCUT_1, ID_SHORTCUT_5, OnOutlookBarShortcut)==>void CMainFrame::OnOutlookBarShortcut(UINT id);

4、ON_UPDATE_COMMAND_UI(ID_VIEW_CAPTIONBAR, OnUpdateViewCaptionBar)==>void CMainFrame::OnUpdateViewCaptionBar(CCmdUI* pCmdUI);

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
大荫蒂欧美视频另类xxxx| 正在播放欧美一区| 日本久久久久久久久久久| 一区二区三区www| 国产精品99久久99久久久二8| 黑人巨大精品欧美一区二区免费| 92国产精品久久久久首页| 久久天堂电影网| 国产亚洲精品综合一区91| 国产精品直播网红| 亚洲人av在线影院| 欧亚精品中文字幕| 欧美午夜丰满在线18影院| 成人激情视频免费在线| 视频在线观看一区二区| 国产精品网站入口| 亚洲欧洲国产一区| 一夜七次郎国产精品亚洲| 性视频1819p久久| 日韩在线精品视频| 中文字幕一区日韩电影| 91在线免费看网站| 欧美成人午夜免费视在线看片| 欧美福利视频网站| 久久久久99精品久久久久| 亚洲91精品在线观看| 欧美俄罗斯性视频| 亚洲国产精品嫩草影院久久| 日产日韩在线亚洲欧美| 日韩高清av一区二区三区| 日韩va亚洲va欧洲va国产| 不卡av在线网站| 欧美性受xxx| 欧美激情xxxx性bbbb| 国产精品亚洲自拍| 8x拔播拔播x8国产精品| 91九色国产社区在线观看| 亚洲欧美激情视频| 欧美日韩国产综合新一区| 国内精品美女av在线播放| 国产一区二区丝袜高跟鞋图片| 亚洲国产精品成人av| 亚洲最新av网址| 久久夜色精品国产欧美乱| 亚洲第一免费播放区| 国产精品人成电影在线观看| 国产精品久在线观看| 日韩av色在线| 久久夜色精品国产欧美乱| 亚洲精品videossex少妇| 日本亚洲欧美成人| 国产精品美女www爽爽爽视频| 日韩av一区在线观看| 欧美理论电影在线播放| 日韩欧美亚洲成人| 久久激情视频久久| 欧美尺度大的性做爰视频| 日韩成人黄色av| 亚洲色图第三页| 亚洲自拍欧美另类| 海角国产乱辈乱精品视频| 在线电影中文日韩| 欧美日韩xxx| 精品福利免费观看| 国产精品久久久久久中文字| 在线看福利67194| 国产精品v日韩精品| 免费不卡欧美自拍视频| 国产香蕉97碰碰久久人人| 亚洲香蕉伊综合在人在线视看| 在线观看不卡av| 欧美激情a∨在线视频播放| 尤物九九久久国产精品的特点| 亚洲v日韩v综合v精品v| 国产日韩精品入口| 久久久综合av| 欧美剧在线观看| 日本亚洲欧洲色α| 视频直播国产精品| 国产在线观看一区二区三区| 日韩风俗一区 二区| 91丝袜美腿美女视频网站| 国产一区二区激情| 国产精品video| 欧美电影《睫毛膏》| 国产精品久久久久久久久久新婚| 成人av.网址在线网站| 亚洲综合最新在线| 欧美孕妇毛茸茸xxxx| 美日韩在线视频| 久久免费精品视频| 成人h视频在线| 免费99精品国产自在在线| 欧美中文在线免费| 91网在线免费观看| 9.1国产丝袜在线观看| 日韩成人在线网站| 国产精品美女免费| 97精品伊人久久久大香线蕉| 91精品视频网站| 国产视频999| 欧美国产日韩一区二区三区| 国产亚洲日本欧美韩国| 欧美日韩国产一区二区| 亚洲精品456在线播放狼人| 91久久精品一区| 日韩av最新在线| 亚洲成人动漫在线播放| 久久99久久99精品免观看粉嫩| 性色av一区二区咪爱| 中文字幕av一区二区| 国产日韩欧美电影在线观看| 亚洲午夜色婷婷在线| 日韩欧美一区二区三区久久| 亚洲最大的成人网| 国产精品欧美一区二区三区奶水| 九九热这里只有精品6| 91香蕉嫩草影院入口| 国产日韩中文字幕| 欧美视频中文字幕在线| 亚洲情综合五月天| 日韩精品高清在线观看| 日韩视频免费看| 精品动漫一区二区| 伊人久久久久久久久久久久久| 国产精品久久久久久久久久久久久| 亚洲精品国产拍免费91在线| 成人网欧美在线视频| 久久国内精品一国内精品| 久久精品视频在线| 欧美激情三级免费| 国产极品精品在线观看| 91av视频在线播放| 91po在线观看91精品国产性色| 欧美日韩中文字幕综合视频| 久久久久久久久中文字幕| 日韩精品高清视频| 国产精品久久久久久久久| 日韩欧美在线中文字幕| 欧美华人在线视频| 日韩电影大片中文字幕| 亚洲中国色老太| 国产91对白在线播放| 亚洲国产第一页| 亚洲高清免费观看高清完整版| 国产日韩av高清| 国产成+人+综合+亚洲欧美丁香花| 91久久久久久久| 成人女保姆的销魂服务| 色天天综合狠狠色| 欧美日韩国产123| 日韩黄色av网站| 亚洲天堂av高清| 国产精品视频xxxx| 国产精品视频永久免费播放| 亚洲综合中文字幕68页| 久久国产精品影视| 欧美激情亚洲激情| 久久精品国产亚洲7777| 日韩精品在线免费观看| 亚洲a∨日韩av高清在线观看| 亚洲最大av网| 97avcom| 久久久99久久精品女同性|