程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> ON_COMMAND_RANGE多個按鈕呼應一個函數的處理辦法

ON_COMMAND_RANGE多個按鈕呼應一個函數的處理辦法

編輯:關於C++

ON_COMMAND_RANGE多個按鈕呼應一個函數的處理辦法。本站提示廣大學習愛好者:(ON_COMMAND_RANGE多個按鈕呼應一個函數的處理辦法)文章只能為提供參考,不一定能成為您想要的結果。以下是ON_COMMAND_RANGE多個按鈕呼應一個函數的處理辦法正文


本文描寫了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 )
Parameters
id1
Command ID at the beginning of a contiguous range of command IDs.
id2
Command ID at the end of a contiguous range of command IDs.
memberFxn
The name of the message-handler function to which the commands are mapped.
Remarks
The 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 edi
pop esi
pop ebx
add esp, 48h
cmp ebp, esp
call __chkesp (0041e680)
mov esp, ebp
pop ebp
ret 8(兩個參數出棧)

此匯編代碼的感化就是在函數前往時檢討挪用中和挪用前往時的棧能否分歧, 假如紛歧致, 就強迫平棧操作, 由於在這個挪用進程中, 傳入OnCommandMy的新聞參數只要一個(只是聲名成兩個, 現實只要一個參數傳入), 所以存在棧紛歧致的情形, 然則強迫平棧可以免由此惹起的毛病.
在Release版本下, 就沒有了檢測棧的操作,
只是簡略的上面幾句匯編代碼完成出棧操作:

mov esp, ebp
pop ebp
ret 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);

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved