⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 myicqdlg.cpp

📁 局域网ICQ的源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		}
		break;
	case ALIGN_LEFT:
		yStep = 0;
		yEnd = rc.top;
		if (hide) {
			xStep = -rc.right / moves;
			xEnd = -rc.Width() + 2;
		} else {
			xStep = -rc.left / moves;
			xEnd = 0;
		}
		break;
	case ALIGN_RIGHT:
		yStep = 0;
		yEnd = rc.top;
		cxScreen = GetSystemMetrics(SM_CXSCREEN);
		if (hide) {
			xStep = (cxScreen - rc.left) / moves;
			xEnd = cxScreen - 2;
		} else {
			xStep = (cxScreen - rc.right) / moves;
			xEnd = cxScreen - rc.Width();
		}
		break;
	}

	for (int i = 0; i < moves; i++) {
		rc.left += xStep;
		rc.top += yStep;
		SetWindowPos(NULL, rc.left, rc.top, 0, 0, SWP_NOSIZE | SWP_NOSENDCHANGING);
		RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_ALLCHILDREN);
		Sleep(20);
	}
	SetWindowPos(NULL, xEnd, yEnd, 0, 0, SWP_NOSIZE);

	isHide = hide;
	if (!isHide)
		SetTimer(IDT_HOVER, 50, NULL);
}

void CIcqDlg::addPendingMsg(IcqMsg *msg)
{
	if (msgList.empty())
		SetTimer(IDT_BLINK, 400, NULL);
	if (!msg->isSysMsg() && !findPendingMsg(msg->uin))
		outbarCtrl.blinkImage(msg->uin);

	IcqLink::addPendingMsg(msg);
}

void CIcqDlg::onNewUINReply(uint32 uin)
{
	myInfo.uin = uin;
	IcqWindow *win = findWindow(WIN_REG_WIZARD);
	if (win)
		((CRegWizard *) win)->onNewUINReply(uin);
}

void CIcqDlg::onContactListReply(UinList &l)
{
	IcqWindow *win = findWindow(WIN_REG_WIZARD);
	if (win) {
		uinList = l;
		((CRegWizard *) win)->onContactListReply();
	}
}

void CIcqDlg::onLoginReply(uint16 error)
{
	IcqWindow *win = findWindow(WIN_REG_WIZARD);
	if (win) {
		((CRegWizard *) win)->onLoginReply(error);
		return;
	}

	lastSeq = 0;
	if (error != LOGIN_SUCCESS) {
		KillTimer(IDT_RESEND);
		AfxMessageBox(IDS_WRONG_PASSWD);
		return;
	}

	SetTimer(IDT_KEEPALIVE, KEEPALIVE_TIMEOUT * 1000, NULL);

	myInfo.status = pendingStatus;
	updateStatusIcon();

	if (regMode == 0)
		serverSession()->modifyUser(&myInfo);
	else if (regMode == 1) {
		serverSession()->updateUser();
		while (!uinList.empty()) {
			uint32 uin = uinList.front();
			uinList.pop_front();
			serverSession()->updateContact(uin);
		}
	}
	regMode = -1;
}

void CIcqDlg::onUpdateContactReply(IcqContact *info)
{
	IcqLink::onUpdateContactReply(info);
	
	IcqContact *c = findContact(info->uin);
	if (c) {
		IcqDB::saveContact(*c);
		outbarCtrl.update(c->uin);
	}
	
	IcqWindow *win = findWindow(WIN_VIEW_DETAIL, info->uin, serverSession()->ackseq);
	if (win)
		((CViewDetailDlg *) win)->onUpdateContactReply(info);
}

void CIcqDlg::onUpdateUserReply()
{
	IcqDB::saveUser(myInfo);
}

void CIcqDlg::onUserOnline(uint32 uin, uint32 status, uint32 ip, uint16 port, uint32 realIP, bool multi)
{
	if (status != STATUS_ONLINE && status != STATUS_AWAY)
		return;

	IcqContact *c = findContact(uin, CONTACT_FRIEND);
	if (!c)
		c = addContact(uin);

	c->ip = ip;
	c->port = port;
	c->realIP = realIP;
	c->status = status;
	outbarCtrl.update(uin, TRUE);
	
	if (c->flags.test(CF_OPTION_INVISIBLE))
		OnStatusInvis();
	if (c->flags.test(CF_OPTION_GREETING) && !c->greeting.empty())
		sendMessage(MSG_TEXT, uin, c->greeting.c_str());
	
	if (!multi)
		onlineNotify(c);
}

