1. 程式人生 > >VC自定義訊息ON_MESSAGE的編譯錯誤error C2440

VC自定義訊息ON_MESSAGE的編譯錯誤error C2440

在手動新增ON_MESSAGE時,遇到下面的編譯錯誤:

error C2440: 'type cast' : cannot convert from 'void (__thiscall CXXXView::*)(unsigned int,long)' to 'long (__thiscall CWnd::*)(unsigned int,long)' Pointers to members have different representations; cannot cast between them

因為是已有工程,且要新增的檢視與已存在的檢視有很多相似的地方,因此,我使用了Ctrl+C和Ctrl+V,結果編譯出現上面的錯誤。

雙擊上面的錯誤,VC定位到ON_MESSAGE(……)一處,沒仔細看錯誤提示,剛開始以為是.h中宣告與.cpp中不一致,感覺手工新增訊息處理的三個地方好像也沒有什麼不對,後來,心血來潮,轉到了ON_MESSAGE的定義處,才弄明白,原來是因為訊息處理函式的返回值型別為void,而ON_MESSAGE巨集中,要求訊息處理函式的返回值為long,後來將.h和.cpp中函式的返回型別改為LRESULT後編譯就通過了……

之前在將VC6.0的工程轉換到VC++2005上時,也遇到類似的問題,在VC6中,定義為void的訊息處理函式能編譯通過,VC++2005卻無法通過,將其返回型別改為LRESULT就可以通過了。以後手工新增訊息處理的時候,最好還是將返回型別指定為LRESULT。

《Programming Windows with MFC》一書中,How Message Maps Work(中文版1.3.6)中這樣寫的:

You can find out how message maps work by examining the DECLARE_MESSAGE_MAP, BEGIN_MESSAGE_MAP, and END_MESSAGE_MAP macros in Afxwin.h and the code forCWnd::WindowProc in Wincore.cpp.

訊息對映機制是通過三個巨集DECLARE_MESSAGE_MAP, BEGIN_MESSAGE_MAP, and END_MESSAGE_MAP 來實現的。

巨集DECLARE_MESSAGE_MAP在類中添加了3個成員:

1) _messageEntries:AFX_MSGMAP_ENTRY陣列,包含了訊息與訊息處理程式之間的關聯關係。

2) messageMap:AFX_MSGMAP指標,結構中包括指向類中的_messageEntries指標以及指向父類的messageMap指標。

3) GetMessageMap函式(Virtual):返回messageMap指標。

BEGIN_MESSAGE_MAP巨集則包含GetMessageMap函式的實現及messageMap的初始化工作。

BEGIN_MESSAGE_MAP和END_MESSAGE_MAP之間出現的程式碼將被填入到_messageEntries陣列中。

c++中的函式前面加個LRESULT表示函式的返回值是LRESULT型別。
需要注意的是LRESULT是一個數據型別:
MSDN: 32-bit value returned from a window procedure or callback function
指的是從視窗程式或者回調函式返回的32位值
在winnt.h中typedef long LONG;
在windef.h中typedef LONG LRESULT;
所以LRESULT就是longresult,也就是長整型
之所以取名類LRESULT,是因為L即long,result表示結果,說明這個函式的返回值是某個結果。

高版本的VS編譯低版本的VS程式時,可能會出現以下問題:

error C2440: 'static_cast' : cannot convert from 'void (__thiscall CMainFrame::* )(void)' to 'LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)'  

其原因是訊息對映ON_MESSAGE(WM_message,OnMyMessage)中OnMyMessage返回值必須為LRESULT,其形式為:

afx_msg LRESULT OnMyMessage(WPARAM, LPARAM);

如果不符合,則有錯誤提示:error C2440: “static_cast”: 無法從“void (__thiscall CPppView::* )(WPARAM,LPARAM)”轉換為“LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)” 表示在匹配目標型別的範圍內沒有具有該名稱的函式
    

解決方法如下:

1,把原來的訊息函式返回值型別改為LRESULT,函式內可以隨便寫個return TRUE; 

2.訊息函式的引數必須改寫成(WPARAM wParam,LPARAM lParam)而不論這兩個引數是否用得到;

3.訊息對映如ON_MESSAGE(WM_message,& OnMyMessage)。


相關推薦

VC定義訊息ON_MESSAGE編譯錯誤error C2440

在手動新增ON_MESSAGE時,遇到下面的編譯錯誤: error C2440: 'type cast' : cannot convert from 'void (__thiscall CXXXView::*)(unsigned int,long)' to 'long

VC定義訊息ON_MESSAGE的用法

在一個對話方塊mark.cpp中,自定義一個訊息, 首先在mark.cpp中新增 #define WM_DATA   WM_USER+100   之後再mark.h裡 protected:// Generated message map functions//{{AFX_M

Cocos2d-x 專案新建定義類後編譯錯誤:打不開定義標頭檔案錯誤解決方案

現在Cocos2dx新建工程需要執行Python指令碼來建立,不再提供Cocos2dx模板。一般我們使用VS2010編譯完Cocos2dx後,可以開始使用Cocos2dx目錄下\tools\project-creator\create_project.py來建立工程。 命

VC++定義訊息的傳送與接收的方法實現

訊息傳遞的方法一:使用ON_MESSAGE 使用ON_MESSAGE響應訊息,必須配合定義訊息#define WM_MY_MESSAGE (WM_USER+100) 對於傳送訊息者-MyMessageDlg, 在其MyMessageDlg.h中,定義#define WM_M

