科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道VC++.NET几个比较难缠的问题及其解决方法

VC++.NET几个比较难缠的问题及其解决方法

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

   问题一:HWND和System::Inptr32的转换 如果你用惯了VB.NET,你一定会认为窗体的Handle属性就等同于API里面要的那个HWND――的确,MSDN里面就是这么说的,而且。

作者:中国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文件里面有如下内容:

<?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 的一个可再发行包组件。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件