问题一HWND和SystemInptr的转换
如果你用惯了VBNET你一定会认为窗体的Handle属性就等同于API里面要的那个HWND——的确MSDN里面就是这么说的而且在VBNET里你可以这样写ShowWindow(MeHandleSW_SHOW)这一切看上去没有错误而且字面意思上是如此理所当然但是进入了CLR C++的环境ShowWindow(this>HandleSW_SHOW)的直接结果就是编译器扔给你一句编译错误类型不匹配无法将SystemInptr转换为HWND
事实很明显Handle并不如MSDN里面说的那样就是HWNDVBNET在把Handle传进API的时候进行了类型转换如果你有把VBNET程序移植到CLR C++或者在CLR C++里面使用用VBNET的程序集的经验就会对这些深有体会CLR C++最大的问题在于它对绝大部分的NET数据类型都要求用户显式地转换而着对于NET Framework来说没有类型自动转换显然是非常痛苦的
我们再说回这个Handle可能有人会这样说我这样写可不可以呢?
ShowWindow(HWND(this>Handle)SW_SHOW)
于是编译器再次给了你脸色看还是那个错误
接着就有人发现Handle还有一个方法 ToPointer这次看上去问题肯定能解决了不是么?Pointer就是指针HWND不也是一个指针吗?
于是又有人提议ShowWindow(this>HandlToPointer()SW_SHOW)
意思上是完美了但是非常遗憾编译器说我只认类型不看意思于是又报了一个错误出来
做到这里看上去已经是山穷水尽了其实失败和成功只有一步之遥HWND和void*是可以互相转换的!我们只要再继续多写一步ShowWindow(HWND(this>HandleToPointer())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 =SystemWindowsFormsFormWindowStateNormal
问题三打包安装
程序写完了以为终于可以松口气了把程序和NET Framework安装包拿到别人那里一安装居然发觉弹出个错误对话框程序配置不正确
这是典型的缺少运行时错误于是就奇怪MSDN不是说NET程序可以XCopy部署的么?只要有NET Framework 就只要拷贝程序到目标机器上面就可以运行的啊??!!
的确对于vb和C#的程序xcopy部署不会存在任何问题因为这两门语言都是给NET量身订做的但是C++不是结果回去查看了程序和clr c++程序引用的dll发现托管的C++程序比程序多引用两个dll
MSVCRDdll
MSVCMDdll
然后我用reflector反编译我的程序发现程序配置头xml文件里面有如下内容
<?xml version= encoding=UTF standalone=yes?>
<assembly xmlns=urn:schemasmicrosoftcom:asmv manifestVersion=>
<dependency>
<dependentAssembly>
<assemblyIdentity type=win name=MicrosoftVCDebugCRT version= processorArchitecture=x publicKeyToken=fcbbaeeb />
</dependentAssembly>
</dependency>
</assembly>
注意MicrosoftVCDebugCRT(当你编译程序使用Debug模式就会产生)!
刚刚说的那两个dll就是MicrosoftVCDebugCRT的部件现在你知道少了什么了吧?
于是我们必须把MicrosoftVCDebugCRT组件一起安装到目标机器上面但是MicrosoftVCDebugCRT上哪找呢?
我们新建一个安装部署项目然后添加合并模块你会看到打开的默认文件夹里面有这个文件
policy___microsoft_vc_debugcrt_xmsm
猜都猜到这是什么了吧?添加进去!
当然如果你编译使用的是Release模式你可能依然需要安装VC++NET 的一个可再发行包组件