文章类型: VC&C++
关键词: VC,C++,获得,控件,所在区域,坐标,位置
内容摘要: 在VC中获得控件所在区域的坐标位置

在VC中获得控件所在区域的坐标位置

2017/11/14 11:40:05    来源:apple    阅读:

在OnPaint()函数中   

  ((CStatic*)GetDlgItem(IDC_jieshou1))->GetWindowRect(&rect2);   

    

  在OnInitDialog()函数中   

  ((CStatic*)GetDlgItem(IDC_jieshou1))->GetWindowRect(&rect2);   

    

  上面的代码是获得控件在起父窗口的相对位置。在OnInitDialog()中调用是对的,坐标没有问题   

  但是在OnPaint里调用却有问题   啊,坐标不对啊


onpaint里面的坐标系是相对的,以可自绘区域的左上角作为原点   

  你可以转换一下试试ScreenToClient(&rect2);


先调用GetWindowRect后再调用ScreenToClient,这个时候得到的rect和直接使用GetClientRect得到的值是相等的。有时候需要获得窗口矩形的大小和客户区矩形的大小二者的值,故需要分别调用GetWindowRect和GetClientRect。如果只需要获得客户区矩形的大小,调用GetClientRect就行了。GetWindowRect和GetClientRect函数的说明如下:


CWnd::GetClientRect  

    void GetClientRect( LPRECT lpRect ) const;

Parameters:

lpRect

    Points to a RECT structure or a CRect object to receive the client coordinates. The left and top members will be 0. The right and bottom members will contain the width and height of the window.

Remarks:

    Copies the client coordinates of the CWnd client area into the structure pointed to by lpRect. The client coordinates specify the upper-left and lower-right corners of the client area. Since client coordinates are relative to the upper-left corners of the CWnd client area, the coordinates of the upper-left corner are (0,0).


CWnd::GetWindowRect

void GetWindowRect( LPRECT lpRect ) const;

Parameters:

lpRect

Points to a CRect object or a RECT structure that will receive the screen coordinates of the upper-left and lower-right corners.

Remarks:

Copies the dimensions of the bounding rectangle of the CWnd object to the structure pointed to by lpRect. The dimensions are given in screen coordinates relative to the upper-left corner of the display screen. The dimensions of the caption, border, and scroll bars, if present, are included.


GetWindowRect() 得到的是在屏幕坐标系下的RECT;(即以屏幕左上角为原点) 

GetClientRect() 得到的是在客户区坐标系下的RECT; (即以所在窗口左上角为原点) 


GetWindowRect()取的是整个窗口的矩形; 

GetClientRect()取的仅是客户区的矩形,也就是说不包括标题栏,外框等;


第一个函数获得的是窗口在屏幕上的位置,得到的结果可能是这样CRect(10,10,240,240); 

第二个函数和它不同,它只获得了客户区的大小,因此得到的结果总是这样CRect(0,0,width,height);


ScreenToClient() 就是把屏幕坐标系下的RECT坐标转换为客户区坐标系下的RECT坐标。



The GetClientRect function retrieves the coordinates of a window's client area. The client coordinates specify the upper-left and lower-right corners of the client area. Because client coordinates are relative to the upper-left corner of a window's client area, the coordinates of the upper-left corner are (0,0).


GetClientRect得到的是客户区的大小,也就是说这样得到的左上角永远是(0,0)


The GetWindowRect function retrieves the dimensions of the bounding rectangle of the specified window. The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.


GetWindowRect 是窗口相对于整个屏幕的坐标,屏幕左上点为0,0


相互转化用ScreenToClient 或者 ClientToScreen


ClientToScreen

The ClientToScreen function converts the client coordinates of a specified point to screen coordinates. 

BOOL ClientToScreen(

   HWND hWnd,        // window handle for source coordinates

   LPPOINT lpPoint   // pointer to structure containing screen coordinates

);

Parameters

hWnd 

Handle to the window whose client area is used for the conversion. 

lpPoint 

Pointer to a POINT structure that contains the client coordinates to be converted. The new screen coordinates are copied into this structure if the function succeeds. 

Return Values

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero.


虽然存在调用GetWindowRect后再调用ScreenToClient==GetClientRect,但ScreenToClient()和ClientToScreen()两者都是属于WINDOWS API函数,可能是存在一定的冗余设计,但意义不同。

不过在.Net Framework下对WINDOWS API函数进行了重新整理和优化,在获取控件或窗口的屏幕坐标和客户区坐标时更方便的多,只需要得到与控件或窗口相对应屏幕坐标和客户区坐标属性值就可以了。


ScreenToClient

The ScreenToClient function converts the screen coordinates of a specified point on the screen to client coordinates. 

