VS2010编译Gh0st3.6

VS 2010编译Gh0st 3.6

用Vs编译Gh0st修改的工作量还是挺大的,毕竟从VC6.0移植到VS2010平台,已经是一个很大的跨越了,VS2010相对于VC6.0也改进了不止一点了。Gh0st3.6使用了第三方界面库CJ60Lib,目前这个库只支持到VC6.0,而其后的版本已经商业化,所以使用VS2010编译Gh0st的时候,需要重新编译CJ60Lib。VS2010的自带安装的Windows SDK已经到了7.1版,也不需要像VC6.0那样需要下载Windows SDK,并配置环境了。VC6.0支持的最高版本的Windows SDK 是Windows 2003的,而VS2010自带的7.1版已经到了Windows Server 2008 了,其中发生的变化也是很大的。下面具体来操作一次。

        先列一下几个主要下文件路径。用的是Gh0s3.6原版,硬盘锁代码已经注释。

E:\Programming\VS2010\Gh0st3.6
E:\Programming\VS2010\Gh0st3.6\gh0st.dsw
E:\Programming\VS2010\Gh0st3.6\gh0st\CJ60Lib
E:\Programming\VS2010\Gh0st3.6\gh0st\CJ60Lib\CJ60Lib\CJ60Lib.dsw
E:\Programming\VS2010\Gh0st3.6\gh0st\CJ60Lib\Lib

一.编译CJ60Lib库

        直接用VS2010打开CJ60Lib.dsw进行转换。一共有7个,有4个是已经不存在的项目了,直接删掉。



在灰色的项目上点右键–Remove,或直接按Del键删除。

1.1编译CJ60StaticLib

        直接在CJ60StaticLib项目上点右键— Project Only —- Build Only CJ60StaticLib或者是 Rebuild Only CJ60StaticLib。以后说编译某个项目也是这样,不再重复说明了。



1.1.1

首先修改程序配置,让默认的字符都为ANSI字符,VS2010默认为宽字符Unicode版。

项目—右键—属性—C/C++—Language—WChar_t—No,如图所示:

修改编译后,对照错误,再来一个一个的修改。


1.1.2

1> stdafx.cpp
1> _WIN32_WINNT not defined. Defaulting to _WIN32_WINNT_MAXVER (see WinSDKVer.h)
1>e:\programming\vs2010\gh0st3.6\gh0st\cj60lib\cj60lib\stdafx.h(51): fatal error C1083: 无法打开包括文件:“..\src\afximpl.h”: No such file or directory

双击这个错误,定位到 stdafx.h 中的

#include<..\src\afximpl.h>
把这句话改成
#include<..\src\mfc\afximpl.h>

1.1.3

接着修改warning C4819警告

warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失

这个警告至需要双击打开该文件,然后保存就可以了。

1.1.4

gh0st3.6\gh0st\cj60lib\cj60lib\subclass.cpp(117): error C2065: “p”: 未声明的标识符

这是因为VS更符号C++标准,临时变量的作用域已经修正了,在Gh0st里,可以看到很多这样的代码。只要把在for或if里面定义的变量,放到for或if之前定义就好了。

这里的代码是:

for (CSubclassWnd* p = theHookMap.Lookup(m_hWnd); p; p=p->m_pNext)

修改为

CSubclassWnd* p = NULL;
for (p = theHookMap.Lookup(m_hWnd); p; p=p->m_pNext) 

后面的i也是一样修改。

gh0st3.6\gh0st\cj60lib\cj60lib\coolmenu.cpp(803): error C2065: “i”: 未声明的标识符

