我建立了一个mfc的多文档工程,其中子框架的菜单会跳出一个无模式对话框CServerDlg,用于实现网络通信的服务器功能。w网络功能直接由CSocket实现,由CSocket派生两个类CServerSocket和CClientSocket。在CClientSocket的OnReceive函数中需要用到CServerDlg的指针,请问应该怎样添加这个指针?
另外,我要添加CPtrList* m_pClientSocketList;接收socket的指针队列,在CClientSocket的OnReceive函数中用到,请问应在哪添加?
另外,我要添加CPtrList* m_pClientSocketList;接收socket的指针队列,在CClientSocket的OnReceive函数中用到,请问应在哪添加?
当然你也可以在CClientSocket中定义一个它的指针作为成员变量,改一下构造函数在声明对象时将它的指针传递过来.
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遇到问题需要关闭,我们对此引起的不便表示抱歉……
高人快来!
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;
}