IDC_EDIT6是我视图(class CMyView : public CFormView)里面的一个编辑控件
pEdit6 我定义在视图头文件中 CEdit* pEdit6
我在OnInitialUpdate中已经初始化了pEdit
pEdit6 = (CEdit*)GetDlgItem(IDC_EDIT6)
但是在程序函数中用时为什么连接不到编辑控件,如果在所用的函数中再赋下值
pEdit6 = (CEdit*)GetDlgItem(IDC_EDIT6)就可以了
请问谁知道哪出问题了,谢谢因为我程序中有若干个编辑控件,而且程序中有很多函数要和这些控件打交道,如果每个函数里面都重复调用
pEdit1 = (CEdit*)GetDlgItem(IDC_EDIT61)
jhh

解决方案 »

  1.   

    如果每个函数里面都重复调用
    pEdit1 = (CEdit*)GetDlgItem(IDC_EDIT1)
    pEdit2 = (CEdit*)GetDlgItem(IDC_EDIT2)
    pEdit3 = (CEdit*)GetDlgItem(IDC_EDIT3)
    ....
    就太麻烦了
      

  2.   

    我这跟用Class Wizard不一样吗
      

  3.   

    如果是多视图的话你调用了OnInitialUpdate了么,跟踪到OnInitialUpdate里看看
      

  4.   

    如果是多视图的话你调用了OnInitialUpdate了么,跟踪到OnInitialUpdate里看看
    ---------------------
    我的是单视图啊
      

  5.   

    GetDlgItem 返回的指针不能长期保留. 只能临时用用,所以你的方法不对,一定要关联 一个 对象.可以定义一个CEdit 类型的成员变量, 然后在InitialUpdate里 对控件进行子类化:m_edit6.SubclassDlgItem(IDC_EDIT6, this);
      

  6.   

    GetDlgItem 返回的指针不能长期保留. 只能临时用用,所以你的方法不对,一定要关联 一个 对象.可以定义一个CEdit 类型的成员变量, 然后在InitialUpdate里 对控件进行子类化:m_edit6.SubclassDlgItem(IDC_EDIT6, this);
    --------------------------
    按照你的可以了,
    定义一个CEdit 类型的成员变量, 然后在InitialUpdate里 对控件进行子类化后
    我再在OnInitialUpdate中初始化pEdit
    pEdit6 = (CEdit*)GetDlgItem(IDC_EDIT6)
    pEdit6 就可以在其他函数中用了
    为什么这个时候GetDlgItem 返回的指针能长期保留
      

  7.   

    GetDlgItem 返回的指针在什么情况下才可以长期保留
      

  8.   

    CWnd* CWnd::GetDlgItem(int nID) const
    {
    ASSERT(::IsWindow(m_hWnd)); if (m_pCtrlCont == NULL)
    return CWnd::FromHandle(::GetDlgItem(m_hWnd, nID));
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    else
    return m_pCtrlCont->GetDlgItem(nID);
    }CWnd* PASCAL CWnd::FromHandle(HWND hWnd)
    {
    CHandleMap* pMap = afxMapHWND(TRUE); //create map if not exist
    ASSERT(pMap != NULL);
    CWnd* pWnd = (CWnd*)pMap->FromHandle(hWnd);
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#ifndef _AFX_NO_OCC_SUPPORT
    pWnd->AttachControlSite(pMap);
    #endif ASSERT(pWnd == NULL || pWnd->m_hWnd == hWnd);
    return pWnd;
    }
    CObject* CHandleMap::FromHandle(HANDLE h)
    {
    ASSERT(m_pClass != NULL);
    ASSERT(m_nHandles == 1 || m_nHandles == 2); if (h == NULL)
    return NULL; CObject* pObject = LookupPermanent(h); //查找永久的
    if (pObject != NULL)
    return pObject;   // return permanent one
    else if ((pObject = LookupTemporary(h)) != NULL) //查找临时的
    {
    HANDLE* ph = (HANDLE*)((BYTE*)pObject + m_nOffset);
    ASSERT(ph[0] == h || ph[0] == NULL);
    ph[0] = h;
    if (m_nHandles == 2)
    {
    ASSERT(ph[1] == h || ph[1] == NULL);
    ph[1] = h;
    }
    return pObject;   // return current temporary one
    }
    ....
    (*m_pfnConstructObject)(pTemp); //创建 //此处添加到临时map里
    // set it in the map
    m_temporaryMap.SetAt((LPVOID)h, pTemp);
    }
    ........ return pTemp;
    }BOOL CWinApp::OnIdle(LONG lCount)
    {
    ....
    {
    VERIFY(!CWinThread::OnIdle(lCount));
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    }
    return lCount < 1;  // more to do if lCount < 1
    }BOOL CWinThread::OnIdle(LONG lCount)
    {
    ........
    }
    else if (lCount >= 0)
    {
    AFX_MODULE_THREAD_STATE* pState = _AFX_CMDTARGET_GETSTATE()->m_thread;
    if (pState->m_nTempMapLock == 0)
    {
    // free temp maps, OLE DLLs, etc.
    AfxLockTempMaps();
    AfxUnlockTempMaps();
    ~~~~~~~~~~~~~~~~~~~
    }
    }#if defined(_DEBUG) && !defined(_AFX_NO_DEBUG_CRT)
    // check MFC's allocator (after idle)
    if (_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) & _CRTDBG_CHECK_ALWAYS_DF)
    ASSERT(AfxCheckMemory());
    #endif return lCount < 0;  // nothing more to do if lCount >= 0
    }
    BOOL AFXAPI AfxUnlockTempMaps(BOOL bDeleteTemps)
    {
    .......
    // clean up temp objects
    pState->m_pmapHGDIOBJ->DeleteTemp();
    pState->m_pmapHDC->DeleteTemp();
    pState->m_pmapHMENU->DeleteTemp();
    pState->m_pmapHWND->DeleteTemp(); //这里删除
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    pState->m_pmapHIMAGELIST->DeleteTemp();
    }
    ........
    }void CHandleMap::DeleteTemp()
    {
    ......
    ASSERT(m_pfnDestructObject != NULL);
    //析构
    (*m_pfnDestructObject)(pTemp); // destruct the object
    } //清除列表
    m_temporaryMap.RemoveAll();       // free up dictionary links etc
    m_alloc.FreeAll(); // free all the memory used for these temp objects
    }
      

  9.   

    上面是mfc的原代码,
    过程是这样的GetDlgItem -> CWnd::FromHandle -> CWnd* pWnd = (CWnd*)pMap->FromHandle(hWnd)
    -> LookupPermanent(h),LookupTemporary(h),m_temporaryMap.SetAt((LPVOID)h, pTemp)
    现在永久窗口map(hwnd 和 CWnd)里找,然后在临时的找,没找到就创建一个CWnd的东东。
    然后是CWinApp::OnIdle -> CWinThread::OnIdle -> AfxUnlockTempMaps -> pState->m_pmapHWND->DeleteTemp() 这里会删除临时创建的CWnd对象。
    这样在FormView的应用程序,就没有办法通过GetDlgItem得到一个确定的CWnd对象,但是hwnd是确定的。
      

  10.   

    可以通过添加变量的方式把hwnd加到永久列表里,先子类化,然后Attach,执行Attach时添加到永久列表
    DDX_Control(pDX, IDC_EDIT1, m_edt);
    void AFXAPI DDX_Control(CDataExchange* pDX, int nIDC, CWnd& rControl)
    {
    if ((rControl.m_hWnd == NULL) && (rControl.GetControlUnknown() == NULL))    // not subclassed yet
    {
    ASSERT(!pDX->m_bSaveAndValidate); pDX->PrepareCtrl(nIDC);
      HWND hWndCtrl;
      pDX->m_pDlgWnd->GetDlgItem(nIDC, &hWndCtrl);
    if ((hWndCtrl != NULL) && !rControl.SubclassWindow(hWndCtrl))
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    .......
    }
    BOOL CWnd::SubclassWindow(HWND hWnd)
    {
    if (!Attach(hWnd))
    ~~~~~~~~~~~~~~~~~~~~~~
    return FALSE;
    ......
    }BOOL CWnd::Attach(HWND hWndNew)
    {
    ..... CHandleMap* pMap = afxMapHWND(TRUE); // create map if not exist
    ASSERT(pMap != NULL);//这里设置
    pMap->SetPermanent(m_hWnd = hWndNew, this);
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~....
    return TRUE;
    }
      

  11.   

    to  xing_xing_xing(未名) 
    你说在FormView的应用程序中没有办法通过GetDlgItem得到一个确定的CWnd对象为什么
    定义一个CEdit 类型的成员变量, 然后在InitialUpdate里 对控件进行子类化后
    我再在OnInitialUpdate中初始化pEdit
    pEdit6 = (CEdit*)GetDlgItem(IDC_EDIT6)
    pEdit6 就可以在其他函数中用了
    这个时候GetDlgItem 返回的不就是一个确定的CWnd对象吗
    我在其他函数中都用这个pEdit6 ,都可以连接到它指向的控件
      

  12.   

    既然有一个 CEdit 对象关联到了这个控件,那么 GetDlgItem(IDC_EDIT6) 返回的就不是临时指针了.那么它的寿命就是返回的那个对象的寿命. 现在你是类里的成员,那么在类对象存在的时候,此控件对象就会一直有效,所以你现在得到的是一个几乎永久的对象指针. 你可以调试代码就能知道,. 在没有对象关联的时候,返回的对象叫 CTempWnd. 而关联到了对象之后, 返回的就是你关联的那个对象呀.理论上是不允许GetDlgItem 这样的函数返回的指针长期保留的,虽然你这里恰好没问题.