子类化控件出错, 对话框上有个ListCtrl控件,与这个控件关联的是:class CAccelList : public CListCtrl出事对话框函数中:
BOOL CTestDlg::OnInitDialog()
{
CDialog::OnInitDialog(); m_ctrlList.SubclassDlgItem(IDC_LIST1, this);   //这一句出错,跟进去
//跟到BOOL CWnd::SubclassWindow(HWND hWnd)就异常
// Set the icon for this dialog.  The framework does this automatically
//  when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here

return TRUE;  // return TRUE  unless you set the focus to a control
}
异常为:
BOOL CWnd::SubclassWindow(HWND hWnd)
{
if (!Attach(hWnd))
return FALSE;   //这里有问题CAccelList类中有两个CComboBox控件class CAccelList : public CListCtrl
{
public:
CComboBox  m_boxName;   
CComboBox  m_boxNum;   
..........
protected:
virtual void PreSubclassWindow();
virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);protected:
//{{AFX_MSG(CAccelList)
afx_msg void OnPaint();
afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
afx_msg void OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct);
//}}AFX_MSG DECLARE_MESSAGE_MAP()};void CAccelList::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
// TODO: Add your message handler code here and/or call default
CListCtrl::OnDrawItem(nIDCtl, lpDrawItemStruct);
}
void CAccelList::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct) 
{
CListCtrl::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
}
void CAccelList::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
 lpMeasureItemStruct->itemHeight = 300;     //行高}
void CAccelList::PreSubclassWindow() 
{
// TODO: Add your specialized code here and/or call the base class
//自类化ComboBox控件 //发送消息给自己CRect rcWin;
GetWindowRect(&rcWin);
WINDOWPOS wp;
wp.hwnd = m_hWnd;
wp.cx = rcWin.Width();
wp.cy = rcWin.Height();
wp.flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER;
SendMessage(WM_WINDOWPOSCHANGED, 0, (LPARAM)&wp); char* pszText[]={"姓名","学号","性别"};
LVCOLUMN lvc = {LVCF_FMT | LVCF_TEXT | LVCF_WIDTH}; int cx[]={100,100,100};      SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);        //第三步:设置列 
for(int i=0;i<sizeof(cx)/sizeof(int);i++)
{ lvc.pszText = pszText[i];
lvc.cx = cx[i];
lvc.fmt = LVCFMT_CENTER; InsertColumn(i,&lvc);
} // 动态创建姓名一列 m_boxName.Create(WS_CHILD | WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST ,CRect(0, 17, 100, 97),this,IDD_COMBOXNAME); m_boxName.AddString(_T("张三")); m_boxName.AddString(_T("李四")); m_boxName.SetCurSel(0);   m_boxName.ShowWindow(SW_SHOW);   ////////////////////////////////////////
    // 动态创建学号一列 m_boxNum.Create(WS_CHILD | WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST ,CRect(100, 17, 200, 80),this,IDD_COMBOXNUM); m_boxNum.AddString(_T("001")); m_boxNum.AddString(_T("002"));
m_boxNum.SetCurSel(0);
   m_boxNum.ShowWindow(SW_SHOW);
CListCtrl::PreSubclassWindow();
}

解决方案 »

  1.   

    m_ctrlList.SubclassDlgItem(IDC_LIST1, this); //这一句出错,跟进去
    //跟到BOOL CWnd::SubclassWindow(HWND hWnd)就异常 就是这一句出错 ,什么原因啊?
      

  2.   


    this指针还没用创建完毕,你调用的太早了
      

  3.   

    那我该什么时候创建啊 ?我看别人的代码也是放在 OnInitDlg中  ,
      

  4.   

    _ctrlList.SubclassDlgItem(IDC_LIST1, this); //这一句出错,跟进去
    //跟到BOOL CWnd::SubclassWindow(HWND hWnd)就异常  异常为:
    BOOL CWnd::SubclassWindow(HWND hWnd)
    {
    if (!Attach(hWnd))
    return FALSE; //这里有问题
      

  5.   

    只有一个控件的话,用ddx来定义吧。
      

  6.   

    void CTestDlg::DoDataExchange(CDataExchange* pDX)
    {
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CTestDlg)
    // DDX_Control(pDX, IDC_LIST1, m_ctrlList);
    //}}AFX_DATA_MAP
    }
    我注释掉这一行,就没有问题了, 这是为什么啊??难道  自定义的类,不能用ddx机制
      

  7.   

    BOOL CWnd::SubclassWindow(HWND hWnd)
    {
    }
    这个虚函数就有问题吧?应该是在你绑定的类上。怎么会是CWnd呢?且这个虚函数没有参数吧?
      

  8.   

    m_ctrlList是不是定义了?
    如CCtrList m_ctrlList
    有没有这个成员变量?
      

  9.   

    是的, 我百度了不少帖子后, 尝试了一下,结果还真是这个原因, 很奇怪,为什么自定义的类,不能用ddx机制啊
      

  10.   

    一、子类化功能的提出:
    一个控件的派生类要正常工作,首先定义类对象,这样类的构造函数会执行且生成对象,但还没HWND,这样需CreateWindow(),还要为这个对象调整位置,设置属性等,完全是在隐式状态下进行。这样有些用户会感到不爽,他们提出:如果能把一个调整好的可视化控件与这个类对象关联,这样不是很好吗?为了满足用户的需求,MFC就提供了SubclassDlgItem()和SubclassWindow这两个功能来实现。通常这样做:
    1、定义类对象
    2、需关联的类对象.SubclassDlgItem(要关联的控件ID,其父窗口对象)
      另一种方法:
      需关联的类对象.SubclassWindow(控件的HWND)这样我们可以把可视化控件的位置和属性调整好,再和相应的派生类关联,这样省了不少事。二、首先你应该明白,一个可视的控件,都是有HWND的。
    这样,在执行子类化操作时,MFC就把这个HWND与生成的类对象关联起来。此后因为类对象已经有了HWND,我们不需要再用CreateWindow()来隐式的建立HWND了。所以WM_CREATE消息不会被调用,即OnCreate()不会执行,要想执行一些初始化操作,MFC提供了一个PreSubClassWindow()虚函数,你可以重载,放入你的初始化代码。三、VC中其实经常在子类化的。
    因为VC是一种可视化工具,要想实现可视化功能,就要把可视的控件与存在的类相关联,以便操作这个控件。如果不是为了可视化编辑,我们完全不需要子类化,一切在程序员的脑海里,全用代码来建立、操作和消毁对象。所以为了实现可视化,VC专门做了“建立类向导”->“建立控件变量”的功能来实现子类化功能。你也可以在此进行子类化,而不用这子类化功能函数。经过这个步骤,VC自动在类中生成两段代码:[
    //{{AFX_DATA(CSiceDlg)
    enum { IDD = IDD_SICE_DIALOG };
    CRichEditCtrl  m_info;
    CWargeList  m_wlist;
    //}}AFX_DATAvoid CSiceDlg::DoDataExchange(CDataExchange* pDX)
    {
      CDialog::DoDataExchange(pDX);  //{{AFX_DATA_MAP(CSiceDlg)
      DDX_Control(pDX, IDC_INFO, m_info);
      DDX_Control(pDX, IDC_WAGERLIST, m_wlist);
      //}}AFX_DATA_MAP
    }   第一段是定义对象,第二段是关联到控件ID。四、什么时候用SubclassDlgItem(),什么时候用SubclassWindow()
    你可以这样理解:如果你知道控件ID,就用SubclassDlgItem(),如果你知道了控件的HWND,就用SubclassWindow(),作用是一样的。但你如果只知道控件的HWND,还是只能用SubclassWindow(),而不能用建立类向导->关联控件变量了。
    通过上面的介绍,你知道原因了吧?
      

  11.   

    自定义的类,可以用DDX机制来关联对象。
    如果你做好了类,如:一个派生自CListCtrl的类CMyListCtrl,在建立类向导->成员变量,点击你要关联的ID,建立成员变量,选择种类“控件”,变量类型里会有两个项,CListCtrl、CMyListCtrl,你可选择到CMyListCtrl你的派生类上。
    如果没有,自已加到这两段里://{{AFX_DATA(CSiceDlg)
    enum { IDD = IDD_SICE_DIALOG };
    CMyListCtrl m_mylist;//加到这里
    //}}AFX_DATAvoid CSiceDlg::DoDataExchange(CDataExchange* pDX)
    {
      CDialog::DoDataExchange(pDX);  //{{AFX_DATA_MAP(CSiceDlg)
      DDX_Control(pDX, IDC_MYLIST, m_mylist);//加到这里
      //}}AFX_DATA_MAP
    }  这样就子类化了。当然就不必再SubclassDlgItem()了,会出错的,因为不能子类化一个已经子类化过的对象。这你应该比我还明白了吧?可以结帖了吧?
      

  12.   

    多谢 , 解答我很久的疑惑 ,一直很奇怪,为什么自定义的控件类,需要Create,而 非自定义不需要,原来已经在ddx机制中子类花了
    不知道你能不能再帮个忙,   我昨天看了你的快捷键的代码, 有些不懂之处, 整理成word形式,发到你邮箱里面了现在过节,也不好劳累你。。你哪天有空,帮忙解惑一下,   劳累你了
      

  13.   

    囧 , 我不小心用马甲了(马甲:caddor,caddor2011,  我分数太少, 不能发帖,所以不断的换马甲,真是羞愧
    )你的邮件我刚看到,   很感谢你的回复。 
     节日快乐!!