看了论坛上很多关于动态改变EDIT控件大小的帖子,基本上都说得很简单,重载WM_SIZE,用GetDlgItem(IDC_EDIT)->MoveWindow(CRect);
可以我用了却不行,我写了一个对话框程序,在对话框上有一个编辑框,我在对话框的OnSize函数里面用MoveWindow,编译没有错误,可每次运行时都要出错,在众多的帖子上没有人说会出错啊,我只好改变了用法,代码如下:
void CTelecomDlg::OnSize(UINT nType, int cx, int cy) 
{
CDialog::OnSize(nType, cx, cy);

// TODO: Add your message handler code here
try
{
GetDlgItem(IDC_RICHEDIT)->MoveWindow(0,0,cx,cy);   
}
catch(...)
{
AfxMessageBox("OnSize fail");
return;   
}
}
每次运行程序时都会出现异常,显示"OnSize fail",以后再改变窗体大小时就不会出现异常,编辑框也正常地动态改变了,进一步跟踪发现,nType的值在每次运行时为0,最小化时为1,最大化时为2,还原时也为0;如果在加一个if( nType != 0 )判断语句,当nType不为0时才执行MoveWindow,那运行时倒是正常了,不会出现异常,可最小化后还原时又来问题了,呵呵,编辑框“不见了”,因为没有执行MoveWindow,看来这样不行。
总结:
在开始运行程序时不应该重载WM_SIZE,和执行MoveWindow,(也不知道对不对,望指正)应该有其它更好的方法解决,我的方法第次都要抛出异常也不是个事啊,明知有异常而不解决就不叫异常了,应该叫错误。
请各位指点一下,谢谢。
(也请各位大虾以后能说得更清楚一点,很容易误导人的,难道是因为这种小问题不是问题?那可苦了我这只菜鸟)

解决方案 »

  1.   

    第一次运行OnSize时,对话框的句柄还没有产生(通过调试可以判断出来),因此,需要先判断m_hWnd是否为空,为空则不处理。
      

  2.   

    如LS 我一般这么写if(m_edit)
    {
    MoveWindow(rect);
    }
      

  3.   

    lxDialog.h文件: ///////////////////////////////////////////////////////////////////////////////////// 
    // 自动改变控件位置和大小的对话框类 
    // 文件名:lxDialog.h 
    // 作者:StarLee([email protected]
    ///////////////////////////////////////////////////////////////////////////////////// class ClxDialog : public CDialog 

    public: 
    ClxDialog(UINT nID, CWnd* pParent = NULL); typedef struct _dlgControlTag  

     int iId; 
     int iFlag; 
     int iPercent; 
    } DLGCTLINFO, *PDLGCTLINFO; enum 

     MOVEX = 0, 
     MOVEY, 
     MOVEXY, 
     ELASTICX, 
     ELASTICY, 
     ELASTICXY 
    }; // 设置控件信息 
    BOOL SetControlProperty(PDLGCTLINFO lp, int nElements); // 是否在对话框右下角显示表示可改变大小的图标 
    void ShowSizeIcon(BOOL bShow = TRUE); protected: 
     virtual BOOL OnInitDialog(); 
     afx_msg void OnSize(UINT nType, int cx, int cy); 
     afx_msg void OnSizing(UINT nSide, LPRECT lpRect); 
     DECLARE_MESSAGE_MAP() private: 
     int m_iClientWidth; // 对话框client区域的宽度 
     int m_iClientHeight; // 对话框client区域的高度 
     int m_iMinWidth; // 对话框的最小宽度 
     int m_iMinHeight; // 对话框的最小高度 
     PDLGCTLINFO m_pControlArray; // 控件信息数组指针 
     int m_iControlNumber; // 设置控件信息的控件个数 
     BOOL m_bShowSizeIcon; // 是否显示表示可改变大小的图标 
     CStatic m_wndSizeIcon; // 放图标的静态控件 
     // 保存图标的bitmap 
     CBitmap m_bmpSizeIcon;  
     BITMAP m_bitmap;  
    }; lxDialog.cpp文件: ////////////////////////////////////////////////////////////////////// 
    // 自动改变控件位置和大小的对话框类 
    // 文件名:lxDialog.cpp 
    // 作者:StarLee([email protected]
    ////////////////////////////////////////////////////////////////////// #include "stdafx.h" 
    #include "lxDialog.h" // 表示可改变大小的图标ID 
    #ifndef OBM_SIZE 
    #define OBM_SIZE 32766 
    #endif ClxDialog::ClxDialog(UINT nID, CWnd* pParent /*=NULL*/) 
    : CDialog(nID, pParent) 
    , m_iClientWidth(0) 
    , m_iClientHeight(0) 
    , m_iMinWidth(0) 
    , m_iMinHeight(0) 
    , m_pControlArray(NULL) 
    , m_iControlNumber(0) 
    , m_bShowSizeIcon(TRUE) 
    {} BEGIN_MESSAGE_MAP(ClxDialog, CDialog) 
     ON_WM_SIZE() 
     ON_WM_SIZING() 
    END_MESSAGE_MAP() BOOL ClxDialog::OnInitDialog() 

     CDialog::OnInitDialog();  // 设置对话框为可变大小的 
     ModifyStyle(0, WS_SIZEBOX);  // 以对话框的初始大小作为对话框的宽度和高度的最小值 
     CRect rectDlg; 
     GetWindowRect(rectDlg); 
     m_iMinWidth = rectDlg.Width(); 
     m_iMinHeight = rectDlg.Height();  // 得到对话框client区域的大小  
     CRect rectClient; 
     GetClientRect(rectClient); 
     m_iClientWidth = rectClient.Width(); 
     m_iClientHeight = rectClient.Height();  // Load图标 
     m_bmpSizeIcon.LoadOEMBitmap(OBM_SIZE); 
     m_bmpSizeIcon.GetBitmap(&m_bitmap);  // 创建显示图标的静态控件并放在对话框右下角 
     m_wndSizeIcon.Create(NULL, WS_CHILD  ¦ WS_VISIBLE  ¦ SS_BITMAP, CRect(0, 0, m_bitmap.bmWidth, m_bitmap.bmHeight), this, 0); 
     m_wndSizeIcon.SetBitmap(m_bmpSizeIcon); 
     m_wndSizeIcon.MoveWindow(m_iClientWidth - m_bitmap.bmWidth, m_iClientHeight - m_bitmap.bmHeight, m_bitmap.bmWidth, m_bitmap.bmHeight);  // 显示图标 
     m_wndSizeIcon.ShowWindow(m_bShowSizeIcon);  return TRUE; 
    } void ClxDialog::OnSize(UINT nType, int cx, int cy)  

     CDialog::OnSize(nType, cx, cy);  // 对话框宽度和高度的增量  
     int iIncrementX = cx - m_iClientWidth; 
     int iIncrementY = cy - m_iClientHeight;  // 最小化时增量为0 
     if (nType == SIZE_MINIMIZED) 
     { 
      iIncrementX = iIncrementY = 0; 
     }  for (int i = 0; i  < m_iControlNumber; i++) 
     { 
      CWnd *pWndCtrl = NULL;   int iId = m_pControlArray[i].iId; 
      int iFlag = m_pControlArray[i].iFlag; 
      int iPercent = m_pControlArray[i].iPercent;   // 无效值 
      if ((iPercent  < 0)  ¦ ¦ (iPercent > 100)) 
       continue;   // 得到控件指针 
      pWndCtrl = GetDlgItem(iId); 
      if ((NULL != pWndCtrl) && IsWindow(pWndCtrl->GetSafeHwnd())) 
      { 
       CRect rectCtrl; 
       pWndCtrl->GetWindowRect(rectCtrl);    ScreenToClient(rectCtrl);    int iLeft = rectCtrl.left; 
       int iTop = rectCtrl.top; 
       int iWidth = rectCtrl.Width(); 
       int iHeight = rectCtrl.Height();    switch (iFlag) 
       { 
        case MOVEX: // X方向移动 
         iLeft += (iIncrementX * iPercent / 100); 
         break;     case MOVEY: // Y方向移动 
         iTop += (iIncrementY * iPercent / 100); 
         break;     case MOVEXY: // X方向和Y方向同时移动 
         iLeft += (iIncrementX * iPercent / 100); 
         iTop += (iIncrementY * iPercent / 100); 
         break;     case ELASTICX: // X方向改变大小 
         iWidth += (iIncrementX * iPercent / 100); 
         break;     case ELASTICY: // Y方向改变大小 
         iHeight += (iIncrementY * iPercent / 100); 
         break;     case ELASTICXY: // X方向和Y方向同时改变大小 
         iWidth += (iIncrementX * iPercent / 100); 
         iHeight += (iIncrementY * iPercent / 100); 
         break;     default: 
         ; 
       }    // 把控件移动到新位置 
       pWndCtrl->MoveWindow(iLeft, iTop, iWidth, iHeight); 
      } 
     }  // 把图标移动到对话框右下角 
     if (IsWindow(m_wndSizeIcon.GetSafeHwnd())) 
      m_wndSizeIcon.MoveWindow(cx - m_bitmap.bmWidth, cy - m_bitmap.bmHeight, m_bitmap.bmWidth, m_bitmap.bmHeight);  // 记录对话框client区域的大小 
     if (nType != SIZE_MINIMIZED) 
     { 
      m_iClientWidth = cx; 
      m_iClientHeight = cy; 
     } 
    } void ClxDialog::OnSizing(UINT nSide, LPRECT lpRect) 

     CDialog::OnSizing(nSide, lpRect);  // 对话框不能小于初始大小  int iWidth = lpRect->right - lpRect->left; 
     int iHeight = lpRect->bottom - lpRect->top;  if (iWidth  <= m_iMinWidth) 
      lpRect->right = lpRect->left + m_iMinWidth;  if(iHeight  <= m_iMinHeight) 
      lpRect->bottom = lpRect->top + m_iMinHeight; 
    } BOOL ClxDialog::SetControlProperty(PDLGCTLINFO lp, int nElements) 

     // 设置控件数组信息  if (NULL == lp) 
      return FALSE;  if (nElements  <= 0) 
      return FALSE;  m_pControlArray = lp; 
     m_iControlNumber = nElements;  return TRUE; 
    } void ClxDialog::ShowSizeIcon(BOOL bShow /*=NULL*/) 

     m_bShowSizeIcon = bShow; 
    } http://blog.csdn.net/scq2099yt/archive/2008/03/12/2174124.aspx 
      

  4.   

    一楼大侠说的很清楚了基本上都说得很简单,重载WM_SIZE,用GetDlgItem(IDC_EDIT)->MoveWindow(CRect); 
    在MoveWindow前要加个窗口是否创建的判断,因为窗口创建前有一次WM_SIZE消息的响应,这时候GetDlgItem返回肯定空
      

  5.   

    收到,谢谢各位
    在MoveWindow前要加个窗口是否创建的判断
    要是以前的帖子都有这句话,我这个菜鸟也不用再开这个帖了
      

  6.   

    if( GetDlgItem(IDC_RICHEDIT) )
        GetDlgItem(IDC_RICHEDIT)->MoveWindow(10, 10, cx-20, cy-20);
      

  7.   

    if( this->m_hWnd )
        GetDlgItem(IDC_RICHEDIT)->MoveWindow(10, 10, cx-20, cy-20);
    这种方法好像不行,第一次运行时this->m_hWnd就不为空了
      

  8.   


    当然不行,因为this是EDIT控件的父窗口的指针,而不是EDIT控件的指针,EDIT控件的指针是GetDlgItem(IDC_RICHEDIT).