熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

VC++.NET幾個比較難纏的問題及其解決方法

2013-11-13 09:58:07  來源: .NET編程 

  問題一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 的一個可再發行包組件


From:http://tw.wingwit.com/Article/program/net/201311/12140.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.