VC++之定義訊息

使用者可以自定義訊息,在應用程式中主動發出,這種訊息一般用於應用程式的某一部分內部處理。   例項說明: 當用戶按鍵盤上的游標上移鍵時,程式傳送使用者自定義訊息,在對應的訊息響應函式中彈出訊息對話方塊,顯示訊息傳送成功。   操作步驟: (1)建立一個單文

vc++ 不同對話方塊中傳遞資訊的方法(基於定義訊息SendMessage)

也是花了一天時間才搞定的。 背景: 新建了一個基於對話方塊的MFC程式,在主對話方塊中新增tabcontrol控制元件,又新建了兩個Dialog(CDialog1和CDialog2),將它們設為tabcontrol控制元件的子對話方塊。 目的: 兩個子對話方塊之間傳遞訊息,子對話方塊與主對話

vc中用SendMessage定義訊息傳遞

SendMessage的函式原型為 LRESULT SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); 第一個引數hWnd,是訊息傳遞的目標視窗或執行緒的控制代碼 第二個引數Msg,是訊息的類別,可以是一些系統訊

laravel 中定義 api 介面的錯誤訊息

當在laravel 中編寫 api 介面時,throw new Exception() 返回的錯誤訊息格式不是我們想要的格式 解決辦法: 在 App\Exceptions目錄下新建一個 ApiException類 繼承 Exception  namespace App\Ex

vc中怎麼使用SendMessage定義訊息函式

   最近在用VC2008做開發,後來由於要用到訊息的傳送,而且需要自定義訊息,在網上查找了很多例子,根據他們所說的,雖然大致都差不多,但是基本上沒有一個能完全做出來的。要知道VC程式設計有一個小地方出錯,都可能是個讓你頭暈腦脹的事情。經過我後來不但探索,經過改進之後,一點錯

VC++ 新增定義訊息響應函式以及傳送訊息SendMessage投遞訊息PostMessage的簡單測試

1.自定義訊息ID。 MyMessageDlg.h中 #define WM_MY_MESSAGE (WM_USER + 100) WM_USER為windows系統為非系統訊息保留的ID,這裡至

關於VS2008編譯錯誤"error LNK2005: 已經在 .obj 中定義"

無意中遇到了這樣的編譯問題, 於是google,發現在.h檔案裡定義變數,發生這問題的概率是灰常大的. 下面這段紅字是參考網上的說法: 當你第一個使用這個頭的.cpp檔案生成.obj的時候,int i 在裡面定義了當另外一個使用這個的.cpp再次[單獨]生成.obj的時候,int i 又被定義然後兩個o

angualar入門學習-- 定義指令 指令編譯執行過程

監聽 監聽器 註冊 sco lar scl $watch 學習 排序 3個階段: 一、加載階段 加載angular.js的源碼,找到ng-app確定應用邊界範圍。 二、編譯階段 compile 查找所有指令,保存在一個列表中 對所有指令按優先級(property屬性值)排序

定義訊息提示框

使用原生JavaScript簡單封裝的一個訊息提示模態框,如果誰有更好的方式可以分享,謝謝! <!DOCTYPE html> <html lang="en"> <head> <title></title> <meta

如何在MFC中定義訊息

訊息對映、迴圈機制是Windows程式執行的基本方式。VC++   MFC   中有許多現成的訊息控制代碼,可當我們需要完成其它的任務,需要自定義訊息,就遇到了一些困難。在MFC   ClassWizard中不允許新增使用者自定義訊息,所以我們必須在程式中新增相應程式碼

Android studio 使用定義mk檔案編譯jni專案

最近將公司ndk專案從eclipse遷移到as,為了方便省事,直接使用原有mk檔案。參考網路資料,順利完成遷移工作。現貼出使用自定義mk檔案的關鍵程式碼,mark以備後面使用。 buildTypes { release { minifyEna

[Visual Studio C++] [MFC] 新增使用者定義訊息訊息響應函式講解

一、前言           本文介紹 兩種方法 新增使用者自定義訊息及訊息響應函式。  第一種,使用者手動新增兩個檔案((.h)和 (.cpp))的內容。  第二種,利用 MFC 的整合功能,自動新增。(推薦

orbslam編譯錯誤error: static assertion failed

Ubuntu16.04後編譯報錯,提示: /usr/local/include/eigen3/Eigen/src/Core/util/StaticAssert.h:32:40: error: static assertion failed: YOU_MIXED_DIFFERENT_NUMERIC

定義訊息通知、手機震動、提示音

Android中自定義訊息通知、獲取手機震動、提示音,在此做下記錄 package com.wjy.project.railway.activity; import android.annotation.TargetApi; import android.app.Notification;

androidstudio2.3.1 ndk 編譯錯誤error: clang frontend command failed with exit code 70 (use -v to

問題描述 android ndk編譯公司舊程式碼時出現如下錯誤: clang.exe: error: clang frontend command failed with exit code 70 (use -v to see invocation) 原因分析&查詢

MFC中傳送定義訊息機制,PostMessage和SendMessage方式

       MFC中有種訊息佇列,使用PostMessage()或者SendMessage()給窗體傳送自定義訊息,當窗體接收到訊息時呼叫該訊息對應繫結的方法。 PostMessage:把訊息投放到執行緒的訊息佇列,不等訊息被處理就立即返回;Send