惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

阮一峰的网络日志
阮一峰的网络日志
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
Schneier on Security
The Last Watchdog
The Last Watchdog
Cyberwarzone
Cyberwarzone
S
Securelist
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cyber Attacks, Cyber Crime and Cyber Security
L
Lohrmann on Cybersecurity
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 司徒正美
The Cloudflare Blog
V
V2EX
博客园_首页
博客园 - 聂微东
Vercel News
Vercel News
人人都是产品经理
人人都是产品经理
G
GRAHAM CLULEY
T
Tenable Blog
Last Week in AI
Last Week in AI
Y
Y Combinator Blog
L
LINUX DO - 最新话题
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
SecWiki News
SecWiki News
博客园 - 三生石上(FineUI控件)
S
Secure Thoughts
N
News | PayPal Newsroom
T
The Blog of Author Tim Ferriss
The GitHub Blog
The GitHub Blog
T
Troy Hunt's Blog
博客园 - 【当耐特】
Forbes - Security
Forbes - Security
H
Hacker News: Front Page
A
About on SuperTechFans
B
Blog RSS Feed
Engineering at Meta
Engineering at Meta
MongoDB | Blog
MongoDB | Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
罗磊的独立博客
D
DataBreaches.Net
P
Privacy & Cybersecurity Law Blog
Schneier on Security
Schneier on Security
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Google DeepMind News
Google DeepMind News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Jina AI
Jina AI
D
Docker
P
Proofpoint News Feed

博客园 - 吴博

C#类型 参考表(MSDN) 快速了解集群和双机热备相关知识 Could not find stored procedure 'sp_MSins_tablename' Javascript 判断 object 的特定类 当 ASP.NET 在 IIS 6.0 中锁死的情况下,如何生成转储文件 通往 WinDbg 的捷径 请教:在一个在方法段的异常处理里面,如何获取当前方法输入的所有参数值。 性能测试VS负载测试VS压力测试 Silverlight为什么不支持中文?有没有别的途径可以解决这个问题呢? 焦油坑与激情 sqlserver白皮书里的秘密 没有virtual的方法子类是否可以重写? 用记事本可以查看dll文件的release或debug依赖。 [zt]关于Debug和Release之本质区别的讨论 vc++,不知道是不是bug。 MSMQ之确认消息 乱解 Overried与new 分区表的经典比喻
VC++.NET 2005 几个比较难缠的问题及其解决方法(转)
吴博 · 2007-09-03 · via 博客园 - 吴博

问题一: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 的一个可再发行包组件

该文章转载自网络大本营:http://www.pushad.com/Info/6795.Html