BOOL ScreenToClient(

   HWND hWnd,         // window handle for source coordinates

   LPPOINT lpPoint    // address of structure containing coordinates

);

Parameters:

hWnd 

Handle to the window whose client area will be used for the conversion. 

lpPoint 

Pointer to a POINT structure that contains the screen coordinates to be converted. 

Return Values:

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero.

VC学习笔记1:按钮的使能与禁止

用ClassWizard的Member Variables为按钮定义变量,如:m_Button1

则:

m_Button1.EnableWindow(true); 使按钮处于允许状态

m_Button1.EnableWindow(false); 使按钮被禁止,并变灰显示


VC学习笔记2:控件的隐藏与显示


用CWnd类的函数BOOL ShowWindow(int nCmdShow)可以隐藏或显示一个控件。


例1:

CWnd *pWnd;

pWnd = GetDlgItem(IDC_EDIT1);//获取控件指针,IDC_EDIT为控件ID号

pWnd->ShowWindow(SW_HIDE);//隐藏控件


例2:

CWnd *pWnd;

pWnd = GetDlgItem( IDC_EDIT1 );//获取控件指针,IDC_EDIT为控件ID号

pWnd->ShowWindow( SW_SHOW );//显示控件


以上方法常用于动态生成控件,虽说用控件的Create函数可以动态生成控件,但这种控件很不好控制,所以用隐藏、显示方法不失为一种替代手段。


VC学习笔记3:改变控件的大小和位置

用CWnd类的函数MoveWindow()或SetWindowPos()可以改变控件的大小和位置。


void MoveWindow(int x,int y,int nWidth,int nHeight);

void MoveWindow(LPCRECT lpRect);


第一种用法需给出控件新的坐标和宽度、高度;


第二种用法给出存放位置的CRect对象;


例:

CWnd *pWnd;

pWnd = GetDlgItem( IDC_EDIT1 );     //获取控件指针,IDC_EDIT1为控件ID号

pWnd->MoveWindow( CRect(0,0,100,100) );     //在窗口左上角显示一个宽100、高100的编辑控件


SetWindowPos()函数使用更灵活,多用于只修改控件位置而大小不变或只修改大小而位置不变的情况:

BOOL SetWindowPos(const CWnd* pWndInsertAfter,int x,int y,int cx,int cy,UINT nFlags);


第一个参数我不会用,一般设为NULL;

x、y控件位置;cx、cy控件宽度和高度;

nFlags常用取值:

SWP_NOZORDER:忽略第一个参数;

SWP_NOMOVE:忽略x、y,维持位置不变;

SWP_NOSIZE:忽略cx、cy,维持大小不变;


例:

CWnd *pWnd;
pWnd = GetDlgItem( IDC_BUTTON1 );     //获取控件指针,IDC_BUTTON1为控件ID号
pWnd->SetWindowPos( NULL,50,80,0,0,SWP_NOZORDER | SWP_NOSIZE );//把按钮移到窗口的(50,80)处
pWnd = GetDlgItem( IDC_EDIT1 );
pWnd->SetWindowPos( NULL,0,0,100,80,SWP_NOZORDER | SWP_NOMOVE );//把编辑控件的大小设为(100,80),位置不变
pWnd = GetDlgItem( IDC_EDIT1 );
pWnd->SetWindowPos( NULL,0,0,100,80,SWP_NOZORDER );//编辑控件的大小和位置都改变

以上方法也适用于各种窗口。


VC学习笔记4:什么时候设定视中控件的初始尺寸?


我在CFormView的视中加入了一个编辑控件,在运行时使它充满客户区,当窗口改变大小时它也跟着改变。


改变控件尺寸可以放在OnDraw()函数中,也可放在CalcWindowRect()函数中,当窗口尺寸发生变化时,它们都将被执行,且CalcWindowRect()函数先于OnDraw()函数,下例是在CalcWindowRect()函数中修改控件尺寸。


重载VIEW类的CalcWindowRect函数,把设定控件的尺寸的语句加入这个函数中。


例:

void CMyEditView::CalcWindowRect(LPRECT lpClientRect, UINT nAdjustType)
{
     // TODO: Add your specialized code here and/or call the base class
     CFrameWnd *pFrameWnd=GetParentFrame(); //获取框架窗口指针
     CRect rect;
     pFrameWnd->GetClientRect(&rect); //获取客户区尺寸
     CWnd *pEditWnd=GetDlgItem(IDC_MYEDIT); //获取编辑控件指针,IDC_MYEDIT为控件ID号
     pEditWnd->SetWindowPos(NULL,0,0,rect.right,rect.bottom-50,SWP_NOMOVE | SWP_NOZORDER); //设定控件尺寸,bottom-50是为了让出状态条位置。
     CFormView::CalcWindowRect(lpClientRect, nAdjustType);
}


