欢迎光临
我们一直在努力

VC++.NET 2005 几个比较难缠的问题及其解决方法-.NET教程,.NET Framework

建站超值云服务器,限时71元/月
问题一:hwnd和system::inptr32的转换
如果你用惯了vb.net,你一定会认为窗体的handle属性就等同于api里面要的那个hwnd——的确,msdn里面就是这么说的,而且,在vb.net里你可以这样写showwindow(me.handle,sw_show),这一切看上去没有错误,而且字面意思上是如此理所当然。但是,进入了clr c++的环境,showwindow(this->handle,sw_show)的直接结果就是编译器扔给你一句编译错误:类型不匹配,无法将system::inptr32转换为hwnd。
 
事实很明显,handle并不如msdn里面说的那样就是hwnd,vb.net在把handle传进api的时候进行了类型转换,如果你有把vb.net程序移植到clr c++或者在clr c++里面使用用vb.net的程序集的经验,就会对这些深有体会。clr c++最大的问题在于,它对绝大部分的.net数据类型都要求用户显式地转换,而着对于.net framework来说没有类型自动转换显然是非常痛苦的。
我们再说回这个handle,可能有人会这样说,我这样写可不可以呢?
showwindow(hwnd(this->handle),sw_show);
于是编译器再次给了你脸色看,还是那个错误。
 
接着就有人发现,handle还有一个方法 topointer,这次看上去问题肯定能解决了,不是么?pointer就是指针,hwnd不也是一个指针吗?于是,又有人提议:
showwindow(this->handl.topointer(),sw_show);
意思上是完美了,但是,非常遗憾,编译器说:我只认类型,不看意思,于是又报了一个错误出来。
 
做到这里,看上去已经是山穷水尽了。其实失败和成功只有一步之遥:hwnd和void*是可以互相转换的!我们只要再继续多写一步:
showwindow(hwnd(this->handle.topointer()),sw_show);
问题就可以解决。

 

 

接下来是第二个问题,还是这个showwindow。并不是所有场合我们都喜欢使用这样的语句:
this->show();
有时候,我们得使用showwindow来达到某些显示的效果。当我们兴高采烈地庆祝我们解决了handle的转换时,我们会惊讶地发现,showwindow显示出来的窗口什么也没有!上面的控件都不见了!
当我看到这个现象的时候,我脑袋里立刻想起一个东西:borland c++ builder。
是的,这个现象与borland c++ builder里的窗口显示特性简直一模一样!据说.net framework总的设计师就是那个大名鼎鼎的从borland跑到microsoft的安德森,果然有风格(可惜的就是mfc却没学到vcl的方便,倒是.net学了这个见鬼的特性)。怎么办呢?细心的人会发现,当我们对窗口执行 this->show();的时候,显示出来的窗口是无焦点的,也就是说,我们不再需要showwindow这个api了(因为这个api一般都是用来显示无焦点的窗体)。我们只要在show()执行之后设置窗口的windowstate,例如:
msgform->windowstate =system::windows::forms::formwindowstate::normal ;
问题三:打包安装。
程序写完了,以为终于可以松口气了。把程序和.net framework安装包拿到别人那里一安装,居然发觉弹出个错误对话框:程序配置不正确。
这是典型的缺少运行时错误。于是就奇怪,msdn不是说.net程序可以xcopy部署的么?只要有.net framework ,就只要拷贝程序到目标机器上面就可以运行的啊??!!
的确,对于vb和c#的程序,xcopy部署不会存在任何问题,因为这两门语言都是给.net量身订做的。但是c++不是。结果回去查看了vb.net程序和clr c++程序引用的dll,发现托管的c++程序比vb.net程序多引用两个dll:
                 msvcr80d.dll
                 msvcm80d.dll
然后我用reflector反编译我的程序,发现程序配置头xml文件里面有如下内容:
 
 
 
<?xml version=1.0 encoding=utf-8 standalone=yes?>
<assembly xmlns=urn:schemas-microsoft-com:asm.v1 manifestversion=1.0>
 <dependency>
    <dependentassembly>
      <assemblyidentity type=win32 name=microsoft.vc80.debugcrt version=8.0.50608.0 processorarchitecture=x86 publickeytoken=1fc8b3b9a1e18e3b />
    </dependentassembly>
 </dependency>
</assembly>
 
注意microsoft.vc80.debugcrt(当你编译程序使用debug模式就会产生)!
刚刚说的那两个dll就是microsoft.vc80.debugcrt的部件,现在你知道少了什么了吧?
于是我们必须把microsoft.vc80.debugcrt组件一起安装到目标机器上面。但是microsoft.vc80.debugcrt上哪找呢?
我们新建一个安装部署项目,然后添加合并模块,你会看到打开的默认文件夹里面有这个文件:
 
 
           policy_8_0_microsoft_vc80_debugcrt_x86.msm
 
猜都猜到这是什么了吧?添加进去!
当然,如果你编译使用的是release模式,你可能依然需要安装vc++.net 的一个可再发行包组件。
赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » VC++.NET 2005 几个比较难缠的问题及其解决方法-.NET教程,.NET Framework
分享到: 更多 (0)