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

    有时,当咱们须要利用闪烁的效果的话,也是能够经过多张图像的快速切换来作到,在这里咱们也将两张图像的重复切换理解为多张图像。 消息队列

相关文章
相关标签/搜索