扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
作者:中国IT实验室 来源:中国IT实验室 2007年9月29日
关键字: 编程
问题一: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文件里面有如下内容:
注意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 的一个可再发行包组件。
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者