VC 获取控件在对话框中的坐标

VC如何获取对话框中控件的坐标

GetWindowRect是取得窗口在屏幕坐标系下的RECT坐标(包括客户区和非客户区),这样可以得到窗口的大小和相对屏幕左上角(0,0)的位置。

    GetClientRect取得窗口客户区(不包括非客户区)在客户区坐标系下的RECT坐标,可以得到窗口的大小,而不能得到相对屏幕的位置,它的top和left都为0,right和botton是宽和高,因为这个矩阵是在客户区坐标系下(相对于窗口客户区的左上角)的。  

    ClientToScreen把客户区坐标系下的RECT坐标转换为屏幕坐标系下的RECT坐标.

    ScreenToClient把屏幕坐标系下的RECT坐标转换为客户区坐标系下的RECT坐标.     我们对同一个窗口先GetWindowRect取得一个RECT,再用ScreenToClient转换到客户坐标系。然后GetClientRect取得一个RECT,再用ClientToScreen转换到屏幕坐标系。显然,GetWindowRect取得的矩阵不小于GetClientRect取得的矩阵。因为前者包含了非客户区,而后包括了客户区。


所以要获得一个控件再对话框中的坐标的实现代码是:

CRect lpRec; 
GetDlgItem(IDC_SLIDER_output)->GetWindowRect(&lpRec); 
ScreenToClient(&lpRec);

估计很多人都会遇到这么一个问题,平时我们用单文档/视图结构时,很容易就在客户区画个图,画根线什么的,然而,要在对话框的某个控件中画这些东西,刚一上来,还真有点搞吧。

    下面,我就把在对话框中对某个控件画图的程序先列出来,然后再看看微软的一些搞的地方。

初始化:

m_IsDrawing=false;
 CWnd*pCanvas=GetDlgItem(IDC_CANVAS);
 pCanvas->GetWindowRect(&m_Canvas);
 ScreenToClient(&m_Canvas);

void CPaintORamaDlg::OnLButtonDown(UINT nFlags, CPoint point) 
{
 // TODO: Add your message handler code here and/or call default
 /
 //Add code
 //---------------------------------------
 if(m_Canvas.PtInRect(point))
 {
  m_IsDrawing=true;
  m_LineStart=point;
  SetCapture();

 }


}

void CPaintORamaDlg::OnLButtonUp(UINT nFlags, CPoint point) 
{
 // TODO: Add your message handler code here and/or call default
 //
 //Add Code
 //------------------------------------------
 m_IsDrawing=false;
 ReleaseCapture();


}

void CPaintORamaDlg::OnMouseMove(UINT nFlags, CPoint point) 
{
 // TODO: Add your message handler code here and/or call default
 
 //Add Code
 //-----------------------------------------------
 if(m_Canvas.PtInRect(point))
 {
 if(m_IsDrawing && (nFlags&MK_LBUTTON))
 {
  CClientDC dc(this);
  dc.MoveTo(m_LineStart);

  dc.LineTo(point);

  m_LineStart=point;
 }
 }
}

 

首先,说明一点的是,通过鼠标单击或者移动传进来的CPoint是一个客户坐标,在文档/视图程序中,也就是客户区,用GetClientRect可以获得该区域。而在对话框中,CPoint还是表示客户区,只不过这个时候这个客户区就是整个的对话框自己,整个对话框就是客户区。必须通过this->GetClientRect来获取,它的top和left都是0。right和botton分别是该对话框的宽与高。

这时,假如我们想在对话框中的某个控件画图,按照我们的想法,获取该控件的窗口以及它的DC,然后我们就可以画图了,实际不是这样的,中间还需要一次转换,请看下面代码:

1   CRect lpRect;

2   CStatic *m_static = (CStatic*)GetDlgItem(IDC_STATIC1);

3   m_static->GetClientRect(&lpRect);

4   CDC *pDC = m_static->GetDC();

5   pDC->MoveTo(CPoint point);

6   pDC->Ellipse(...);

等等

上面的这些操作有以下问题,

1. 第三句中,通过GetClientRect来获取客户区,我们知道该函数是获取窗体的客户区,那么上面第三句就是获得该控件的客户区,它的top和left都为0,right和botton是宽和高。然而,前面我们说过,通过鼠标传入的CPoint是一个以整个对话框为客户区的客户区坐标,即它是以整个对话框的左上顶角点作为坐标原点计算的。所以这两者根本无法联系在一起,所以也就不能在该控件上画出这个点了。

这时,我们想起了另一个函数, GetWindowRect(),可是,这个函数只可以用来获取控件的屏幕坐标。即使用它也还是不能在控件上画出该点。对了,转换呀,我们可以用ScreenToClient,用这个函数可以将控件的坐标lpRect转换成以对话框左上顶点为原点的控件客户区坐标。 这样,就和传入的CPoint的坐标一致了。

真是搞的,微软何不提供一个直接获取控件在对话框客户区中的位置坐标呢,非要这么绕干嘛呢!