void CIcqDlg::onUserOffline(uint32 uin)
{
	IcqLink::onUserOffline(uin);

	outbarCtrl.update(uin, TRUE);

	IcqContact *c = findContact(uin);
	if (c && c->flags.test(CF_OPTION_POPUP_OFFLINE)) {
		CString str;
		str.Format(IDS_NOTIFY_OFFLINE, c->nick.c_str(), c->uin);
		new CNotifyWnd(getApp()->largeImageList.ExtractIcon(c->face), str);
	}
}

void CIcqDlg::onStatusChanged(uint32 uin, uint32 status)
{
	if (status != STATUS_ONLINE && status != STATUS_AWAY)
		return;
	
	IcqContact *c = findContact(uin);
	if (c) {
		if (c->status != STATUS_ONLINE && status == STATUS_ONLINE)
			onlineNotify(c);
		c->status = status;
		outbarCtrl.update(uin);
	}
}

void CIcqDlg::onRecvMessage(IcqMsg *msg)
{
	uint8 type = msg->type;
	uint32 from = msg->uin;
	BOOL relay = (msg->flags & MF_RELAY);

	if (type == MSG_AUTH_ACCEPTED) {
		serverSession()->updateContact(from);
		addContact(from);
	}

	IcqContact *c = findContact(from);

	if (!c && !msg->isSysMsg()) {
		int n = outbarCtrl.getFolderCount();
		c = addContact(from, n - 2);
	}

	if (msg->isSysMsg()) {
		options.playSound(SOUND_SYSMSG);
		addPendingMsg(msg);
		IcqDB::saveMsg(*msg);
		return;
	}
	if (!c)
		return;

	if (c->status == STATUS_OFFLINE && !relay) {
		c->status = STATUS_ONLINE;
		outbarCtrl.update(c->uin, TRUE);
	}
	
	options.playSound(SOUND_MSG, c);
	if (type == MSG_TCP_REQUEST) {
		addPendingMsg(msg);
		return;
	}
	IcqDB::saveMsg(*msg);

	// auto reply
	if ((myInfo.status == STATUS_AWAY) &&
		options.flags.test(UF_AUTO_REPLY) &&
		!options.autoReplyText.empty() &&
		type != MSG_AUTO_REPLY)
		sendMessage(MSG_AUTO_REPLY, from, options.autoReplyText.c_str());

	IcqWindow *win;
	if (c->flags.test(CF_DIALOGMODE)) {
		win = findWindow(WIN_SEND_MESSAGE, from);
		if (!win) {
			CSendMsgDlg *pDlg = new CSendMsgDlg(c);
			pDlg->Create(IDD_SEND_MESSAGE);
			win = pDlg;
		}
		((CSendMsgDlg *) win)->onRecvMessage(*msg);
		delete msg;

	} else {
		addPendingMsg(msg);

		win = findWindow(WIN_VIEW_MESSAGE, from);
		if (win)
			((CViewMsgDlg *) win)->onRecvMessage();
		else if (options.flags.test(UF_AUTO_POPUP_MSG)) {
			CViewMsgDlg *dlg = new CViewMsgDlg(c);
			dlg->Create(IDD_VIEW_MESSAGE);
			win = dlg;
		}
	}
}

void CIcqDlg::onUserFound(PtrList *l)
{
	IcqWindow *win = findWindow(WIN_SEARCH_WIZARD, 0, serverSession()->ackseq);
	if (win)
		((CSearchWizard *) win)->onUserFound(l);
}

void CIcqDlg::onAddFriendReply(uint32 uin, uint8 result)
{
	uint16 seq = serverSession()->ackseq;
	IcqWindow *win;
	if (win = findWindow(WIN_SEARCH_WIZARD, uin, seq))
		((CSearchWizard *) win)->onAddFriendReply(result);
	else if ((win = findWindow(WIN_SYS_MESSAGE, 0, seq)) ||
			(win = findWindow(WIN_ADD_FRIEND, uin, seq)))
		((CSysMsgDlg *) win)->onAddFriendReply(result);
	else
		return;

	if (result == ADD_FRIEND_ACCEPTED) {
		serverSession()->updateContact(uin);
		addContact(uin);
	}
}

