// MainFrm.cpp : implementation of the CMainFrame class // #include "stdafx.h" #include "StockServer.h" #include "MainFrm.h" #include "UserListView.h" #include "MessagesView.h" #include "ServerSocket.h" #include "..\\Common\\IPInfos.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CMainFrame IMPLEMENT_DYNCREATE(CMainFrame, CMainTray) BEGIN_MESSAGE_MAP(CMainFrame, CMainTray) //{{AFX_MSG_MAP(CMainFrame) ON_WM_CREATE() ON_WM_DESTROY() ON_WM_GETMINMAXINFO() ON_WM_CLOSE() ON_UPDATE_COMMAND_UI(ID_INDICATOR_CONNECTION_STATUS, OnUpdateConnectionStatus) ON_UPDATE_COMMAND_UI(ID_INDICATOR_CONNECTION_CLIENTS, OnUpdateConnectionClients) ON_UPDATE_COMMAND_UI(ID_INDICATOR_NBMESSAGES, OnUpdateNbMessages) ON_WM_TIMER() ON_COMMAND(ID_VIEW_PARAMETERS, OnViewParameters) ON_UPDATE_COMMAND_UI(ID_VIEW_PARAMETERS, OnUpdateViewParameters) ON_COMMAND(ID_OPTIONS_ALWAYSVISIBLE, OnOptionsAlwaysvisible) ON_UPDATE_COMMAND_UI(ID_OPTIONS_ALWAYSVISIBLE, OnUpdateOptionsAlwaysvisible) ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs) ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_AS, OnUpdateFileSaveAs) ON_COMMAND(ID_OPERATIONS_STARTSERVER, OnOperationsStartserver) ON_UPDATE_COMMAND_UI(ID_OPERATIONS_STARTSERVER, OnUpdateOperationsStartserver) ON_COMMAND(ID_OPERATIONS_STOPSERVER, OnOperationsStopserver) ON_UPDATE_COMMAND_UI(ID_OPERATIONS_STOPSERVER, OnUpdateOperationsStopserver) ON_WM_MENUCHAR() ON_WM_INITMENUPOPUP() ON_COMMAND(ID_TRAYMENU_SHOWSTOCKSERVER, OnTraymenuShowStockServer) //}}AFX_MSG_MAP END_MESSAGE_MAP() static UINT indicators[] = { ID_SEPARATOR, // status line indicator ID_INDICATOR_CONNECTION_STATUS, ID_INDICATOR_CONNECTION_CLIENTS, ID_INDICATOR_NBMESSAGES, ID_INDICATOR_TIME, }; ///////////////////////////////////////////////////////////////////////////// // CMainFrame construction/destruction CMainFrame::CMainFrame() { m_pApp = (CStockServerApp*)AfxGetApp(); m_pUserListView = NULL; m_pMessagesView = NULL; m_pServerSocket = NULL; m_bServerStarted = FALSE; m_bWindowOnTop = m_pApp->GetProfileInt("Settings", "OnTop", FALSE); } CMainFrame::~CMainFrame() { } BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { if( !CMainTray::PreCreateWindow(cs) ) return FALSE; // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs cs.style = WS_OVERLAPPEDWINDOW; return TRUE; } int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CMainTray::OnCreate(lpCreateStruct) == -1) return -1; SetMessageText("ÇÁ·Î±×·¥ ÁغñÁß..."); if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) { TRACE0("Failed to create toolbar\n"); return -1; // fail to create } if (!m_DlgBarUtil.Create(this, IDD_DIALOGBAR_UTIL, CBRS_GRIPPER|CBRS_TOOLTIPS| CBRS_FLYBY|CBRS_SIZE_DYNAMIC|TBSTYLE_FLAT|CBRS_TOP, IDD_DIALOGBAR_UTIL)) { TRACE0("Failed to create dialog bar from CDialogBarUtil class\n"); return -1; // fail to create } if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT))) { TRACE0("Failed to create status bar\n"); return -1; // fail to create } m_wndStatusBar.SetPaneInfo(m_wndStatusBar.CommandToIndex(ID_INDICATOR_CONNECTION_STATUS), ID_INDICATOR_CONNECTION_STATUS, SBPS_POPOUT, 40); // TODO: Delete these three lines if you don't want the toolbar to // be dockable EnableDocking(CBRS_ALIGN_ANY); m_DlgBarUtil.SetWindowText("Util bar"); m_DlgBarUtil.EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_DlgBarUtil); RecalcLayout(); m_wndToolBar.SetWindowText("Main bar"); m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); CRect rc; m_DlgBarUtil.GetWindowRect(rc); DockControlBar(&m_wndToolBar, AFX_IDW_DOCKBAR_TOP, rc); RecalcLayout(); CString szBuf; szBuf.LoadString(AFX_IDS_APP_TITLE); //Change title caption SetWindowText(szBuf); //Set window placement RestoreWindowPlacement(); //Apply App Language // SetLanguage(m_bEnglishLanguage); UpdateAllView(); UpdateMenu(); LoadBarState("ControlsPos"); // System Tray TraySetIcon(IDR_MAINFRAME); TraySetToolTip(szBuf); TraySetMenu(IDR_TRAY_MENU, IDR_BITMAP_MENU); TraySetMinimizeToTray(m_pApp->GetProfileInt("Options", "MinimizeToTray", TRUE)); m_bWindowOnTop = !m_bWindowOnTop; OnOptionsAlwaysvisible(); SetTimer(ID_TIMER_TIME, TIMER_TIME_VALUE, NULL); return 0; } BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext) { int cxCur[2]={0,}; cxCur[0] = m_pApp->GetProfileInt("Settings", "SplitWnd0", 100); cxCur[1] = m_pApp->GetProfileInt("Settings", "SplitWnd1", 100); // create splitter window if (!m_wndSplitter.CreateStatic(this, 1, 2)) return FALSE; if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CUserListView), CSize(cxCur[0], 100), pContext) || !m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CMessagesView), CSize(cxCur[1], 100), pContext)) { m_wndSplitter.DestroyWindow(); return FALSE; } m_pUserListView = GetUserListView(); m_pMessagesView = GetMessagesView(); return TRUE; } void CMainFrame::OnClose() { if (!DisconnectServer()) return; KillTimer(ID_TIMER_TIME); // SetLanguage(DEFAULT_LANGUAGE_ENGLISH, FALSE); SaveWindowPlacement(); SaveBarState("ControlsPos"); m_pApp->WriteProfileInt("Settings", "OnTop", m_bWindowOnTop); // information about a specific row or column int cxCur[2], cxMin[2]; m_wndSplitter.GetColumnInfo( 0, cxCur[0], cxMin[0] ); m_wndSplitter.GetColumnInfo( 1, cxCur[1], cxMin[1] ); m_pApp->WriteProfileInt("Settings", "SplitWnd0", cxCur[0]); m_pApp->WriteProfileInt("Settings", "SplitWnd1", cxCur[1]); CMainTray::OnClose(); } void CMainFrame::OnDestroy() { CMainTray::OnDestroy(); } void CMainFrame::UpdateMenu() { CMenu* pMenu = GetMenu(); if (pMenu) pMenu->DestroyMenu(); m_menu.LoadMenu(IDR_MAINFRAME); m_menu.LoadToolbar(IDR_BITMAP_MENU); HMENU hMenu = m_menu.Detach(); ::SetMenu(GetSafeHwnd(), hMenu); m_hMenuDefault = hMenu; BCMenu::SetMenuDrawMode(1); // Original or XP style } void CMainFrame::SaveWindowPlacement() { WINDOWPLACEMENT wp; GetWindowPlacement(&wp); m_pApp->WriteProfileBinary("Settings", "WindowPos", (LPBYTE)&wp, sizeof(wp)); } void CMainFrame::RestoreWindowPlacement() { WINDOWPLACEMENT *lwp; UINT nl; if(m_pApp->GetProfileBinary("Settings", "WindowPos", (LPBYTE*)&lwp, &nl)) { SetWindowPlacement(lwp); delete [] lwp; } else { CenterWindow(GetDesktopWindow()); } } void CMainFrame::UpdateAllView() { m_pUserListView->UpdateCols(); m_pMessagesView->UpdateCols(); } void CMainFrame::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) { CMainTray::OnGetMinMaxInfo(lpMMI); CPoint minSize(MIN_FRAME_WITH, MIN_FRAME_HEIGTH); // CPoint maxSize(640, 480); lpMMI->ptMinTrackSize.x = minSize.x; lpMMI->ptMinTrackSize.y = minSize.y; // lpMMI->ptMaxTrackSize.x = maxSize.x; // lpMMI->ptMaxTrackSize.y = maxSize.y; } /*============================================================================ Description: Update the status bar connection status indicator Return: - ============================================================================*/ void CMainFrame::OnUpdateConnectionStatus(CCmdUI* pCmdUI) { m_wndStatusBar.SetPaneStyle(m_wndStatusBar.CommandToIndex(ID_INDICATOR_CONNECTION_STATUS), m_bServerStarted ? SBPS_NORMAL : SBPS_POPOUT); pCmdUI->SetText(m_bServerStarted ? CString((LPCTSTR)IDS_SERVER_CONNECTED) : CString((LPCTSTR)IDS_SERVER_DISCONNECTED)); } /*============================================================================ Description: Update the status bar connection status indicator Return: - ============================================================================*/ void CMainFrame::OnUpdateConnectionClients(CCmdUI* pCmdUI) { CString szBuf; int nClients = m_pServerSocket ? m_pServerSocket->GetClientsConnectedCount() : 0; szBuf.Format(IDS_INDICATOR_CONNECTION_CLIENTS, nClients); pCmdUI->SetText(szBuf); } /*============================================================================ Description: Update the status bar connection status indicator Return: - ============================================================================*/ void CMainFrame::OnUpdateNbMessages(CCmdUI* pCmdUI) { CString szBuf; int nClients = m_pServerSocket ? m_pServerSocket->GetTotalMessagesCount() : 0; szBuf.Format(IDS_INDICATOR_NBMESSAGES, nClients); pCmdUI->SetText(szBuf); } void CMainFrame::OnTimer(UINT nIDEvent) { switch (nIDEvent) { case ID_TIMER_TIME: m_wndStatusBar.SetPaneText(m_wndStatusBar.CommandToIndex(ID_INDICATOR_TIME), CTime::GetCurrentTime().Format("%m/%d/%Y %H:%M:%S") ); TraySetMinimizeToTray(m_pApp->GetProfileInt("Options", "MinimizeToTray", TRUE)); break; default: CMainTray::OnTimer(nIDEvent); break; } } ///////////////////////////////////////////////////////////////////////////// // CMainFrame diagnostics #ifdef _DEBUG void CMainFrame::AssertValid() const { CMainTray::AssertValid(); } void CMainFrame::Dump(CDumpContext& dc) const { CMainTray::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CMainFrame message handlers CUserListView* CMainFrame::GetUserListView() { CWnd* pWnd = m_wndSplitter.GetPane(0, 0); CUserListView* pView = DYNAMIC_DOWNCAST(CUserListView, pWnd); return pView; } CMessagesView* CMainFrame::GetMessagesView() { CWnd* pWnd = m_wndSplitter.GetPane(0, 1); CMessagesView* pView = DYNAMIC_DOWNCAST(CMessagesView, pWnd); return pView; } //This handler ensures that keyboard shortcuts work LRESULT CMainFrame::OnMenuChar(UINT nChar, UINT nFlags, CMenu* pMenu) { LRESULT lresult; if (m_menu.IsMenu(pMenu)) lresult = BCMenu::FindKeyboardShortcut(nChar, nFlags, pMenu); else lresult = CMainTray::OnMenuChar(nChar, nFlags, pMenu); return(lresult); } //This handler updates the menus from time to time void CMainFrame::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu) { CMainTray::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu); if (!bSysMenu) { if (m_menu.IsMenu(pPopupMenu)) BCMenu::UpdateMenu(pPopupMenu); } } void CMainFrame::OnViewParameters() { ShowControlBar(&m_DlgBarUtil, !m_DlgBarUtil.IsVisible(), FALSE); } void CMainFrame::OnUpdateViewParameters(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_DlgBarUtil.IsVisible()); } void CMainFrame::OnTraymenuShowStockServer() { TrayShowMainWindow(); } void CMainFrame::OnOptionsAlwaysvisible() { if (!m_bWindowOnTop) { SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); } else { SetWindowPos(&wndNoTopMost, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); } m_bWindowOnTop = !m_bWindowOnTop; } void CMainFrame::OnUpdateOptionsAlwaysvisible(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_bWindowOnTop); } CPtrList* CMainFrame::GetClientsList() { if (!m_pServerSocket) return NULL; return m_pServerSocket->GetClientsList(); } void CMainFrame::UpdateClientsList(CPtrList* pClientstList) { m_pUserListView->UpdateClientsList(pClientstList); } void CMainFrame::OnFileSaveAs() { CStdioFile file; static CString szFileName; CString szFileExt; CString szFileFilter; CString szMessage; CString szBuf1; CString szBuf2; CString szBuf3; BOOL bOpen; if (m_pMessagesView->ListIsEmpty()) { AfxMessageBox(IDS_SAVE_EMPTY_LIST); return; } szFileExt.LoadString(IDS_TXT_FILE_EXT); szFileFilter.LoadString(IDS_TXT_FILE_FLT); CFileDialog Dlg(FALSE, szFileExt, szFileName, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFileFilter); if (Dlg.DoModal() == IDOK) { szFileName = Dlg.GetPathName(); try { bOpen = file.Open(szFileName, CFile::modeWrite | CFile::modeCreate); if (bOpen) { CListCtrl& lc = m_pMessagesView->GetListCtrl(); szBuf1.LoadString(IDR_MAINFRAME); /* szBuf2.LoadString(IDS_TAB_CLIENTS); szBuf3.LoadString(IDS_FILE_LOG_HEADER); szMessage.Format("%s - %s\n%s", szBuf1, szBuf2, szBuf3); file.WriteString(szMessage); szBuf1.LoadString(IDS_COL_USERS); szMessage.Format(_T("%s\n"), szBuf1); file.WriteString(szMessage); szBuf1.LoadString(IDS_FILE_LOG_HEADER); file.WriteString(szBuf1); for (int i = 0; i < lc.GetItemCount(); i++) { szMessage.Format(_T("%s\n"), lc.GetItemText(i, CLIENTSLISTVIEW_COL_USER)); file.WriteString(szMessage); } */ } } catch (CException *e) { e->Delete(); } if (bOpen) { file.Close(); } else { szBuf1.LoadString(IDS_MSG_SAVE_AS_FAILED); szMessage.Format(szBuf1, szFileName); AfxMessageBox(szMessage, MB_ICONSTOP); } } } void CMainFrame::OnUpdateFileSaveAs(CCmdUI* pCmdUI) { pCmdUI->Enable(!m_pMessagesView->ListIsEmpty()); } void CMainFrame::OnOperationsStartserver() { CString szBuf; UINT uPort = m_DlgBarUtil.GetPort(); if (uPort < DEFAULT_MIN_PORT_NUMBER || uPort > DEFAULT_MAX_PORT_NUMBER) { szBuf.Format(IDS_INVALID_PORT_NUMBER, DEFAULT_MIN_PORT_NUMBER, DEFAULT_MAX_PORT_NUMBER); AfxMessageBox(szBuf); return; } m_pUserListView->ClearView(); // ClearAllViews(); m_pServerSocket = new CServerSocket(this); if (m_pServerSocket->BeginListening(uPort, 100)) { szBuf.Format("Server started and online on port %d.", uPort); AddMessage( "Server", szBuf ); m_DlgBarUtil.BlockConrols(); m_bServerStarted = TRUE; } else { DisconnectServer(); } } void CMainFrame::OnUpdateOperationsStartserver(CCmdUI* pCmdUI) { pCmdUI->Enable(!m_bServerStarted); } void CMainFrame::OnOperationsStopserver() { if (DisconnectServer()) m_DlgBarUtil.BlockConrols(FALSE); } void CMainFrame::OnUpdateOperationsStopserver(CCmdUI* pCmdUI) { pCmdUI->Enable(m_bServerStarted); } BOOL CMainFrame::DisconnectServer() { if (!m_pServerSocket) return TRUE; int nClients = m_pServerSocket->GetClientsConnectedCount(); if (nClients > 0) { CString szBuf; szBuf.Format(IDS_STOP_SERVER, nClients); int nRet = MessageBox(szBuf, CString((LPCTSTR)IDR_MAINFRAME), MB_ICONQUESTION|MB_YESNO); if (nRet == IDNO) return FALSE; } AddMessage( "Server", "Server shutdown and offline!" ); if (m_pServerSocket) { delete m_pServerSocket; m_pServerSocket = NULL; } m_bServerStarted = FALSE; return TRUE; } /////////////////////////////////////////////////////////////////////////// // void CMainFrame::AddMessage(CString szName, CString szMessage) { m_pMessagesView->AddMessage(GlobalHelper::GetLocalTime(), szName, szMessage); } void CMainFrame::ClearAllViews() { m_pMessagesView->ClearView(); m_pUserListView->ClearView(); }