none
用代码创建的控件怎样改变位置 RRS feed

  • 问题

  • 我创建了一个按钮

    m_btn.Create("BTN", WS_CHILD|WS_VISIBLE, CRect(10,10,100,30), this, IDC_MOVE);

     

    在OnSize函数中用下面的代码不能显示出窗口

    pWnd = GetDlgItem(IDC_MOVE);
     if(pWnd)
     {
      CRect Rect;
      pWnd->GetWindowRect(&Rect);
      ScreenToClient(&Rect);
     /* 
      Rect.left = Rect.left*cx/m_Rect.Width(); //有下面的四行代码就不能显示窗口
      Rect.right = Rect.right*cx/m_Rect.Width();
      Rect.top = Rect.top*cy/m_Rect.Height();
      Rect.bottom = Rect.bottom*cy/m_Rect.Height();
     */ 
      pWnd->MoveWindow(Rect);
     }
     GetClientRect(&m_Rect);

    这里的原因我想不明白,望高手解答.


    xiao
    2011年5月31日 14:20

答案

  • pWnd = GetDlgItem(IDC_MOVE);
    if(pWnd)
    {
    CRect Rect;
    pWnd->GetWindowRect(&Rect);
    ScreenToClient(&Rect);
    /*
    Rect.left = Rect.left*cx/m_Rect.Width(); //有下面的四行代码就不能显示窗口
    Rect.right = Rect.right*cx/m_Rect.Width();
    Rect.top = Rect.top*cy/m_Rect.Height();
    Rect.bottom = Rect.bottom*cy/m_Rect.Height();
    */
    pWnd->MoveWindow(Rect);
    }
    GetClientRect(&m_Rect);这几段代码没问题,如果是用从工具条上拖几个控件到窗口上用这段代码没有任何问题.

    如果用在代码创建的控件上就有问题了.


    xiao
    这个您需要Debug下调试一下啊!看看Rect的值具体是多少?

    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.
    • 已标记为答案 wh_xiao 2011年6月3日 8:29
    2011年6月2日 0:01
    版主
  • 要用这种方法,:

    if(m_btn.GetSafeHwnd())
     {
      CRect Rect;
      m_btn.GetWindowRect(&Rect);
      ScreenToClient(&Rect);
      m_btn.SetWindowPos(NULL, 4, Rect.top, cx-30, cy-Rect.top-50, SWP_NOACTIVATE|SWP_NOZORDER );
     }

    这里的计算是一件有点烦的工作.


    xiao
    • 已标记为答案 wh_xiao 2011年6月3日 8:21
    2011年6月3日 8:21

