首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

禁用 Print Screen、托管 C++ 析構函數語意、CLS 合規性等進階議題

     編輯:關於VC++

一、禁用螢幕擷圖

無法完全阻止第三方程式以 BitBlt 擷取螢幕像素,但可禁用系統熱鍵 Print Screen / Alt+Print Screen:

// CMainFrame 中
int OnCreate(LPCREATESTRUCT lpCreateStruct) {
    RegisterHotKey(m_hWnd, IDHOT_SNAPDESKTOP, 0, VK_SNAPSHOT); // Print Screen
    return 0;
}
void OnDestroy() { UnregisterHotKey(m_hWnd, IDHOT_SNAPDESKTOP); }

// 攔截 WM_HOTKEY,直接返回 0 旁路預設行為
LRESULT OnHotKey(WPARAM wp, LPARAM) { return 0; }

// 視窗啟用/停用時動態註冊/註銷 Alt+Print Screen
void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized) {
    CFrameWnd::OnActivate(nState, pWndOther, bMinimized);
    if (nState) RegisterHotKey(m_hWnd, IDHOT_SNAPWINDOW, MOD_ALT, VK_SNAPSHOT);
    else UnregisterHotKey(m_hWnd, IDHOT_SNAPWINDOW);
}

CS_OWNDC 無效,因 Windows 仍會將私有 DC 像素複製到螢幕 DC。

二、托管類別析構函數自動為虛擬

在 /clr 編譯下,托管類別析構函數隱含為虛擬,即使未宣告 virtual,刪除基類指標指向的衍生物件時,衍生類別析構函數仍會被正確呼叫。

原理:編譯器將析構函數轉為 Finalize 方法 (Object 類別虛擬方法),並產生 __dtor 方法供 delete 呼叫。__dtor 以 callvirt 呼叫 Finalize,CLR 依實際物件型別分派。各 Finalize 會顯式呼叫基類 Finalize 確保順序。另呼叫 GC::SuppressFinalize 避免 GC 重複終結。

ILDASM 反組譯圖

三、無法從 Managed 程式碼直接呼叫 MFC 擴充 DLL

MFC 擴充 DLL 依賴大量 MFC 狀態 (CWinApp 指標、模組狀態等),托管環境極難建立。建議:

  • 將核心邏輯提取為無狀態 extern "C" 函數,以 P/Invoke 呼叫。
  • 或將邏輯重寫為 Managed 類別。
  • UI 程式碼微軟明確不建議從 Managed 呼叫 MFC。

四、UInt32 非 CLS 合規的含義與對策

CLS (Common Language Specification) 定義跨語言互通的型別子集。UInt32 非 CLS 合規,因 VB.NET (舊版) 無無號整數型別。

  • 規則僅適用於公開介面 (public/protected 類別/方法);內部實作可自由使用。
  • 任何 .NET 語言皆可參考 使用 UInt32 的組件,但 VB 等語言無法建構 無號值,傳入負數會被視為大數值。
  • 若需完整 32 位元無號範圍且支援 VB,公開介面改用 Int64。

檢查 CLS 合規:C# 可用 [assembly: CLSCompliant(true)] 讓編譯器檢查;C++ 編譯器識別屬性但不檢查;FxCop 也不檢查 CLS 合規。目前無自動工具檢查 Managed C++ 的 CLS 合規性。

結語

掌握熱鍵攔截、托管析構語意、MFC/Managed 邊界、CLS 合規性,能避開跨語言、跨執行期開發的常見陷阱。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved