2013-03-28 45 views
1

在Delphi 2007與Delphi XE2中聲明HDC類型(Device Context Handle)的方式有所不同。D2007與DXE2中的Delphi HDC類型聲明

在D2007下面的代碼工作正常,但產生在DXE2範圍檢查錯誤:

Control.Parent.Perform(WM_PAINT, Integer(DC), 0); 

當通過代碼D2007步進DC(設備上下文)的值似乎總是小於MAXINT但是在DXE2中,DC的值通常大於MaxInt。

爲什麼在同一臺機器(相同的項目,相同的代碼,相同的OS)上運行時,D2007和DXE2中的DC值不同?

將DC轉換爲WParam(我認爲這是一個無符號整數)是否安全?

+0

我強烈建議你採用鑄造'WParam',這應該在兩個環境中編譯。 – OnTheFly 2013-03-28 21:46:34

回答

3

在現代的Delphi版本中,您的演員陣容不正確。 Perform的第二個參數被輸入爲WPARAM,其在XE2中是無符號的。所以如果你要演員,那麼你應該投到WPARAM

在32位代碼中,您的演員重新將大值DC解釋爲負值。然後當你傳遞給一個無符號參數並且範圍檢查錯誤發生時。在64位代碼中,您的轉換會導致指針截斷。

但是你不需要施放任何東西。那是因爲HDCUINT_PTR,因此是WPARAM。只需刪除投:

Control.Parent.Perform(WM_PAINT, DC, 0); 

的Windows類型的定義傳統上一直是德爾福惹許多錯誤定義鍵類型。當引入64位Delphi編譯器時,Embarcadero選擇了那一刻來糾正這些錯誤。

在較舊的Delphi版本中,因爲第二個參數WPARAM已簽名,但HDC未簽名,因此需要投射。

+0

剛剛發現這[上一篇文章](http://stackoverflow.com/questions/7837084/when-did-wparam-change-from-being-signed-to-unsigned),其中指出WParam在XE2中更改爲無符號。因此,如果我理解正確,如果您的代碼將在XE2之前的Delphi版本中進行編譯,您應該投HDC,但將其轉換爲WParam(非Integer)。從XE2開始,你不應該投HDC。那個聽起來是對的嗎? – deonvn 2013-03-28 12:06:12

+0

是的,我認爲這是正確的。基本的問題是Delphi的舊版本做錯了。所以你必須施展才能彌補這些錯誤。如果你想要新舊編譯的代碼,然後轉換爲'WPARAM'。 – 2013-03-28 12:11:34

1

是carfull整型是不wParam參數.. 需要DC類型轉換爲wParam參數類型

Control.Parent.Perform(WM_PAINT, WPARAM(DC), 0); 
+0

因爲它們已經兼容,所以您不需要將'HDC'強制轉換爲'WPARAM'。它們都是'UINT_PTR'。 – 2013-03-28 10:44:29

+0

@大衛,這就是你不應該依賴的。您現在不需要這樣做,但是誰知道'HDC'或'WPARAM'將來可能會被定義爲不同的類型。 [+1] – TLama 2013-03-28 10:48:38

+1

@TLama它只是因爲Borland把它擰回來的時候才改變。在世界其他地方,它永遠都是未簽名的。它不會改變,因爲這樣做會破壞一切!回到足夠遠的地方,參數的Borland聲明是'Integer'。因此,通過你的分析,轉換成整數本來就是正確的。但是這首先導致了錯誤。現在類型被正確聲明瞭,強制轉換可以被刪除。鑄造的問題在於它將你帶入類型系統之外。演員們總是一種代碼味道。 – 2013-03-28 10:53:09