void CIcqDlg::setDefaultOptions()
{
	static const char *files[NR_SOUNDS] = {
		"global.wav",
		"msg.wav",
		"system.wav",
		"folder.wav",
	};
	for (int i = 0; i < NR_SOUNDS; i++)
		options.soundFiles[i] = getApp()->rootDir + "sound\\" + files[i];

	bitset<NR_USER_FLAGS> &flags = options.flags;
	flags.set(UF_ALWAYS_ON_TOP);
	flags.set(UF_TASKBAR_STYLE);
	flags.set(UF_ONLINE_NOTIFY);
	flags.set(UF_MONITOR_NETWORK);
	flags.set(UF_TASKBAR_ICON);
	flags.set(UF_USE_HOTKEY);
	flags.set(UF_DEFAULT_HOTKEY);
	flags.set(UF_SOUND_ON);

	CString str;
	int id;
	StrList l;
	for (id = IDS_QUICKREPLY_1; id <= IDS_QUICKREPLY_4; id++) {
		str.LoadString(id);
		l.push_back((LPCTSTR) str);
	}
	IcqDB::saveQuickReply(l);

	l.clear();
	for (id = IDS_AUTOREPLY_1; id <= IDS_AUTOREPLY_3; id++) {
		str.LoadString(id);
		l.push_back((LPCTSTR) str);
	}
	IcqDB::saveAutoReply(l);

	options.autoStatus = STATUS_AWAY;
	options.autoStatusTime = 10;

	outbarCtrl.removeAllFolders();
	str.LoadString(IDS_GROUP_FRIEND);
	outbarCtrl.addFolder(str);
	str.LoadString(IDS_GROUP_STRANGER);
	outbarCtrl.addFolder(str);
	str.LoadString(IDS_GROUP_BLACKLIST);
	outbarCtrl.addFolder(str);
	outbarCtrl.setSelFolder(0);
}

void CIcqDlg::onError()
{
	updateStatusIcon();
	logout();
}

void CIcqDlg::resolveHost()
{
	const char *host = options.host.c_str();

	if (options.flags.test(UF_USE_PROXY) && !options.proxy[options.proxyType].resolve)
		serverSession()->connect(host, options.port);
	else {
		struct in_addr addr;
		if ((addr.s_addr = inet_addr(host)) != INADDR_NONE)
			onHostFound(addr);
		else
			getHostByName(host);
	}
}