for (i=0; i < nFound; i++) { 

这里的i,是在前面的
for (UINTi=0; i< nItem; i++) 

里面定义的,只要把for里面的i放到for之前定义就可以了,修改如下:

UINTi=0;
for (i=0; i< nItem; i++)

这样的错误修改,以后不再写出,因为实在是太多了,修改方法也很简单。

1.1.5

gh0st3.6\gh0st\cj60lib\cj60lib\coolmenu.cpp(76): error C4430: 缺少类型说明符 – 假定为 int。注意: C++ 不支持默认 int

在VC6.0里,用修饰符申明的变量可以不现式的写出变量类型,默认类型为int。如这里的const CXGAP = 1; 等于 const int CXGAP = 1; 但是VS2010必须现式的指出,不能省略。所以修改方法就是现式的写上定义类型。

// constants used for drawing 

constCXGAP = 1; // num pixels between button and text 

constCXTEXTMARGIN = 2; // num pixels after hilite to start text 

constCXBUTTONMARGIN = 2; // num pixels wider button is than bitmap 

constCYBUTTONMARGIN = 2; // ditto for height 

修改如下:

// constants used for drawing 

constintCXGAP = 1; // num pixels between button and text 

constintCXTEXTMARGIN = 2; // num pixels after hilite to start text 

constintCXBUTTONMARGIN = 2; // num pixels wider button is than bitmap 

constintCYBUTTONMARGIN = 2; // ditto for height

这个在Gh0st里有,以后这个错误也不在指出。

1.1.6

接下来要解决的就是一大堆的重定义错误了

1>c:\program files\microsoft sdks\windows\v7.0a\include\shlwapi.h(126): error C2011: “tagSFBS_FLAGS”:“enum”类型重定义
1>          c:\program files\microsoft sdks\windows\v7.0a\include\shlwapi.h(126) : 参见“tagSFBS_FLAGS”的声明
1>c:\program files\microsoft sdks\windows\v7.0a\include\shlwapi.h(251): error C2084: 函数“HRESULT SHLocalStrDupW(LPCWSTR,LPWSTR *)”已有主体
1>          c:\program files\microsoft sdks\windows\v7.0a\include\shlwapi.h(250) : 参见“SHLocalStrDupW”的前一个定义
1>c:\program files\microsoft sdks\windows\v7.0a\include\shlwapi.h(256): error C2084: 函数“HRESULT SHLocalStrDupA(LPCSTR,LPSTR *)”已有主体
1>          c:\program files\microsoft sdks\windows\v7.0a\include\shlwapi.h(255) : 参见“SHLocalStrDupA”的前一个定义
1>c:\program files\microsoft sdks\windows\v7.0a\include\shlwapi.h(860): error C2365: “URL_SCHEME_INVALID”: 重定义;以前的定义是“枚举数”
1>          c:\program files\microsoft sdks\windows\v7.0a\include\shlwapi.h(860) : 参见“URL_SCHEME_INVALID”的声明
1>c:\program files\microsoft sdks\windows\v7.0a\include\shlwapi.h(861): error C2365: “URL_SCHEME_UNKNOWN”: 重定义;以前的定义是“枚举数”
1>          c:\program files\microsoft sdks\windows\v7.0a\include\shlwapi.h(861) : 参见“URL_SCHEME_UNKNOWN”的声明
1>c:\program files\microsoft sdks\windows\v7.0a\include\shlwapi.h(862): error C2365: “URL_SCHEME_FTP”: 重定义;以前的定义是“枚举数”
1>          c:\program files\microsoft sdks\windows\v7.0a\include\shlwapi.h(862) : 参见“URL_SCHEME_FTP”的声明
1>c:\program files\microsoft sdks\windows\v7.0a\include\shlwapi.h(863): error C2365: “URL_SCHEME_HTTP”: 重定义;以前的定义是“枚举数”
1>          c:\program files\microsoft sdks\windows\v7.0a\include\shlwapi.h(863) : 参见“URL_SCHEME_HTTP”的声明
1>c:\program files\microsoft sdks\windows\v7.0a\include\shlwapi.h(864): error C2365: “URL_SCHEME_GOPHER”: 重定义;以前的定义是“枚举数”
1>          c:\program files\microsoft sdks\windows\v7.0a\include\shlwapi.h(864) : 参见“URL_SCHEME_GOPHER”的声明
1>c:\program files\microsoft sdks\windows\v7.0a\include\shlwapi.h(865): error C2365: “URL_SCHEME_MAILTO”: 重定义;以前的定义是“枚举数”
1>          c:\program files\microsoft sdks\windows\v7.0a\include\shlwapi.h(865) : 参见“URL_SCHEME_MAILTO”的声明
1>c:\program files\microsoft sdks\windows\v7.0a\include\shlwapi.h(866): error C2365: “URL_SCHEME_NEWS”: 重定义;以前的定义是“枚举数”
1>          c:\program files\microsoft sdks\windows\v7.0a\include\shlwapi.h(866) : 参见“URL_SCHEME_NEWS”的声明

造成这个原因是ATL和CJLIB库的兼容性问题上,从错误上看是shlwapi.h里的代码被重定义了,ATL在定义前都会判断一下是否已经定义,而CJLIB则没有判断。解决方法是把CJLIB中的shlwapi.h包含给注释掉。可以在当前项目搜索shlwapi.h,一共有两处。

E:\Programming\VS2010\Gh0st3.6\gh0st\CJ60Lib\Include\ModulVer.h
E:\Programming\VS2010\Gh0st3.6\gh0st\CJ60Lib\Include\ShellTree.h

把其中的 #include<Shlwapi.h> 改成 //#include <Shlwapi.h>
重新编译后,错误一下少了很多,看起来也清爽了许多。

1.1.7

gh0st3.6\gh0st\cj60lib\cj60lib\cjsizedockbar.cpp(89): error C2440: “static_cast”: 无法从“UINT (__thiscall CCJSizeDockBar::* )(CPoint)”转换为“LRESULT (__thiscall CWnd::* )(CPoint)”
1>          从基类型到派生类型的强制转换需要 dynamic_cast 或 static_cast

这句话定位到的是ON_WM_NCHITTEST(),其实就是消息响应函数的返回值类型不匹配,这里也可以看出VS2010和VC6.0的不同。ON_WM_NCHITTEST对应的消息函数是UINTCCJSizeDockBar::OnNcHitTest(CPointpoint) ,把返回值类型改下就好了。有两处:

E:\Programming\VS2010\Gh0st3.6\gh0st\CJ60Lib\CJ60Lib\CJSizeDockBar.cpp
UINTCCJSizeDockBar::OnNcHitTest(CPointpoint) 

修改为:

LRESULTCCJSizeDockBar::OnNcHitTest(CPointpoint) 

E:\Programming\VS2010\Gh0st3.6\gh0st\CJ60Lib\Include\CJSizeDockBar.h
afx_msgUINTOnNcHitTest(CPointpoint); 

修改为:

afx_msgLRESULTOnNcHitTest(CPointpoint); 

后面还有一个一样的错误,只是所在类不一样,修改方法还是一样的

gh0st3.6\gh0st\cj60lib\cj60lib\cjcontrolbar.cpp(155): error C2440: “static_cast”: 无法从“UINT (__thiscall CCJControlBar::* )(CPoint)”转换为“LRESULT (__thiscall CWnd::* )(CPoint)”
1>          从基类型到派生类型的强制转换需要 dynamic_cast 或 static_cast

这里就不再说了,请参考上面的修改。

1.1.8

gh0st3.6\gh0st\cj60lib\cj60lib\cjpagerctrl.cpp(75): error C2440: “static_cast”: 无法从“BOOL (__thiscall CCJPagerCtrl::* )(NMPGSCROLL *,LRESULT *)”转换为“BOOL (__thiscall CCmdTarget::* )(NMHDR *,LRESULT *)”
1>          在匹配目标类型的范围内没有具有该名称的函数
gh0st3.6\gh0st\cj60lib\cj60lib\cjpagerctrl.cpp(76): error C2440: “static_cast”: 无法从“BOOL (__thiscall CCJPagerCtrl::* )(NMPGCALCSIZE *,LRESULT *)”转换为“BOOL (__thiscall CCmdTarget::* )(NMHDR *,LRESULT *)”
1>          在匹配目标类型的范围内没有具有该名称的函数

这两处的错误都是一样的,都是同一种参数类型不匹配。定位信息:

ON_NOTIFY_REFLECT_EX(PGN_SCROLL, OnPagerScroll) 

ON_NOTIFY_REFLECT_EX(PGN_CALCSIZE, OnPagerCalcSize)

可以看出他们所对应的函数分别是OnPagerScroll和OnPagerCalcSize。直接在上面按F12(右键–跳转到定义处)就跳转到函数定义出了。

E:\Programming\VS2010\Gh0st3.6\gh0st\CJ60Lib\CJ60Lib\CJPagerCtrl.cpp
BOOLCCJPagerCtrl::OnPagerScroll(NMPGSCROLL* pNMPGScroll, LRESULT* pResult) 

{

    *pResult = 0;

returnFALSE; // Let parent handle message 

}

修改如下:

BOOLCCJPagerCtrl::OnPagerScroll(NMHDR* pNMPGScroll, LRESULT* pResult) 

{

    *pResult = 0;

returnFALSE; // Let parent handle message 

}

===================================================

BOOLCCJPagerCtrl::OnPagerCalcSize(NMPGCALCSIZE* pNMPGCalcSize, LRESULT* pResult) 

{

switch(pNMPGCalcSize->dwFlag) 

修改如下:

BOOLCCJPagerCtrl::OnPagerCalcSize(NMHDR* pNMHDRPGCalcSize, LRESULT* pResult) 

{

NMPGCALCSIZE *pNMPGCalcSize = (NMPGCALCSIZE *)pNMHDRPGCalcSize;

switch(pNMPGCalcSize->dwFlag) 

===================================================

接着修改头文件中申明的参数类型

E:\Programming\VS2010\Gh0st3.6\gh0st\CJ60Lib\Include\CJPagerCtrl.h
virtualBOOLOnPagerScroll(NMPGSCROLL* pNMPGScroll, LRESULT * pResult); 

virtualBOOLOnPagerCalcSize(NMPGCALCSIZE * pNMPGCalcSize, LRESULT* pResult); 

修改如下:

virtualBOOLOnPagerScroll(NMHDR* pNMPGScroll, LRESULT * pResult); 

virtualBOOLOnPagerCalcSize(NMHDR* pNMHDRPGCalcSize, LRESULT* pResult);

1.2 编译CJ60Lib

首先还是修改字符集为ANSI,不然默认为WChar_t。这步是编译Gh0st每一个项目都需要做的,以后的操作中不再提起,请注意。如果提示A函数和W函数重定义,参数冲突等,都是这个问题,改下项目属性就能解决了。

wchar_t *类型与USHORT *的转换错误

    VC6的编译器不支持wchar_t数据类型,wchar_t实际上被定义成unsigned short,VC9的编译器已经支持wchar_t为内置数据类型,但是由一个编译选项控制,这个选项默认是打开的,也就是将wchar_t作为编译器的内置数据类型。但是OLECHAR和WCHAR的定义仍然是unsigned short,在VC6的编译环境中,两者的指针都是USHORT *,相互赋值和做为函数参数传递没有问题,但是如果wchar_t作为编译器的内置数据类型,那就意味着wchar_t *与OLECHAR *或WCHAR *是两种不同类型的指针,相互赋值就会报编译错误,下面的信息就是一个典型的错误输出:

f:\project\.....\shellpidl.cpp(290) : error C2664: 'MultiByteToWideChar' : cannot convert parameter 5 from 'USHORT *' to 'LPWSTR'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

解决的方法就是使用C++的reinterpret_cast操作符或使用C-style强制转换,当然也可以在项目属性设置中关闭前面提到的那个选项。

这个直接编译就能过了。用VS2010编译函数很多安全函数的警告,这个不用管他,想修改也是可以的。还有一个_WIN32_WINNT宏未定义的警告,如非必要,我就不加上去了,尽量的保持和原版的相同。要加的话,直接加在每个项目的StdAfx.h里面。格式:#define_WIN32_WINNT 0×0500 这里的参数含义可以参看MSDN,后面有一处修改必须加,也会再次提到。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值