www.gusucode.com > 一个比较完整的VC++仿QQ聊天源码源码程序 > 一个比较完整的VC++仿QQ聊天源码/fakeQQ/fakeQQ/FakeQQDlg.cpp
// FakeQQDlg.cpp : implementation file // Download by http://www.codesc.net #include "stdafx.h" #include "FakeQQ.h" #include "FakeQQDlg.h" #include "ChatRecordSet.h" #include "ViewLogDlg.h" #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() ///////////////////////////////////////////////////////////////////////////// // CFakeQQDlg dialog CFakeQQDlg::CFakeQQDlg(CWnd* pParent /*=NULL*/) : CDialog(CFakeQQDlg::IDD, pParent) { //{{AFX_DATA_INIT(CFakeQQDlg) m_Elapse = _T("00:00:00"); //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_bHide = false; m_hIcon = ::FaceIcon[::MyInfo.m_Face]; m_nDisplayTimerID = 1; m_nTrayIconFlashTimerID = 2; m_bTrayIconFlashing = false; m_hFlashingTrayIcon = NULL; } void CFakeQQDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CFakeQQDlg) DDX_Control(pDX, IDC_TOOLBAR_PANE, m_ToolBarPane); DDX_Control(pDX, IDC_USER_LIST, m_UserList); DDX_Text(pDX, IDC_ELAPSE, m_Elapse); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CFakeQQDlg, CDialog) //{{AFX_MSG_MAP(CFakeQQDlg) ON_WM_SYSCOMMAND() ON_WM_TIMER() ON_WM_DESTROY() ON_COMMAND(ID_SHOW_WINDOW, OnShowWindow) ON_NOTIFY(NM_DBLCLK, IDC_USER_LIST, OnDblclkUserList) ON_COMMAND(ID_HIDE_WINDOW, OnHideWindow) ON_COMMAND(ID_VIEW_LOG, OnViewLog) ON_COMMAND(ID_SHOW_LAST_CHAT, OnShowLastChat) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CFakeQQDlg message handlers BOOL CFakeQQDlg::OnInitDialog() { CDialog::OnInitDialog(); if (!m_ToolBar.CreateEx(this) || !m_ToolBar.LoadToolBar(IDR_TOOLBAR)) { TRACE0("Failed to create toolbar\n"); return -1; } RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0); CRect Rect; m_ToolBarPane.GetWindowRect(Rect); ScreenToClient(Rect); m_ToolBar.MoveWindow(&Rect); m_ToolBar.SetBarStyle(m_ToolBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY); BuildUserList(); // 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 m_nDisplayTimerID = SetTimer(m_nDisplayTimerID, 1000, NULL); m_StartTime = CTime::GetCurrentTime(); m_Nid.cbSize = sizeof(NOTIFYICONDATA); m_Nid.hWnd = GetSafeHwnd(); m_Nid.uID = 0; m_Nid.hIcon = m_hIcon; m_Nid.uFlags = NIF_ICON|NIF_TIP|NIF_MESSAGE; m_Nid.uCallbackMessage = WM_COMMAND; CString sTitle; sTitle.Format("FakeQQ 1.0\r\n%s\r\n%s:%d", ::MyInfo.m_UserName, ::MyInfo.m_Ip, ::MyInfo.m_Port); strcpy(m_Nid.szTip, sTitle); Shell_NotifyIcon(NIM_ADD, &m_Nid); SetWindowText(::MyInfo.m_UserName); return TRUE; // return TRUE unless you set the focus to a control } void CFakeQQDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } void CFakeQQDlg::OnTimer(UINT nIDEvent) { //闪烁 if(nIDEvent == m_nTrayIconFlashTimerID) { if(m_nTrayIconFlashTicks) { m_Nid.hIcon = NULL; } else { m_Nid.hIcon = m_hFlashingTrayIcon; } Shell_NotifyIcon(NIM_MODIFY,&m_Nid); m_nTrayIconFlashTicks = !m_nTrayIconFlashTicks; } //显示时间 if(nIDEvent == m_nDisplayTimerID) { CTimeSpan Elapse = CTime::GetCurrentTime() - m_StartTime; CString Prompt = Elapse.Format("%H:%M:%S"); m_Elapse= Prompt; UpdateData(false); } CDialog::OnTimer(nIDEvent); } void CFakeQQDlg::OnDestroy() { CDialog::OnDestroy(); FlashTrayIcon(m_hIcon, false); KillTimer(m_nDisplayTimerID); Shell_NotifyIcon(NIM_DELETE, &m_Nid); } void CFakeQQDlg::OnShowWindow() { ShowWindow(true); m_bHide = false; SetForegroundWindow(); } BOOL CFakeQQDlg::OnCommand(WPARAM wParam, LPARAM lParam) { if(!wParam) { switch(lParam) { case WM_LBUTTONUP: OnShowWindow(); break; case WM_LBUTTONDBLCLK: OnShowLastChat(); break; case WM_RBUTTONUP: CMenu Menu, *pMenu; Menu.LoadMenu(IDR_POP); pMenu=Menu.GetSubMenu(0); SetForegroundWindow(); POINT Pt; GetCursorPos(&Pt); pMenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_BOTTOMALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON,Pt.x,Pt.y,this); break; } } return CDialog::OnCommand(wParam, lParam); } void CFakeQQDlg::OnDblclkUserList(NMHDR* pNMHDR, LRESULT* pResult) { HD_NOTIFY *phdn = (HD_NOTIFY *) pNMHDR; if(phdn->iItem >= 0) { CUserInfo * pUser = (CUserInfo *)m_UserList.GetItemData(phdn->iItem); CSendMsgDlg SendDlg(pUser); SendDlg.DoModal(); } *pResult = 0; } void CFakeQQDlg::BuildUserList() { //初始化界面 m_ImageList.Create(32, 32, TRUE, 8, 1); for(int i = 0; i < sizeof(::FaceIcon)/sizeof(HICON); i++) { m_ImageList.Add(::FaceIcon[i]); } m_UserList.SetBkColor(RGB(128, 128, 192)); m_UserList.SetTextBkColor(RGB(128, 128, 192)); m_UserList.SetImageList(&m_ImageList, LVSIL_NORMAL); m_UserList.SetIconSpacing(0, 10); //0为主叫连接 m_UserList.InsertItem(0, "主叫连接", 0); } CFakeQQDlg::~CFakeQQDlg() { POSITION p = m_UserInfoList.GetHeadPosition(); while(p) { CUserInfo * pUser = (CUserInfo *)m_UserInfoList.GetNext(p); if(pUser) delete pUser; } m_UserInfoList.RemoveAll(); for(int i = 0; i < m_MsgQueue.GetSize(); i++) { CMsgInfo * pMsg = (CMsgInfo *)m_MsgQueue.GetAt(i); if(pMsg) delete pMsg; } m_MsgQueue.RemoveAll(); } void CFakeQQDlg::OnHideWindow() { ShowWindow(SW_HIDE); m_bHide = true; } void CFakeQQDlg::FlashTrayIcon(HICON Icon, bool Flash) { m_nTrayIconFlashTicks = 0; if(Flash) { m_hFlashingTrayIcon = Icon; m_nTrayIconFlashTimerID = SetTimer(m_nTrayIconFlashTimerID, 500 , NULL); m_bTrayIconFlashing = true; } else { KillTimer(m_nTrayIconFlashTimerID); m_Nid.hIcon = Icon; Shell_NotifyIcon(NIM_MODIFY,&m_Nid); m_bTrayIconFlashing = false; } } void CFakeQQDlg::PushMsg(CMsgInfo *pMsg) { CSingleLock sLock(&m_Mutex); m_MsgQueue.Add(pMsg); //保存讯息 SaveMsg(pMsg); //在ListCtrl里显示头像 int nItem = FindUser(&pMsg->m_FromUser); CUserInfo * pUser; if(nItem != -1) { pUser = (CUserInfo *)m_UserList.GetItemData(nItem); delete pUser; m_UserList.DeleteItem(nItem); } else nItem = 1; nItem = m_UserList.InsertItem(nItem, pMsg->m_FromUser.m_UserName, pMsg->m_FromUser.m_Face); pUser = new CUserInfo(); *pUser = pMsg->m_FromUser; m_UserList.SetItemData(nItem, (DWORD)pUser); //闪动TrayIcon? if(m_MsgQueue.GetSize() == 1) FlashTrayIcon(::FaceIcon[pMsg->m_FromUser.m_Face]); sLock.Unlock(); } CMsgInfo * CFakeQQDlg::PopMsg() { if(!m_MsgQueue.GetSize()) return NULL; CMsgInfo * pMsg = (CMsgInfo *)m_MsgQueue.GetAt(0); m_MsgQueue.RemoveAt(0); //处理TrayIcon if(!m_MsgQueue.GetSize()) FlashTrayIcon(m_hIcon, false); else { CMsgInfo * pNextMsg = (CMsgInfo *)m_MsgQueue.GetAt(0); FlashTrayIcon(::FaceIcon[pNextMsg->m_FromUser.m_Face]); } return pMsg; } int CFakeQQDlg::FindUser(CUserInfo *pUser) { //0为主叫连接 for(int i = 1; i < m_UserList.GetItemCount(); i++) { CUserInfo * pItem = (CUserInfo *)m_UserList.GetItemData(i); if(pItem && !strcmp(pItem->m_Ip, pUser->m_Ip) && pItem->m_Port == pUser->m_Port) return i; } return -1; } bool CFakeQQDlg::SaveMsg(CMsgInfo *pMsg) { try { CChatRecordSet crs(&::ChatDB); crs.Open(); crs.AddNew(); crs.m_Address.Format("%s:%d", pMsg->m_FromUser.m_Ip, pMsg->m_FromUser.m_Port); crs.m_ChatMsg = pMsg->m_Msg; crs.m_UserFace = pMsg->m_FromUser.m_Face; crs.m_UserName = pMsg->m_FromUser.m_UserName; crs.m_MsgTime = pMsg->m_Time; if(crs.Update()) return true; } catch(CException *e) { e->Delete(); return false; } return false; } void CFakeQQDlg::OnViewLog() { // TODO: Add your command handler code here CViewLogDlg LogDlg; LogDlg.DoModal(); } void CFakeQQDlg::OnShowLastChat() { CMsgInfo * pMsg = PopMsg(); if(pMsg) { CReplyMsgDlg ReplyDlg(pMsg); ReplyDlg.DoModal(); delete pMsg; } }