void CIcqDlg::initGUI()
{
	CString str;
	str.Format("%lu", myInfo.uin);
	SetWindowText(str);

#ifndef _DEBUG
	SetWindowPos(options.flags.test(UF_ALWAYS_ON_TOP) ? &wndTopMost : &wndNoTopMost,
		0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
#endif

	removeNotifyIcon();
	if (options.flags.test(UF_TASKBAR_ICON))
		addNotifyIcon();

	UnregisterHotKey(m_hWnd, ID_HOTKEY);
	if (options.flags.test(UF_USE_HOTKEY)) {
		uint32 hotKey = (options.flags.test(UF_DEFAULT_HOTKEY) ?
			HOTKEY_DEFAULT : options.hotKey);
		if (!RegisterHotKey(m_hWnd, ID_HOTKEY, HIWORD(hotKey), LOWORD(hotKey)))
			AfxMessageBox(IDS_FAILED_HOTKEY);
	}
	outbarCtrl.setShowOnlineOnly(options.flags.test(UF_SHOW_ONLINE));

	PtrList &l = PluginFactory::getPluginList();
	PtrList::iterator it;
	for (it = l.begin(); it != l.end(); ++it) {
		IcqPlugin *p = (IcqPlugin *) *it;
		if (p->type == ICQ_PLUGIN_TOY)
			((ToyPlugin *) p)->init(icqLink, getApp()->getProfile(p->name.c_str()));
	}

	if (options.skin.empty())
		outbarCtrl.setSkin(NULL);
	else if (skin.load(getApp()->rootDir + "skins\\" + options.skin.c_str()))
		outbarCtrl.setSkin(&skin);
}

BOOL CIcqDlg::doRegWizard()
{
	destroyUser();

	SetTimer(IDT_RESEND, SEND_TIMEOUT * 1000, NULL);

	{
		CRegWizard wiz;
		wiz.DoModal();
		if (!wiz.isFinished)
			return FALSE;

		wiz.getData(&myInfo, &options);
		regMode = wiz.modeDlg.m_mode;
	}

	serverSession()->uin = myInfo.uin;
	IcqConfig::addUser(myInfo.uin);
	getApp()->setDBDir(myInfo.uin);

	setDefaultOptions();
	IcqDB::saveOptions(options);
	IcqDB::saveUser(myInfo);
	saveGroupInfo();

	if (regMode == 1) {
		UinList::iterator it, next;
		for (it = uinList.begin(); it != uinList.end(); it = next) {
			next = it;
			++next;
			uint32 uin = *it;
			IcqContact *c = findContact(uin);
			if (c)
				uinList.erase(it);
			else
				addContact(uin);
		}
	}
	saveGroupInfo();
	outbarCtrl.Invalidate();

	initGUI();
	login();
	return TRUE;
}

BOOL CIcqDlg::doLogin()
{
	CLoginDlg loginDlg;
	int result = loginDlg.DoModal();
	if (result == IDCANCEL)
		return FALSE;

	if (result == IDC_REGWIZARD)
		return doRegWizard();

	destroyUser();

	myInfo.uin = loginDlg.m_uin;
	serverSession()->uin = myInfo.uin;
	getApp()->setDBDir(myInfo.uin);

	if (!IcqDB::loadOptions(options) ||
		!IcqDB::loadUser(myInfo) ||
		!loadGroupInfo()) {
		if (AfxMessageBox(IDS_PROMPT_DB_CORRUPTED, MB_YESNO) == IDYES)
			return doRegWizard();
		return FALSE;
	}

	SetTimer(IDT_RESEND, SEND_TIMEOUT * 1000, NULL);

	CString passwd = loginDlg.m_passwd;
	while (passwd != myInfo.passwd.c_str()) {
		CLoginAgainDlg againDlg(loginDlg.m_uin);
		if (againDlg.DoModal() != IDOK)
			return FALSE;

		passwd = againDlg.m_passwd;
	}

	initGUI();
	login(options.flags.test(UF_LOGIN_INVIS) ? STATUS_INVIS : STATUS_ONLINE);
	return TRUE;
}

void CIcqDlg::destroyUser()
{
	IcqLink::destroyUser();

	UnregisterHotKey(m_hWnd, ID_HOTKEY);
	regMode = -1;
}

IcqMsg *CIcqDlg::fetchMsg(uint32 uin)
{
	IcqMsg *msg = findPendingMsg(uin);
	if (msg)
		msgList.remove(msg);

	if (!findPendingMsg(uin)) {
		if (uin)
			outbarCtrl.blinkImage(uin, FALSE);
		else
			m_btnSysMsg.SetIcon(iconSysMsg);
	}
	if (msgList.empty()) {
		KillTimer(IDT_BLINK);
		updateStatusIcon();
	}
	return msg;
}

void CIcqDlg::showOptions(UINT iSelectPage)
{
	CSysOptionDlg win(this, iSelectPage);
	if (win.DoModal() == IDOK) {
		IcqDB::saveOptions(options);
		initGUI();
	}
}

void CIcqDlg::onStatusAway()
{
	if (myInfo.status == STATUS_OFFLINE)
		login(STATUS_AWAY);
	else {
		if (myInfo.status != STATUS_AWAY) {
			myInfo.status = STATUS_AWAY;
			serverSession()->changeStatus(myInfo.status);
		}
		updateStatusIcon();
	}
}

void CIcqDlg::onNotifyDblClk()
{
	if (msgList.empty()) {
		if (isHide) {
			hideWindow(FALSE);
			SetTimer(IDT_HOVER, 5000, NULL);
		} else {
			ShowWindow(SW_NORMAL);
			SetForegroundWindow();
		}
	} else {
		IcqMsg *msg = (IcqMsg *) msgList.front();

		if (msg->isSysMsg())

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -