www.pudn.com > QQ2004_Source_0.01.rar > QQClientDlg.cpp
// QQClientDlg.cpp : implementation file // #include "stdafx.h" #include "QQClient.h" #include "QQClientDlg.h" #include "QQSocket.h" #include "SendDlg.h" #include "AddFriendDlg.h" #include "Communication.h" #include "XMLParser.h" #include#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CQQClientDlg dialog CQQClientDlg::CQQClientDlg(LPCTSTR serverIP, CWnd* pParent /*=NULL*/) : CDialog(CQQClientDlg::IDD, pParent) { //{{AFX_DATA_INIT(CQQClientDlg) //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); _serverIP = serverIP; } void CQQClientDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CQQClientDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CQQClientDlg, CDialog) //{{AFX_MSG_MAP(CQQClientDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BTN_ADDFRD, OnBtnAddFriend) ON_WM_DESTROY() ON_MESSAGE(WM_PEER_NOTIFY, OnListenNotify) ON_MESSAGE(WM_SENDDLG_CLOSED, OnSenddlgClosed) ON_MESSAGE(WM_OUTBAR_NOTIFY, OnOutbarNotify) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CQQClientDlg message handlers BOOL CQQClientDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // 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 SetWindowText(_userID); initFriendList(); sockaddr_in serverAddr; CQQSocket::stringToIPAddr(_serverIP, serverAddr); serverAddr.sin_port = htons(6000); _comm.startListen(this, _userID, serverAddr); return TRUE; // return TRUE unless you set the focus to a control } void CQQClientDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CQQClientDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CQQClientDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CQQClientDlg::OnBtnAddFriend() { // TODO: Add your control notification handler code here CAddFriendDlg dlg; dlg._userID = _userID; dlg._serverIP = _serverIP; if (dlg.DoModal() != IDOK) return ; CFriendData friendData; if (queryUser(dlg._friendID, friendData) != S_OK) { friendData.userID = dlg._friendID; friendData.nickname = dlg._friendID; ::ZeroMemory(&friendData.addr, sizeof(sockaddr_in)); } _friendList.addFriend(friendData); int itemCount = _obFriendList.GetItemCount(); _obFriendList.InsertItem(0, itemCount, friendData.nickname, itemCount % 7); _obFriendList.Invalidate(TRUE); _obFriendList.UpdateWindow(); } void CQQClientDlg::initFriendList(void) { DWORD flags = CGfxOutBarCtrl::fDragItems | CGfxOutBarCtrl::fEditGroups | CGfxOutBarCtrl::fEditItems | CGfxOutBarCtrl::fRemoveGroups | CGfxOutBarCtrl::fRemoveItems | CGfxOutBarCtrl::fAddGroups; CRect rcList; CWnd *outbar = GetDlgItem(IDC_STATIC_LIST); outbar->GetWindowRect(rcList); ScreenToClient(rcList); _obFriendList.Create(WS_CHILD | WS_VISIBLE, rcList, this, IDC_STATIC_LIST, flags); _obFriendList.SetOwner(this); _headIconList.Create(IDB_HEADICON_LIST, 32, 0, RGB(0, 128, 128)); _obFriendList.SetImageList(&_headIconList, CGfxOutBarCtrl::fLargeIcon); _obFriendList.SetAnimationTickCount(10); _obFriendList.AddFolder(_T("好友列表"), 0); _obFriendList.AddFolder(_T("黑名单"), 1); if (downloadFriends() != S_OK) return ; int friendCount = _friendList.getCount(); for(int i = 0; i < friendCount; i++) { CFriendData *data = _friendList.getFriend(i); _ASSERTE(data != NULL); if (data == NULL) continue ; _obFriendList.InsertItem(0, i, data->nickname, i % 7); } _obFriendList.SetSelFolder(0); } void CQQClientDlg::clear() { _friendList.clear(); _obFriendList.SetSelFolder(0); int itemCount = _obFriendList.GetItemCount(); for(int i = 0; i < itemCount; i++) _obFriendList.RemoveItem(i); } HRESULT CQQClientDlg::queryUser(CString userID, CFriendData &friendData) { CCommunication comm; if (comm.create() != S_OK) return E_FAIL; if (comm.connect(_serverIP) != S_OK) return E_FAIL; if (comm.sendQueryUserRequest(userID) != S_OK) return E_FAIL; CXMLParser parser; if (comm.receiveResponse(parser, 5000, FALSE) != S_OK) return E_FAIL; CElement *root = parser.get_root(); if (root->getChildContent(_T("userID")) != userID) return E_FAIL; friendData.userID = userID; friendData.nickname = root->getChildContent(_T("nickname")); if (root->getChildContent(_T("online")) == _T("true")) { CQQSocket::stringToIPAddr(root->getChildContent(_T("ipAddr")), friendData.addr); CString port = root->getChildContent(_T("port")); friendData.addr.sin_port = _ttoi(port); friendData.online = TRUE; } else friendData.online = FALSE; return S_OK; } HRESULT CQQClientDlg::downloadFriends() { clear(); CCommunication comm; if (comm.create() != S_OK) return E_FAIL; if (comm.connect(_serverIP) != S_OK) return E_FAIL; comm.sendDownloadFriendsRequest(_userID); CXMLParser parser; if (comm.receiveResponse(parser) != S_OK) return E_FAIL; CElement *root = parser.get_root(); CElementList friendList; root->GetChildrenByTag(_T("friend"), friendList); POSITION pos = friendList.GetHeadPosition(); while(pos != NULL) { CElement *friendEle = friendList.GetNext(pos); _ASSERTE(friendEle != NULL); if (friendEle == NULL) continue ; CString friendID = friendEle->get_content(); CFriendData friendData; if (queryUser(friendID, friendData) != S_OK) { friendData.userID = friendID; friendData.nickname = friendID; ::ZeroMemory(&friendData.addr, sizeof(sockaddr_in)); } _friendList.addFriend(friendData); } return S_OK; } void CQQClientDlg::OnDestroy() { CCommunication comm; if (comm.create() != S_OK) return ; if (comm.connect(_serverIP) != S_OK) return ; comm.sendLogoffRequest(_userID); _comm.stopListen(); CDialog::OnDestroy(); // TODO: Add your message handler code here DialogIterator it = _dialogVector.begin(); for (;it != _dialogVector.end(); it++) { (*it)->DestroyWindow(); delete (*it); } } HRESULT CQQClientDlg::sendMessageToFriend(int index) { CFriendData *friendData = _friendList.getFriend(index); _ASSERTE(friendData != NULL); if (friendData == NULL) return E_FAIL; CSendDlg *dlg = NULL; DialogIterator it = _dialogVector.begin(); for (;it != _dialogVector.end(); it++) { if ( ((CSendDlg*)(*it))->_friendID == friendData->userID ) { dlg = (CSendDlg*)(*it); dlg->SetFocus(); return S_OK; } } if (queryUser(friendData->userID, *friendData) != S_OK) { AfxMessageBox(_T("错误:连接服务器,查询用户数据失败")); return E_FAIL; } if (friendData->online == FALSE) { AfxMessageBox(_T("该用户不在线上.")); return E_FAIL; } dlg = new CSendDlg(this); dlg->_friendName = friendData->nickname; dlg->_friendID = friendData->userID; dlg->_userID = _userID; dlg->_userName = _nickname; memcpy(&dlg->_friendAddr, &friendData->addr, sizeof(sockaddr_in)); dlg->Create(IDD_SENDMSG); dlg->ShowWindow(SW_SHOW); _dialogVector.push_back(dlg); return S_OK; } LRESULT CQQClientDlg::OnSenddlgClosed(WPARAM wParam, LPARAM lParam) { TCHAR *friendID = (TCHAR*)wParam; CSendDlg *dlg = NULL; DialogIterator it = _dialogVector.begin(); for (;it != _dialogVector.end(); it++) { if ( ((CSendDlg*)(*it))->_friendID == friendID ) { dlg = (CSendDlg*)(*it); _dialogVector.erase(it); break ; } } delete[] friendID; if (dlg != NULL) delete dlg; return 0; } LRESULT CQQClientDlg::OnListenNotify(WPARAM wParam, LPARAM lParam) { TCHAR *message = (TCHAR*)wParam; TCHAR *friendID = (TCHAR*)lParam; CSendDlg *dlg = NULL; DialogIterator it = _dialogVector.begin(); for (;it != _dialogVector.end(); it++) { if ( ((CSendDlg*)(*it))->_friendID == friendID ) { dlg = (CSendDlg*)(*it); break ; } } CFriendData friendData; if (queryUser(friendID, friendData) != S_OK) { if (dlg != NULL) friendData.nickname = friendID; else return 0; } if (dlg == NULL) { dlg = new CSendDlg(this); dlg->_friendName = friendData.nickname; dlg->_friendID = friendData.userID; dlg->_userID = _userID; dlg->_userName = _nickname; memcpy(&dlg->_friendAddr, &friendData.addr, sizeof(sockaddr_in)); dlg->Create(IDD_SENDMSG); dlg->ShowWindow(SW_SHOW); _dialogVector.push_back(dlg); } dlg->insertMessage(friendData.nickname, message); delete[] friendID; delete[] message; return 0; } LRESULT CQQClientDlg::OnOutbarNotify(WPARAM wParam, LPARAM lParam) { switch(wParam) { case NM_OB_ITEMCLICK: { int index = (int)lParam; sendMessageToFriend(index); break ; } } return 0; }