全部回复

  • 加上您注释掉的代码以后,您可以Debug下看看你的Rect值具体是多少就应该很清楚了吧。
    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.
    2011年5月31日 15:03
    版主
  • pWnd = GetDlgItem(IDC_MOVE);
    if(pWnd)
    {
    CRect Rect;
    pWnd->GetWindowRect(&Rect);
    ScreenToClient(&Rect);
    /*
    Rect.left = Rect.left*cx/m_Rect.Width(); //有下面的四行代码就不能显示窗口
    Rect.right = Rect.right*cx/m_Rect.Width();
    Rect.top = Rect.top*cy/m_Rect.Height();
    Rect.bottom = Rect.bottom*cy/m_Rect.Height();
    */
    pWnd->MoveWindow(Rect);
    }
    GetClientRect(&m_Rect);这几段代码没问题,如果是用从工具条上拖几个控件到窗口上用这段代码没有任何问题.

    如果用在代码创建的控件上就有问题了.


    xiao
    2011年6月1日 6:26
  • pWnd = GetDlgItem(IDC_MOVE);
    if(pWnd)
    {
    CRect Rect;
    pWnd->GetWindowRect(&Rect);
    ScreenToClient(&Rect);
    /*
    Rect.left = Rect.left*cx/m_Rect.Width(); //有下面的四行代码就不能显示窗口
    Rect.right = Rect.right*cx/m_Rect.Width();
    Rect.top = Rect.top*cy/m_Rect.Height();
    Rect.bottom = Rect.bottom*cy/m_Rect.Height();
    */
    pWnd->MoveWindow(Rect);
    }
    GetClientRect(&m_Rect);这几段代码没问题,如果是用从工具条上拖几个控件到窗口上用这段代码没有任何问题.

    如果用在代码创建的控件上就有问题了.


    xiao
    这个您需要Debug下调试一下啊!看看Rect的值具体是多少?

    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.
    • 已标记为答案 wh_xiao 2011年6月3日 8:29
    2011年6月2日 0:01
    版主
  • 程序运行到Rect.left = Rect.left*cx/m_Rect.Width();

    调试m_Rect的值为:

    top = -842150451    bottom = -842150451

    left = -852150451    right = -842150451   四个值全一样真是奇怪

     

    Rect的值:

    0x0012e9c0 {top = 10   bottom = 30   left = 10  right = 100}

     

    再运行就提示出错信息:0x0000094:integer  divide  by  zero;

     

     


    xiao
    2011年6月2日 13:35
  • 您代码中if语句之后的GetClientRect(&m_Rect);是不是应该放到if语句里面呢?like this:
    pWnd = GetDlgItem(IDC_MOVE);
    
    if(pWnd)
    
    {
    
    CRect Rect;
    
    pWnd->GetWindowRect(&Rect);
    
    ScreenToClient(&Rect);
    
    
    
    GetClientRect(&m_Rect);
    
    
    
    Rect.left = Rect.left*cx/m_Rect.Width(); //有下面的四行代码就不能显示窗口
    
    Rect.right = Rect.right*cx/m_Rect.Width();
    
    Rect.top = Rect.top*cy/m_Rect.Height();
    
    Rect.bottom = Rect.bottom*cy/m_Rect.Height();
    
    pWnd->MoveWindow(Rect);
    
    }
    


    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.
    2011年6月3日 0:16
    版主
  • void CVView::OnSize(UINT nType, int cx, int cy)
    {
     CFormView::OnSize(nType, cx, cy);
     
     // TODO: Add your message handler code here
     pWnd = GetDlgItem(IDC_MOVE);
     if(pWnd)
     {
      CRect Rect;
      pWnd->GetWindowRect(&Rect);
      ScreenToClient(&Rect);
      
      Rect.left = Rect.left*cx/m_Rect.Width();
      Rect.right = Rect.right*cx/m_Rect.Width();
      Rect.top = Rect.top*cy/m_Rect.Height();
      Rect.bottom = Rect.bottom*cy/m_Rect.Height();
     
      pWnd->MoveWindow(Rect);
     }
     GetClientRect(&m_Rect);

    }

     

    无论怎样结果都一样,OnSize函数是响应WM_SIZE消息的,程序在初始化和窗口显示的时候会投递WM_SIZE消息,我估计是在初始化的时候出问题.


    xiao
    2011年6月3日 2:26
  • 您的代码是放在OnSize函数中的,这样您可以设置一个BOOL标记,在View类的OnInitialUpdate最后return之前设置为TRUE,默认为FALSE。在OnSize中先判断一下,然后加上上面的代码.

    void CVView::OnSize(UINT nType, int cx, int cy) 
    
    {
    
     CFormView::OnSize(nType, cx, cy);
    
     
    
     // TODO: Add your message handler code here
    
     if(m_bCreate) // m_bCreate为BOOL类型的变量,默认为FALSE,OnInitialUpdate中最后return之前设置为TRUE
    
     {
    
     pWnd = GetDlgItem(IDC_MOVE);
    
     if(pWnd)
    
     {
    
     GetClientRect(&m_Rect);
    
    
    
     CRect Rect;
    
     pWnd->GetWindowRect(&Rect);
    
     ScreenToClient(&Rect);
    
     
    
     Rect.left = Rect.left*cx/m_Rect.Width();
    
     Rect.right = Rect.right*cx/m_Rect.Width();
    
     Rect.top = Rect.top*cy/m_Rect.Height();
    
     Rect.bottom = Rect.bottom*cy/m_Rect.Height();
    
     
    
     pWnd->MoveWindow(Rect);
    
     }
    
     }
    
    }
    
    
    
    
    
    

     

     


    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.
    2011年6月3日 3:37
    版主
  • 要用这种方法,:

    if(m_btn.GetSafeHwnd())
     {
      CRect Rect;
      m_btn.GetWindowRect(&Rect);
      ScreenToClient(&Rect);
      m_btn.SetWindowPos(NULL, 4, Rect.top, cx-30, cy-Rect.top-50, SWP_NOACTIVATE|SWP_NOZORDER );
     }

    这里的计算是一件有点烦的工作.


    xiao
    • 已标记为答案 wh_xiao 2011年6月3日 8:21
    2011年6月3日 8:21