我建立了一个mfc的多文档工程,其中子框架的菜单会跳出一个无模式对话框CServerDlg,用于实现网络通信的服务器功能。w网络功能直接由CSocket实现,由CSocket派生两个类CServerSocket和CClientSocket。在CClientSocket的OnReceive函数中需要用到CServerDlg的指针,请问应该怎样添加这个指针?
另外,我要添加CPtrList* m_pClientSocketList;接收socket的指针队列,在CClientSocket的OnReceive函数中用到,请问应在哪添加?

解决方案 »

  1.   

    声明CServerDlg的全局指针算了;
    当然你也可以在CClientSocket中定义一个它的指针作为成员变量,改一下构造函数在声明对象时将它的指针传递过来.
      

  2.   

    全局指针用过了,我在ServerDlg.h中定义CPtrList* m_pClientSocketList;     在ServerDlg.cpp中定义CServerDlg*  g_DlgServer;
    CServerDlg::CServerDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CServerDlg::IDD, pParent)
    {
    ...
    g_DlgServer=this;//g_DlgServer指针指向
    m_pClientSocketList = new CPtrList();//初始化socket链表
    }
    void CClientSocket::OnReceive(int nErrorCode) //重载函数OnReceive
    {
    // TODO: Add your specialized code here and/or call the base class
    Message m_Message;
    memset(&m_Message,0,sizeof(m_Message));//存储单元先清零
    Receive(&m_Message,sizeof(m_Message));//接收消息 CString strUserName=m_Message.strName;//获取发送者用户名称 if(m_Message.iType==FIRSTLOG)//如果用户首次登陆,添入socket链表
    {
    CPtrList* m_pClientList=g_DlgServer->m_pClientSocketList;//Socket链表
     
    int iCount=m_pClientList->GetCount();//获得链表节点个数
    POSITION pos=m_pClientList->GetHeadPosition();//获得首节点
    if(pos)//如果链表非空
    {
    //遍历socket链表检查用户名是否存在,如果已经存在,则发送一个
    //服务器信息给试图登陆的用户,通知用户名已存在
    for(int i=0;i<m_pClientList->GetCount();i++)
    {
    CClientSocket* m_pClientSocket=static_cast<CClientSocket*>(m_pClientList->GetNext(pos));
    if(m_pClientSocket->GetUserName()==strUserName)//用户名已存在
    {
    //组织发送给用户的消息
    Message msObj;
    memset(&msObj,0,sizeof(Message));//消息先清零
    msObj.iType=SYSERROR;//设置消息属性,用户已存在
    msObj.iSubType=USEREXSIT;
    m_pClientSocket->Send(&msObj,sizeof(Message));
    return;
    }
    else//用户名不存在,不管整个遍历过程结束能否找到该用户名,依次将所有链表指针
    {   //的用户名发送给即将登陆的用户
    //组织发送给用户的消息
    Message msObj1;
    memset(&msObj1,0,sizeof(Message));//消息先清零
    msObj1.iType=USERLOG;//设置消息属性,用户登陆
    msObj1.iSubType=USERLOGIN;
    CString strTemp;
    strTemp=m_pClientSocket->GetUserName();//获得节点的用户名
    int len=strTemp.GetLength();//用户名长度
    lstrcpy(msObj1.strName,strTemp.GetBuffer(len));//将节点的用户名发送给登陆用户
    m_pClientSocket->Send(&msObj1,sizeof(Message));
    } }
    }
            g_DlgServer->m_pClientSocketList->AddTail(this);
    iCount=m_pClientList->GetCount();//获得新链表节点数
    pos=m_pClientList->GetHeadPosition();//获得首节点
    if(pos)//把新登陆用户的用户名依次发送给各在线用户
    {
    for(int i=0;i<m_pClientList->GetCount();i++)
    {
    CClientSocket* m_pClientSocket=static_cast<CClientSocket*>(m_pClientList->GetNext(pos));
    m_Message.iType=USERLOG;
    m_Message.iSubType=USERLOGIN;
      m_pClientSocket->Send(&m_Message,sizeof(Message));
    }
    }
    .
    .
    .
    .
    }
    但调试中发现m_pClientSocketList添加有问题
    还有,原本我用的是模式对话框,程序中添加的ODBC数据库操作没问题,改成无模式的后,若数据库中数据为空,则进行数据记录清空操作操作就会出现   ***.exe遇到问题需要关闭,我们对此引起的不便表示抱歉……
    高人快来!
      

  3.   

    父对话框发送消息给子对话框
    1,定义一个Handle全局变量HWND  hwndChartDlg;
    2,在生成子对话框时取得无模式对话框的句柄赋给Handle全局变量
    //无模式对话框
    CChartDlg *pDlg=new CChartDlg;
    pDlg->Create(IDD_DIALOG_CHART,this);
    pDlg->ShowWindow(SW_SHOW);
    // pDlg->PostMessage(WM_COMMMESSAGE,1,1); //pDlg是局部变量,不能用在其它地方
    hwndChartDlg=pDlg->GetSafeHwnd(); //取得无模式对话框的句柄赋给Handle全局变量
    3,在主对话框的任意地方都可以用API函数给无模式对话框发送自定义的用户消息
    ::PostMessage(hwndChartDlg,WM_COMMMESSAGE,1,1); // hwndChartDlg为目标对话框句柄
    4,在子对话框的头文件要定义自定义的用户消息
      #define WM_COMMMESSAGE WM_USER+100 //自定义的用户消息
    5, 在子对话框的头文件定义消息映射函数
    //{{AFX_MSG(CChartDlg)
    virtual void OnCancel();
    virtual BOOL OnInitDialog();
    virtual void OnOK();
    //}}AFX_MSG
      LRESULT OnCommMessage(WPARAM wParam, LPARAM lParam);
    DECLARE_MESSAGE_MAP()
    6, 在子对话框的CPP文件中声明响应消息:
    BEGIN_MESSAGE_MAP(CChartDlg, CDialog)
    //{{AFX_MSG_MAP(CChartDlg)
    //}}AFX_MSG_MAP
    ON_MESSAGE(WM_COMMMESSAGE,OnCommMessage)
        END_MESSAGE_MAP()
    7, 在子对话框的CPP文件中添加消息响应函数
        LRESULT CChartDlg::OnCommMessage(WPARAM wParam, LPARAM lParam)
    {
    AfxMessageBox("Received message!");
    return 0;
    }