Popup&ScreenToClient&ClientToScreen

来源:互联网 发布:淘宝虚拟物品恶意退款 编辑:程序博客网 时间:2024/06/10 03:01

void __fastcall TShellFileOpenForm::NnBitBtnShowTypeMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
{
 
 TPoint pt;
 pt = NnBitBtnShowType->ClientOrigin;
 pt.x = pt.x + NnBitBtnShowType->Width;
 pt.y = pt.y + NnBitBtnShowType->Height; 
 //ShowStylePopupMenu->Popup((pt.x+plToolBar->Left+ShowTypebtn->Left ),(pt.y+plToolBar->Top+ShowTypebtn->Top+ShowTypebtn->Height));
 ShowStylePopupMenu->Popup((pt.x),(pt.y));
}


 P.x = X;
 P.y = Y;
 ClientToScreen(Owner->Handle, &P);
 Command = TrackPopupMenu(Menu, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON |
      TPM_RETURNCMD, P.x, P.y, 0, Owner->Handle, NULL);

 


RECT __fastcall TNcProgram::ClientToForm( RECT rect )
{
 
    RECT   retRect;
    POINT   pt;

   
    pt.x = rect.left;
    pt.y = rect.top;
    pt = ClientToScreen( pt );              
    pt = Parent->ScreenToClient( pt );      
    retRect.top = pt.y;
    retRect.left = pt.x;

    
    pt.x = rect.right;
    pt.y = rect.bottom;
    pt = ClientToScreen( pt );            
    pt = Parent->ScreenToClient( pt );     
    retRect.bottom = pt.y;
    retRect.right = pt.x;

    return  retRect;
}

 

void __fastcall TNnDBCtrlGrid::ChildMouseDownProc( System::TObject* Sender, TMouseButton Button,  Classes::TShiftState Shift, int X, int Y )
{
 TDBCtrlPanel *pPanel = (TDBCtrlPanel *)GetChildParent( );
 int idx = -1;
 for( int i=0; i<pPanel->ControlCount; i++ )
        {
  if( ((TControl *)Sender) == pPanel->Controls[i] ){
   
   break;
  }
 }
 if( (dynamic_cast<TWinControl *>(Sender) == NULL)&&(dynamic_cast<TControl *>(Sender) != NULL) )
        {
  
  POINT   pt;
  pt.x = X;
  pt.y = Y;
  pt = ((TControl *)Sender)->ClientToScreen( pt );
  pt =  ScreenToClient( pt );
  MouseDown( Button, Shift, pt.x, pt.y );
 }
 if( FChildDefMouseDownProc[idx] != NULL )
        {
  
  (FChildDefMouseDownProc[idx])( Sender, Button, Shift, X, Y );
 }
}


GetClientRect的CRect是相对它的窗口的客户区的原点而言的,即它的左上角坐标总是(0,0),大小总是客户区的长宽。GetWindowRect得到的CRect则是相对于屏幕坐标而言的,它的左上角坐标就是窗口在屏幕上的左上角坐标,它的大小就是整个窗口的大小。
ClientToScreen,可以把一个CPoint对象或CRect对象的坐标从客户区坐标系(以客户区左上角为原点)变换为屏幕坐标系(以屏幕左上角为原点)。
如:
// 把对话框的大小变成客户区的大小
void CAboutDlg::OnButton1()
{
CRect myRect;
GetClientRect(&myRect);//取得客户区的大小

ClientToScreen(myRect);//转换为屏幕坐标
MoveWindow(myRect.left, myRect.top,
myRect.Width(), myRect.Height());//MoveWindow使用的是屏幕坐标
}

ScreenToClient,则可以把一个CPoint对象或CRect对象的坐标从屏幕坐标系变换为客户区坐标系。
例如:
CPoint pos( ::GetMessagePos() ); //::GetMessagePos() 得到发生事件时鼠标的屏幕坐标
ScreenToClient(&pos);//把它转换为客户区坐标以便随后在绘图时使用
...
使用以下代码,可以把对话框移到刚好覆盖的地方:
CRect rcTab; // 整个Tab
CRect rcItem; // Tab上方的按钮

// 取得并计算要移动的矩形框
m_tab1.GetWindowRect(&rcTab); // 屏幕坐标
ScreenToClient(rcTab); // 化成父窗口的客户区坐标
m_tab1.GetItemRect(0, &rcItem); // 取得Tab上方按钮的大小
rcTab.DeflateRect(0,rcItem.bottom+1,0,0); // 缩小Tab的矩形

// 把对话框移动到这个矩形框上
m_Page1->MoveWindow(rcTab); // 相对于父窗口的客户区移动

补充:
关于这些函数的最权威、最详细的描述,请参看MSDN。
GetClientRect(),GetWindowRect()这两个函数都是CWnd类的成员函数,或称为方法(Method)。所以调用它们得到的矩形都是属于调用它们的那个CWnd对象的窗口的,如m_tab1.GetWindowRect(&rcTab); 得到的矩形rcTab就是Tab控件的窗口大小和位置(屏幕坐标系)。"它的大小就是整个窗口的大小"这句话中说的窗口就是发出GetWindowRect()调用的这个CWnd窗口。

 

 


GetWindowRect是取得窗口在屏幕坐标系下的RECT坐标(包括客户区和非客户区),这样可以得到窗口的大小和相对屏幕左上角(0,0)的位置。
GetClientRect取得窗口客户区(不包括非客户区)在客户区坐标系下的RECT坐标,可以得到窗口的大小,而不能得到相对屏幕的位置,因为这个矩阵是在客户区坐标系下(相对于窗口客户区的左上角)的。(这个client area可以是一个控件的客户区,如:picture control)  

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

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


http://wqj1212.blog.bokee.net/bloggermodule/blog_viewblog.do?id=1359881


procedure MakeSamePos(AControl, RefControl: TControl);
var
  P: TPoint;
begin
  P := RefControl.BoundsRect.TopLeft;
  P := RefControl.Parent.ClientToScreen(P);
  P := AControl.Parent.ScreenToClient(P);
  AControl.Left := P.x;
  AControl.Top := P.y;
end;

 

原创粉丝点击