2016-09-04 130 views
-5

我看到的每個示例代碼都是GetDC和releaseDC。 (或者BeginPaint/EndPaint) 但是我認爲繪圖畫面經常發生(特別是在遊戲中),將它們存儲在內存中總是會得到更好的釋放。Win32API)我爲什麼要一次又一次獲取DC和ReleaseDC?

所以我確實喜歡把mainDC保持爲全局,只是使用它,只有在程序結束時才釋放它。但爲什麼人們不這樣做呢? (可能獲取/釋放DC的成本很少?)

case WM_CREATE: 
    hdc = GetDC(hWnd); //hdc is declared as global HDC 
    MyBitmap = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP1)); 
    return 0; 
case WM_PAINT: 
    MemDC = CreateCompatibleDC(hdc); 
    OldBitmap = (HBITMAP)SelectObject(MemDC, MyBitmap); 
    BitBlt(hdc, 0, 0, 300, 300, MemDC, 0, 0, SRCCOPY); 
    SelectObject(MemDC, OldBitmap); 
    DeleteDC(MemDC); 
    return 0; 
+4

*「但是爲什麼人們不這樣做?」* - 因爲它都是錯誤的。所以你節省了廉價的操作'GetDC'只在每次重繪時調用昂貴的操作('CreateCompatibleDC')。而且由於你永遠不會調用'BeginPaint' /'EndPaint',無效區域永遠不會被驗證,即使沒有任何東西可以繪製,也會產生連續的WM_PAINT消息。在嘗試優化之前,您需要了解它的工作原理。 – IInspectable

+0

人們不這樣做,因爲文檔說你不能。不應該像這樣緩存DC,除非您特別注意使用適當的標誌創建窗口類,而不應該這樣做。區議會旨在成爲臨時性對象,僅在必要時創建並在事後立即處置。使用'GetDC'檢索DC足夠便宜,這在286處理器上運行良好。無論您現在運行什麼芯片,它都能夠保證足夠快。 –

+0

@CodyGray哇,我的好奇心剛剛吹走!謝謝大家回答。 – JokyDandy

回答

0

您在此處顯示的代碼是錯誤的。首先,您需要閱讀更多文檔。這裏有一個有用的鏈接:Painting and Drawing。基本上有兩種方法來更新窗口:

  • 在響應WM_PAINT消息。使用BeginPaint()/ EndPaint()函數正確繪製客戶區。當客戶區域的一部分被「無效」時(由於調整大小,從最小化狀態恢復,移動先前遮蔽它的窗口或者在程序上使其無效WM_PAINT是低優先級消息,在消息隊列變空之前收到
  • 特別繪製一個部分或者整個客戶區域,而沒有一個無效的區域,使用GetDC()/ ReleaseDC()來實現這一點。 ,當應用程序(CPU)是忙。

編寫一些代碼來處理WM_PAINT消息通常是幾乎強制性的,而具體地繪製以及是可選的,這取決於應用程序的要求。

從不自己發送或發佈WM_PAINT消息,而是使部分或整個客戶區失效 - 應用程序將在空閒之前收到WM_PAINT消息。如果你想讓繪畫直接調用UpdateWindow() - 這會繞過消息隊列。

0

Windows 10中的最近(2016年8月)安全更新阻止重新使用打印機設備上下文。打印完一個文檔後,Windows 10將拒絕使用同一個DC再次打印。爲每個文檔創建一個新的DC一直是首選實踐,但現在它似乎是Windows 10中的一項要求。