ClientToScreen ()與 ScreenToClient()

ClientToScreen( )是把窗口座標轉換爲屏幕座標
pWnd->GetWindowRect(&rc);是獲取整個窗體的大小
pWnd->GetClientRect(&rc1);是獲取窗體中客戶區的大小

ScreenToClient( )是把屏幕座標轉換爲窗口座標
屏幕座標是相對於屏幕左上角的,而窗口座標是相對於窗口用戶區左上角的
VC下,有些函數使用窗口座標,有些使用屏幕座標,使用時要分清。


一個窗體分爲兩部分:系統區和客戶區
象標題和菜單之類的是系統區,由系統來控制,客戶區就是你的地盤嘍!!!
Width, Height 是指總體的,ClientWidth, ClientHeight是指客戶區的,二者相減就是
系統區的啦!!!
ClientToScreen是把座標從當前窗體轉化成全屏幕的!!!
ScreenToClient是把屏幕座標轉化成相對當前窗體的座標!!!!
在MFC對話框程序中,若是要得到對話框中某個控件相對於屏幕的rect,必須爲這個控件定義一個控件變量,而後經過該控件變量調用ClientToScreen。
若是在Dialog類裏面直接調ClientToScreen,那麼得到的是該Dialog窗體左上角rect大小的一塊 空間 相對於屏幕的rect。
  1. point   
  2. 是相對CLYHchxuView(暫時理解爲屏幕)的座標  
  3. 若是你要獲的是相對CLYHchxuView左上角的座標  
  4. 就不須要轉換  
  5. 若是你你要獲的是相對程序主窗口左上角的座標  
  6. 能夠這樣算  
  7. void CLYHchxuView::OnLButtonDblClk(UINT nFlags, CPoint point)   
  8. {   
  9. // TODO: Add your message handler code here and/or call default   
  10.   
  11. CRect rc;  
  12. GetParent()->GetWindowRect(&rc);  
  13. ClientToScreen(&point);    
  14. docx=point.x-rc.left;  
  15. docy=point.y-rc.top;  
  16. Invalidate();   
  17. CView::OnLButtonDblClk(nFlags, point);   
  18. }  

point 
是相對CLYHchxuView(暫時理解爲屏幕)的座標
若是你要獲的是相對CLYHchxuView左上角的座標
就不須要轉換
若是你你要獲的是相對程序主窗口左上角的座標
能夠這樣算
void CLYHchxuView::OnLButtonDblClk(UINT nFlags, CPoint point) 
{ 
// TODO: Add your message handler code here and/or call default 

CRect rc;
GetParent()->GetWindowRect(&rc);
ClientToScreen(&point);  
docx=point.x-rc.left;
docy=point.y-rc.top;
Invalidate(); 
CView::OnLButtonDblClk(nFlags, point); 
}


如今來看看Invalidate(TRUE)都幹了些什麼。其實,它只是間接向消息隊列添加了 WM_ERASEBKGND 和WM_PAINT兩個消息。可是,若是使用Invalidate(FALSE)的話,則只有WM_PAINT消息產生,這時是不會有任何閃爍的

如今看來,閃爍彷佛是由WM_ERASEBKGND消息產生的,事實上,的確與它有關。那WM_ERASEBKGND有幹了什麼呢?WM_ERASEBKGND消息由OnEraseBkgnd()消息處理函數響應,它的做用就是重繪客戶區背景。咱們能夠經過向工程裏添加WM_ERASEBKGND這個消息,而後在重寫的消息處理函數中將返回語句修改成return TRUE來屏蔽這一功能,這樣作的好處是這時不會重繪背景了,壞處是這時背景也不會被擦出來。 函數

    好像尚未說到真實緣由,其實真正的緣由就隱含在其中。如今來作一個實驗,分別嘗試一下快速的眨眼和慢速的眨眼,你會發現快速眨眼時咱們會感受眼前的黑色一閃而過,而慢速眨眼時,則會以爲整個過程是連續的,沒有什麼異樣。其實閃爍也就是這麼回事,即多張不連續圖像的快速切換。這裏有三個條件,多張和快速和不連續,並且須要同時具有纔會發生閃爍。若是隻是兩張,只會感受到突變,還談不上閃爍;若是頻率慢的話,也至關於兩張圖像的狀況了;最後若是是連續圖像的話,那就像是看電影,平穩的過渡也不會讓人以爲不適。 spa

    知道了這些,接下來就能夠作決策了。 .net

    解決方案code

    使用Invalidate(FALSE),添加WM_ERASEBKGND消息處理函數或者局部刷新三者選其一,都是能夠解決問題的。它們的都是經過除去圖像不連續這一因素來達到目的的。 blog

 

    另外,要說的是GDI的BitBlt()函數是及其高效的,一次操做所須要的時間只有幾到十幾個微秒,因此咱們能夠放心的使用它,而不用擔憂任何效率問題。不過相對於BitBlt()來講StretchBlt()就要慢的多,大概是幾十倍的差異。 隊列

    還有就是通常的繪圖工做都是先繪製在一個緩衝區上,而後再一次拷貝到屏幕上。 get

    有時,當咱們須要利用閃爍的效果的話,也是能夠經過多張圖像的快速切換來作到,在這裏咱們也將兩張圖像的重複切換理解爲多張圖像。 消息隊列

相關文章
相關標籤/搜索