91options->proxy[i]=networkDlg.proxyInfo[i];
92}
93}
此方法传入两个结构IcqUser和IcqOption以上有说明
第56行到第61行,主要给qid赋值,modeDlg.m_mode如选中新申请一个QQ号则为0,选中已有QQ号为1,本情景为0,也就是将info->qid=qid;qid是IcqWindow的一个公有变量QIDqid
classQID{
public:
QID(){
uin=0;
}
booloperator==(constQID&qid){
return(uin==qid.uin&&!
strcasecmp(domain.c_str(),qid.domain.c_str()));
}
boolisAdmin(){
return(uin==ADMIN_UIN&&domain.empty());
}
char*toString();
boolparse(constchar*qid);
uint32uin;
stringdomain;
};
剩下的代码就是根据这几个对话框所添入的东东给全局变量icqLink中的IcqUser和IcqOption的各成员变量赋值.
回到RegFinishDlg:
:
OnSetActive()中第208行开始,
208wiz->qid.uin=0;
209
210CStringstr;
211str.LoadString(IDS_PLEASE_WAIT);
212SetDlgItemText(IDC_STATUS,str);
213str.LoadString(IDS_REG_REGISTERING);
214SetDlgItemText(IDC_STATUS_DETAIL,str);
215wiz->SetWizardButtons(PSWIZB_DISABLEDFINISH);
216
217m_faceLabel.start();
218
219resolveHost();
220
221returnCPropertyPage:
:
OnSetActive();
}
这行将MyIcq号赋为0,211-218设置一些状态,219进入CRegFinishDlg:
:
resolveHost()
voidCRegFinishDlg:
:
resolveHost()
{
172 CRegWizard*wiz=(CRegWizard*)GetParent();
173 constchar*host=wiz->networkDlg.m_host;
174
175 if(wiz->networkDlg.m_useProxy&&!
wiz->networkDlg.m_proxyResolve)
176 getUdpSession()->connect(host,wiz->networkDlg.m_port);
177 else{
178 structin_addraddr;
179 addr.s_addr=inet_addr(host);//将x.x.x.x转换为无符号整数给addr.s_addr
180 if(addr.s_addr!
=INADDR_NONE)
181 onHostFound(addr);
182 else
183 ((CIcqDlg*)AfxGetMainWnd())->getHostByName(host);
}
}
175行看出在网络设置对话框中有没有选使用代理服务器,本情景中没选到178行将用户选定的地址作为参数传给onHostFound(addr);进入onHostFound
voidCRegFinishDlg:
:
onHostFound(structin_addr&addr)
{
163 if(addr.s_addr!
=INADDR_NONE){
164 CRegWizard*wiz=(CRegWizard*)GetParent();
165 getUdpSession()->connect(inet_ntoa(addr),wiz->networkDlg.m_port);
166 }else
167 onTimeout();
}
在165行调用函数getUpdSession()->connect传入参数是用户输入的地址和端口。
inlineUdpSession*getUdpSession()
{
returnicqLink->udpSession;
}
voidUdpSession:
:
connect(constchar*host,uint16port)
{
090 IcqOption&options=icqLink->options;
091
092 //Connectusingproxy
093 if(options.flags.test(UF_USE_PROXY)){
094 if(options.proxyType==PROXY_SOCKS)
095 socksProxy.start(options.proxy[PROXY_SOCKS],sock);
096 elseif(options.proxyType==PROXY_HTTP)
097 httpProxy.start(host,options.proxy[PROXY_HTTP]); }
099 else{ //notuseproxy
100 sockaddr_inaddr;
101 socklen_tlen=sizeof(addr);
103 memset(&addr,0,sizeof(addr));
104 addr.sin_family=AF_INET;
105 addr.sin_port=htons(port);
106 addr.sin_addr.s_addr=inet_addr(host);
107 :
:
connect(sock,(sockaddr*)&addr,len);
109 getsockname(sock,(sockaddr*)&addr,&len);
110 realIP=ntohl(addr.sin_addr.s_addr);
112 icqLink->onConnect(true);
}
}
首先判断有没有用proxy本情景中没有用所以到100行调用几个SOCKET函数连接传入的服务器及端口,将真实IP存放在realIP中,然后调用icqLink->onConnect(true);这个函数是一个虚函数,
CicqDlg类改写了它,所以程序进入CIcqDlg:
:
onConnect
voidCIcqDlg:
:
onConnect(boolsuccess)
{
292IcqWindow*win=findWindow(WIN_REG_WIZARD);
进入findWindow
IcqWindow*IcqLink:
:
findWindow(inttype,QID*qid,uint32seq)
{
PtrList:
:
iteratorit;
for(it=windowList.begin();it!
=windowList.end();++it){
IcqWindow*win=(IcqWindow*)*it;
if(win->type==type&&(!
qid||win->qid==*qid)
&&(seq==0||win->seq==seq))
returnwin;
}
returnNULL;
}
接上程序
293if(win){
294 ((CRegWizard*)win)->onConnect(success);
295 return;
296}
........}
本情景中WIN_REG_WIZARD存在所以进入((CRegWizard*)win)->onConnect(success);
voidonConnect(boolsuccess){
finishDlg.onConnect(success);
}
voidCRegFinishDlg:
:
onConnect(boolsuccess)
{
148 if(success){
149 CRegWizard*wiz=(CRegWizard*)GetParent();
150 if(wiz->modeDlg.m_mode==0)
151 wiz->seq=getUdpSession()->regNewUIN(wiz->basicDlg.m_passwd);
152 else{
153 icqLink->myInfo.qid.uin=wiz->modeDlg.m_uin;
wiz->seq=getUdpSession()->login(wiz->modeDlg.m_passwd,STATUS_OFFLINE);
155 }
156 }else
157 onTimeout();
}
modeDlg.m_mode如选中新申请一个QQ号则为0,选中已有QQ号为1,本情景为0所以到151行
uint16UdpSession:
:
regNewUIN(constchar*passwd)
{
001 initSession();
002 UdpOutPacket*out=createPacket(UDP_NEW_UIN);
003 *out< 004 returnsendPacket(out);
}
先看001regNewUIN主要功能是注册一个新ID,
voidUdpSession:
:
initSession()
{
161sid=(rand()&0x7fffffff)+1; //将sid初值赋值为随机数
162sendSeq=(rand()&0x3fff);
163retryKeepAlive=0;
164sessionCount=0;
165
166memset(window,0,sizeof(window));
167
168clearSendQueue(); //清空发送队列
}
再看002
(1)UdpOutPacket*UdpSession:
:
createPacket(uint16cmd)
{
UdpOutPacket*p=newUdpOutPacket;
p->cmd=cmd;
p->seq=++sendSeq;
createPacket(*p,cmd,sendSeq);
returnp;
}
(2)voidUdpSession:
:
createPacket(UdpOutPacket&out,uint16cmd,uint16seq)
{
out<<(