设为首页 加入收藏

TOP

代码高处走 从VC6到VC9移植代码问题说明(三)
2014-11-23 20:26:41 来源: 作者: 【 】 浏览:266
Tags:代码 高处 VC6 VC9 移植 问题 说明
rFxn) \

  { message, 0, 0, 0, AfxSig_lwl, \

  (AFX_PMSG)(AFX_PMSGW) \

  (static_cast< LRESULT (AFX_MSG_CALL CWnd::*)(WPARAM, LPARAM) > \

  (memberFxn)) },

  注意,函数类型没有变化,都是:

  LRESULT (AFX_MSG_CALL CWnd::*)(WPARAM, LPARAM);

  类型的函数指针(CWnd以及派生类的类成员函数指针),区别之处是新的ON_MESSAGE宏使用C++的static_cast 操作符代替了C类型的强制转换。产生这两个错误其实是因为用户没有按照ON_MESSAGE宏的约定声明和定义消息响应函数造成的,比如,对于某些不需要处理返回值的消息响应函数,用户通常这样声明和定义消息响应函数:

  在头文件中声明:

  afx_msg void OnFileProcess(WPARAM wParam,LPARAM lParam);

  在源文件中实现:

  void CCrpFileOpavDlg::OnFileProcess(WPARAM wParam, LPARAM lParam)

  {

  .......

  }

  或者更过分一些,直接指定为实际参数类型:

  在头文件中声明:

  afx_msg void OnFileProcess(LPCTSTR lpszMessage, int nPercent);

  在源文件中实现:

  void CCrpFileOpavDlg::OnFileProcess(LPCTSTR lpszMessage, int nPercent)

  {

  .......

  }

  旧版本的ON_MESSAGE使用了C类型的强制转换,宏解开后的代码后不会产生错误信息,但是改成对类型检查很严格的static_cast 操作符时就出问题了,因为通不过static_cast 操作符的检查。解决方法就是修改代码,同时吸取教训,普遍使用的方法并不一定就能约定俗成,一切还是要按照规矩来。

  错误现象之三:

  f:\project\.....\WzButton.cpp(74) : error C2440: 'static_cast' : cannot convert from 'UINT (__thiscall CWzButton::* )(CPoint)' to 'LRESULT (__thiscall CWnd::* )(CPoint)'

  Cast from base to derived requires dynamic_cast or static_cast

  出现这个错误的原因可是“人力不可抗拒”之原因造成的,因为旧版本的ON_WM_NCHITTEST 宏使用了

  UINT (__thiscall CWzButton::* )(CPoint);

  类型的类成员函数指针,其定义如下:

  #define ON_WM_NCHITTEST() \

  { WM_NCHITTEST, 0, 0, 0, AfxSig_wp, \

  (AFX_PMSG)(AFX_PMSGW)(UINT (AFX_MSG_CALL CWnd::*)(CPoint))&OnNcHitTest },

  但是新版本变成了:

  #define ON_WM_NCHITTEST() \

  { WM_NCHITTEST, 0, 0, 0, AfxSig_l_p, \

  (AFX_PMSG)(AFX_PMSGW) \

  (static_cast< LRESULT (AFX_MSG_CALL CWnd::*)(CPoint) > (&ThisClass :: OnNcHitTest)) },

  注意返回值类型由UINT改成了LRESULT,再加上static_cast的严格检查,所以就出错了。修改的方法就是将你的OnNcHitTest函数由:

  afx_msg UINT OnNcHitTest(CPoint point);

  改成:

  afx_msg LRESULT OnNcHitTest(CPoint point);

  不必太在意,这个不是你的错,不过,如果你要维护一个老的界面库(通常很多控件的subclass都会用到ON_WM_NCHITTEST),改起来还是很痛苦地,不扯了,继续下一个。

  七、statreg.cpp 和atlimpl.cpp 的废弃(obsolete)问题

  在编译老的ATL向导生成的代码时,会遇到下面的编译输出:

  StdAfx.cpp

  statreg.cpp is obsolete. Please remove it from your project.

  atlimpl.cpp is obsolete. Please remove it from your project.

  因为老的ATL向导生成的代码通常在stdafx.cpp文件中添加以下代码:

  #ifdef _ATL_STATIC_REGISTRY

  #include

  #include

  #endif

  #include

  根据提示删除#include 和#include 两行代码就行了,不过更好的办法是这样改:

  #ifdef _ATL_STATIC_REGISTRY

  #include

  #if _MSC_VER <= 1200 // MFC 6.0 or earlier

  #include

  #endif

  #endif

  #if _MSC_VER <= 1200 // MFC 6.0 or earlier

  #include

  #endif

  八、新的C++编译器不再支持默认类型的变量定义

  错误现象是:

  f:\project\.....\WzCheckBox.cpp(464) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

  产生这个错误的原因是程序中出现了这样的代码:

  const some_const_var = 10;

  或

  static some_static_bool = FALSE;

  新的C++编译器严格按照C++标准,不再支持默认类型的变量定义方式,必须严格指定变量类型,如下使用:

  const int some_const_var = 10;

  或

  static BOOL some_static_bool = FALSE;

  九、for 语句的变量作用域问题

  考察下面的代码:

  for(int i = 0; i < 120; i++)

  {

  if(something_happen)

  {

  break;

  }

  .............

  }

  if(i < 120)

  {

  //something happen

  }

  在VC6的编译器中,这样的代码是没有问题的,因为VC6的编译器为了兼容旧的Microsoft C/C++编译器,没有严格按照C++标准执行,但是从VC7开始,VC的编译器开始遵守C++标准,所以就会出现“变量i没有定义的错误”。解决的方法也很简单,按照Jim Hyslop 和Herb Sutter的经典对话系列的第四篇中的方法,改成如下就可以了:

  int i;

  for(i = 0; i < 120; i++)

  十、字符串函数的返回值问题

  strchr(_tcschr)、strpbrk(_tcspbrk)、strrchr(_tcsrchr)和strstr(_tcsstr)这四个函数在VC6的CRT库中定义的返回值都是char *(TCHAR *) (#add 括号里和括号外的也是依次对应
首页 上一页 1 2 3 4 5 下一页 尾页 3/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇VC+ADO 连接ACCESS和SQL SERVER的.. 下一篇VC++ 6.0点打开按钮出现 “Micros..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: