本帖最后由 hio131 于 2012-01-22 12:11:49 编辑

解决方案 »

  1.   

    这个问题只在动态创建控件时出现
    CXButton btn;//CXButton是自定义按钮类
        btn.Create((LPCTSTR)szCaption,dwStyle,rct,this,10001);
        btn.ShowWindow(SW_SHOW);btn是个局部变量,函数结束后就不存在了,也不显示了,当然问题一大堆
      

  2.   

    我这么写只是做实验方便  事实上到PreSubclassWindow时Create还没有返回
      

  3.   

    只要是用Create生成的  就会出现上述问题,就算定义一个成员指针m_ptrBtn m_ptrBtn = new CXButton;
    m_ptrBtn.Create(...)也是不行的如果new的是CButton程序可以正常运行
      

  4.   

    如果new的是CButton程序可以正常运行
      

  5.   

    你的 btn对象是个局部变量, 函数执行完后当然什么都不剩了,所以也就没显示出来,它只显示了很短暂的一瞬间
      

  6.   


    -执行到PreSubclassWindow时Create还没返回-只要是手动用Create创建的就不行 if (bIsCreated == FALSE)
    { CString szCaption(_T("Button"));
    CRect rct;
    m_btnOK.GetWindowRect(&rct);
    DWORD dwStyle = m_btnOK.GetStyle();
    m_pNewBtn = new CButton;//CButton没问题,CXButton在PreSubclassWindow中不能获得rect,也无法自绘
    m_pNewBtn->Create((LPCTSTR)szCaption,dwStyle,rct,this,100001);//复制OK按钮的属性
                    m_pNewBtn->ShowWindow(SW_SHOW);
    bIsCreated = TRUE;
    return;
    }
    m_pNewBtn->MoveWindow(0,0,100,100);//无问题
      

  7.   

    "而且这个问题只在动态创建控件时出现,如果定义为成员,上述代码都能正确获得信息"
    因为定义为成员时,初始化(Create)已由windows完成。
      

  8.   

    看6楼第一次执行时create一个按钮,第二次以后只是movewindow   这是可以正常执行的  new出来的对象在函数结束时不会销毁但同样一段代码  把注释位置的CButton换成CXButton在CXButton内部就无法得到Rect  GetWindowText也不行
      

  9.   

    你问的是“void CXButton::PreSubclassWindow()”
    有没有从CButton 直接继承一个 类试试 ?
    估计同样不行。
      

  10.   


    CXButton是从CButton继承来的啊
      

  11.   

    现在的问题是
    //TDlg.hclass CTDlg : public CDialog
    {
    //...
    CButton m_Btn1;//DDX绑定,正常
    CXButton m_Btn2;//DDX绑定,CXButton成员函数中可正常获得rect和WindowText
    CButton *m_pBtn3;//动态生成,正常
    CXButton *m_pBtn4;//动态生成,异常
    BOOL bIsCreated;//构造函数中被初始化为FALSE
    //...
    }//TDlg.cpp
    void CTDlg::OnBnClickedOk()
    {
    if (bIsCreated == FALSE)
    {
    CString szCaption(_T("Button"));
    CRect rct(0,0,60,60);
    DWORD dwStyle = m_btnOK.GetStyle();
    m_pBtn3 = new CButton;
    m_pBtn3->Create((LPCTSTR)szCaption,dwStyle,rct,this,100001);
                    //m_pBtn3的动态创建,正常,换成m_pBtn4,在CXButton的成员函数中无法获得rect和WindowText
    m_pBtn3->ShowWindow(SW_SHOW);
    bIsCreated = TRUE;
    return;
    }
    m_pBtn3->MoveWindow(0,0,100,100);//正常,pBtn3所指对象没被销毁
    return;
    }
      

  12.   


    再补充一下void CXButton::PreSubclassWindow()
    {
    CButton::PreSubclassWindow();
    CRect rct;
    this->GetWindowRect(rct);//空
    CString szCaption;
    this->GetWindowText(szCaption);//空
    DWORD dwStyle = this->GetStyle();//传入的dwStyle
    CString szTemp;
    szTemp.Format(_T("Caption:%s\tRect:top=%dleft=%dbottom=%dright=%d\tStyle:%d"),szCaption,rct.top,rct.left,rct.bottom,rct.right,dwStyle);
    ::MessageBox(NULL,szTemp,_T("E"),MB_OK);//应用程序异常,调试会发现是一个断言,AfxMessageBox一样
    }
      

  13.   

    按你的目的,可以放:
    void CXButton::OnSize(UINT nType, int cx, int cy) 
      

  14.   


    这只是测试  我是在自绘时发现的  在DrawItem里无法获得正确的rect和caption,后来发现在presubclasswindow里也不行
      

  15.   

    在“DrawItem里无法获得正确的rect和caption”不会有问题吧?这时窗口已产生。
    是没有还是不正确?
      

  16.   

    我觉得问题说的挺清楚的了啊………… 
    没办法了  求代码吧……  只要动态创建出来的按钮能在presubclasswindow和drawitem中获得正确的信息就好
      

  17.   

    CXPButton里不是有代码吗?
    void CXPButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
    {
    // TODO: Add your code to draw the specified item

    CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
    CRect rect = lpDrawItemStruct->rcItem;
    UINT state = lpDrawItemStruct->itemState;
    CPoint pt;
    CString strText;
    CString &m_title = strText;
    GetWindowText(strText);
      

  18.   

    我晕  看来你没看清楚  这个CXButton是我自己准备写的 - -   不是CXPButton
      

  19.   

    - - 光复制是没用的 代码就摆在那 GetWindowText就是拿不到  我有什么办法? 我实在搞不懂才来问的
      

  20.   

    我用的VS05调试了一下  静态按钮不是用CWnd::Create来创建的,而是由MFC自己调用了API,CWnd::Create的处理流程似乎不太一样而且我试了,在presubclasswindow中,动态创建的按钮无法正确获得父窗口,用GetParent得到的窗口类,句柄是查不到的(SPY++)不知道为什么。
    -----------------------------------------------
    CRgn r;
    r.CreateRectRgn(/*355*/30,30,1000,1000);//(屏幕坐标)对话框左103,按钮左222,再偏移30  是355
    SetWindowRgn(r, TRUE);我用这三行代码测试,动态创建的按钮CreateRectRgn坐标是屏幕坐标,静态按钮用的是按钮的窗口坐标似乎跟映射模式之类的有关系……?  我实在有些搞不懂了现在我先判断按钮是动态创建的还是静态创建的,如果动态的就从Create中获得Rect  勉强也达到了效果  不过这个问题到底是没解决啊
      

  21.   

    因为你用的VS5,我是VC6。不过我想不会差这么多。你不能传代码。就帮不了你了。