VC学习笔记5:单选按钮控件(Ridio Button)的使用


一、对单选按钮进行分组:


每组的第一个单选按钮设置属性:Group,Tabstop,Auto;其余按钮设置属性Tabstop,Auto。

如:

Ridio1、Ridio2、Ridio3为一组,Ridio4、Ridio5为一组

设定Ridio1属性:Group,Tabstop,Auto

设定Ridio2属性:Tabstop,Auto

设定Ridio3属性:Tabstop,Auto

设定Ridio4属性:Group,Tabstop,Auto

设定Ridio5属性:Tabstop,Auto


二、用ClassWizard为单选控件定义变量,每组只能定义一个。如:m_Ridio1、m_Ridio4。


三、用ClassWizard生成各单选按钮的单击消息函数,并加入内容

void CWEditView::OnRadio1()
{
     m_Ridio1 = 0;     //第一个单选按钮被选中
}

void CWEditView::OnRadio2()
{
     m_Ridio1 = 1;     //第二个单选按钮被选中
}

void CWEditView::OnRadio3()
{
     m_Ridio1 = 2;     //第三个单选按钮被选中
}

void CWEditView::OnRadio4()
{
     m_Ridio4 = 0;     //第四个单选按钮被选中
}

void CWEditView::OnRadio5()
{
    m_Ridio4 = 1;     //第五个单选按钮被选中
}


四、设置默认按钮:


在定义控件变量时,ClassWizard在构造函数中会把变量初值设为-1,只需把它改为其它值即可。


如:

//{{AFX_DATA_INIT(CWEditView)

m_Ridio1 = 0;     //初始时第一个单选按钮被选中

m_Ridio4 = 0;     //初始时第四个单选按钮被选中

//}}AFX_DATA_INIT


VC学习笔记6:旋转控件(Spin)的使用


当单击旋转控件上的按钮时,相应的编辑控件值会增大或减小。其设置的一般步骤为:


一、在对话框中放入一个Spin控件和一个编辑控件作为Spin控件的伙伴窗口,


设置Spin控件属性:Auto buddy、Set buddy integer、Arrow keys


设置文本控件属性:Number


二、用ClassWizard为Spin控件定义变量m_Spin,为编辑控件定义变量m_Edit,定义时注意要把m_Edit设置为int型。


三、在对话框的OnInitDialog()函数中加入语句:

BOOL CMyDlg::OnInitDialog()
{
     CDialog::OnInitDialog();

     m_Spin.SetBuddy( GetDlgItem( IDC_EDIT1 ) );//设置编辑控件为Spin控件的伙伴窗口
     m_Spin.SetRange( 0, 10 );//设置数据范围为0-10
     return TRUE;
}


四、用ClassWizard为编辑控件添加EN_CHANGE消息处理函数,再加入语句:


void CMyDlg::OnChangeEdit1()

{

    m_Edit = m_Spin.GetPos();     //获取Spin控件当前值

}


五、将SPIN控件的 “Set Bueey Integer”设置为TRUE。


OK!


VC学习笔记7:程序结束时保存文件问题


在文档-视图结构中,用串行化自动保存文件在各种VC书上都有介绍。现在的问题是我不使用串行化,而是自己动手保存,当点击窗口的关闭按钮时,如何提示并保存文档。


用ClassWizard在文档类(CxxDoc)中添加函数CanCloseFrame(),再在其中加入保存文件的语句就可以了。


注:要保存的数据应放在文档类(CxxDoc)或应用程序类(CxxApp)中,不要放在视图类中。


例:


//退出程序

BOOL CEditDoc::CanCloseFrame(CFrameWnd* pFrame)
{
     CFile file;
     if(b_Flag)     //b_Flag为文档修改标志,在修改文档时将其置为True
     {
         int t;
         t=::MessageBox(NULL,"文字已经改变,要存盘吗?","警告",
                 MB_YESNOCANCEL | MB_ICONWARNING);     //弹出提示对话框
         if(t==0 || t==IDCANCEL)
             return false;
         if(t==IDYES)
         {
             CString sFilter="Text File(*.txt)|*.txt||";
             CFileDialog m_Dlg(FALSE,"txt",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,(LPCTSTR)sFilter,NULL);//定制文件对话框
             int k=m_Dlg.DoModal();     //弹出文件对话框
             if(k==IDCANCEL || k==0)
                 return false;
             m_PathName=m_Dlg.GetPathName();     //获取选择的文件路径名
             file.Open(m_PathName,CFile::modeCreate | CFile::modeWrite);
             file.Write(m_Text,m_TextLen);     //数据写入文件
             file.Close();
         }
     }
     return CDocument::CanCloseFrame(pFrame);
}


第一种用法需给出控件新的坐标和宽度、高度;

第二种用法给出存放位置的CRect对象;

例:

CWnd *pWnd;

pWnd = GetDlgItem( IDC_EDIT1 ); //获取控件指针,IDC_EDIT1为控件ID号

pWnd->MoveWindow( CRect(0,0,100,100) ); //在窗口左上角显示一个宽100、高100的编辑控件


SetWindowPos()函数使用更灵活,多用于只修改控件位置而大小不变或只修改大小而位置不变的情况:

BOOL SetWindowPos(const CWnd* pWndInsertAfter,int x,int y,int cx,int cy,UINT nFlags);

第一个参数我不会用,一般设为NULL;

x、y控件位置;cx、cy控件宽度和高度;

nFlags常用取值:

SWP_NOZORDER:忽略第一个参数;

SWP_NOMOVE:忽略x、y,维持位置不变;

SWP_NOSIZE:忽略cx、cy,维持大小不变;

例:

CWnd *pWnd;

pWnd = GetDlgItem( IDC_BUTTON1 ); //获取控件指针,IDC_BUTTON1为控件ID号

pWnd->SetWindowPos( NULL,50,80,0,0,SWP_NOZORDER | SWP_NOSIZE ); //把按钮移到窗口的(50,80)处

pWnd = GetDlgItem( IDC_EDIT1 );

pWnd->SetWindowPos( NULL,0,0,100,80,SWP_NOZORDER | SWP_NOMOVE ); //把编辑控件的大小设为(100,80),位置不变

pWnd = GetDlgItem( IDC_EDIT1 );

pWnd->SetWindowPos( NULL,0,0,100,80,SWP_NOZORDER ); //编辑控件的大小和位置都改变

以上方法也适用于各种窗口。


实例:

CRect rc; 
GetWindowRect(&rc);
//控件为 GetDlgItem(IDC_STATIC_AUTHOR)->GetWindowRect(&rcLarge);
那么rc就是当前窗口的矩形大小 
rc.left,rc.top,rc.right,rc.bottom分别就是窗口左上右下的坐标了

SetWindowPos(NULL,0,0,rc.Width(),rc.top,SWP_NOMOVE|SWP_NOZORDER);
SetWindowPos(NULL,0,0,rc.Width(),rc.top-rcLarge.top,SWP_NOMOVE|SWP_NOZORDER); 
 
//*****************************BY RALF

 CRect   rect1,rect2;   
 GetDlgItem(IDC_RICHEDIT1)->GetWindowRect(rect1);
 GetDlgItem(IDC_RICHEDIT1)->ShowWindow(SW_HIDE);
 GetDlgItem(IDC_LIST1)->GetWindowRect(rect2);
 ScreenToClient(&rect2);
 GetDlgItem(IDC_LIST1)->SetWindowPos(&wndTop,rect2.TopLeft().x,rect2.TopLeft().y,rect2.Width(),rect2.Height()+rect1.Height(), SWP_SHOWWINDOW);

——————————————————————————————————————


得到按钮的坐标

 CMenu m_pop;
 CMenu*  m;
 m_pop.LoadMenu(IDR_MENU1);
 m=m_pop.GetSubMenu(3);
 CPoint CursorPos;
 CRect   rect;  
 GetDlgItem(IDC_BUTTON7)->GetWindowRect(rect);
 CursorPos=rect.BottomRight();
 m->TrackPopupMenu(TPM_LEFTALIGN,CursorPos.x-rect.Width(),CursorPos.y,this);


其中左下角的坐标等于右下角坐标减去宽度*******************


↑ 上一篇文章:sql如何查询表的第一条记录和最后一条记录 关键词:sql,查询,表,第一条,记录,最后一条 发布日期:2017/11/13 15:04:13
↓ 下一篇文章:盘点世界十大名著(二)续篇 关键词:盘点,世界,文学经典,十大名著,2006年,读者文摘,纽.. 发布日期:2017/11/16 9:00:02
相关文章:
VC++中ListBox控件的使用 关键词:VC++中ListBox控件的使用 发布日期:2017-05-15 10:48
VC++/MFC精讲多练#004:DIY一个漂亮的滚动条控件 关键词:VC++/MFC精讲多练#004:DIY一个漂亮的滚动条控件 发布日期:2016-10-09 14:40
VC++下的GetWindowRect和GetClientRect 关键词:VC,GetWindowRect,GetClientRect,窗口定位,相对位置,绝对位置,相对.. 发布日期:2017-11-30 17:10
相关目录:.NETVC&C++软件开发
我要评论
正在加载评论信息......