2.  第四句和第五句的问题,获取该控件的DC,然后画图,这是人的正常思维,可是微软不这么干,如果像上面这么画,将什么也画不出来,按照微软的想法,只有客户区才能画图,所以,还是要先老老实实的得到客户区的DC,可是,对话框程序中的客户区就是对话框本身呀,唉,没办法,还是先得到这个客户区吧。

CClientDC dc(this); 这里应该明白前面的控件和传入点为什么都要用以对话框左上顶点为原点的客户区坐标了吧。这样就可以让对话框DC来画它们了。

上面这段代码可以修改为如下:

 

    CRect lpRect;

    CStatic *m_static = (CStatic*)GetDlgItem(IDC_STATIC1);

    m_static->GetWindowRect(&lpRect);

    ScreenToClient(&lpRect);  

     CClientDC dc(this);

     dc.MoveTo(CPoint point);

     dc.LineTo(CPoint point);

     .......

MFC中,class CRect : public tagRECT类的一个成员函数,作用是判断参数中给出的点是否在矩形区域内。returns TRUE if point is within rectangle。

  [函数原型]
  BOOL PtInRect( POINT point ) const throw( );
  [声明]
  Declare Function PtInRect Lib "user32" (lpRect As RECT, pt As POINTAPI) As Long
  [说明]
  这个函数判断指定的点是否位于矩形lpRect内部
  [参数表]
  point ------------- POINTAPI,欲判断的点
  [返回值]
  Long,非零表示点在矩形内部,零表示点在矩形外部。会设置GetLastError
  [其它]
  如点位于矩形四边之内,或矩形的顶部或左侧边线上,则认为它在矩形内部。如位于矩形的右侧或底部边线,则不认为它在矩形内部


包括:

(1)动态设置控件的颜色

(2)获取鼠标位置

(3)CButtonST

程序的界面效果如下图:


可以方便地获取屏幕上任意点位置的颜色。RGB表示。

有额外需要(比如在窗口最下化情况下的读取颜色)的话可以自己改写代码。

关键点是设置一个定时器,然后在定时器函数中进行如下设置即可:

  1. void CGetScreenPixelDlg::OnTimer(UINT_PTR nIDEvent)  
  2. {  
  3.     // TODO: 在此添加消息处理程序代码和/或调用默认值  
  4. //  DWORD   dwPos = GetMessagePos();   
  5. //  CPoint point( LOWORD(dwPos),   HIWORD(dwPos) );  
  6. //  HWND hwnd=::GetForegroundWindow();  
  7.     CPoint   point;   
  8.     GetCursorPos(&point);  
  9.     HDC hDC = ::GetDC(NULL);    
  10.   
  11.     // 再获取当前鼠标位置像素值  
  12.     COLORREF color = ::GetPixel(hDC, point.x, point.y);   
  13.     // 设置中间显示的文字处的背景色(非黑色地方)  
  14.     m_colorState.SetBkColor(color);  
  15.     // 下面的都是设置对应文本控件的数值  
  16.     posx = point.x;  
  17.     posy = point.y;  
  18.     red = GetRValue(color);  
  19.     green = GetGValue(color);  
  20.     blue = GetBValue(color);  
  21.     UpdateData(FALSE);      // 文本控件的数值显示  
  22.     CDialogEx::OnTimer(nIDEvent);  
  23. }  


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
VC对话框滚动条绘画坐标指的是在VC(Visual C++)对话框,使用滚动条来制绘画的坐标。 在VC对话框,我们可以通过添加一个滚动条件来实现对话框内容的滚动。滚动条件是一个用户界面组件,通常是一个带有箭头和滑块的横向或纵向条形件。通过操作滚动条,我们可以改变内容的显示位置,使得内容可以在有限的区域内滚动查看。 绘画坐标是指在界面上绘制图形或者文字时,确定绘制位置的坐标系统。通常,在对话框进行绘图时,我们会使用设备坐标或者客户区坐标。 设备坐标是相对于显示设备或打印设备的物理单元的坐标系统,它是一个固定的坐标系统,不会因为窗口大小的改变而改变。设备坐标通常以左上角为原点,向右为正 X 轴方向,向下为正 Y 轴方向。 客户区坐标是相对于对话框客户区域(不包括标题栏和边框)的坐标系统。客户区坐标是一个相对坐标系统,它的原点位置随对话框大小的改变而改变,但是它的单位是像素,也是一个固定的坐标系统。 当我们使用滚动条来制绘画坐标时,我们可以通过滚动条的值来改变绘图的起始位置。比如,当滚动条滚动到最上方时,我们可以将绘画起始坐标设为设备坐标或客户区坐标的原点;当滚动条滚动到最下方时,我们可以将绘画起始坐标设为设备坐标或客户区坐标的某个固定值。 以上就是VC对话框滚动条绘画坐标的简要解释。通过使用滚动条,我们可以方便地制绘画内容的位置,使得对话框的内容可以在有限的区域内滚动查看。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值