return0;//Return0ifallsucceed.}while(0);return-1;//Return-1toindicateerrorhappens.}voidCMainFrame::OnClose(){if(!m_is_view_closing){if(!Session::Instance().IsExpired())//Onlypromptnotificationinloggedinstate.{if(IDNO==MessageBox(L"您确定要退出并关闭程序吗?",L"退出系统提示!",MB_YESNO|MB_ICONEXCLAMATION))return;if(!LogOut()){MessageBox(L"退出系统失败,若无法重新登录请联系维护人员!",L"退出系统提示!",MB_OK|MB_ICONWARNING);LOG_ERROR(L"服务端退出请求处理失败。程序关闭。");}elseLOG_TRACE(L"退出系统成功。");}m_view.SendMessage(WM_CLOSE);//RequestCETradeClientViewtoclose.m_is_view_closing=true;//Enablenexttimeclose.return;//Andcancelthisclose.}m_user_msg_monitor.Stop();LOG_TRACE(L"程序关闭。");CFrameWnd::OnClose();}voidCMainFrame::OnMeasureItem(intnIDCtl,LPMEASUREITEMSTRUCTlpMeasureItemStruct){do{if((lpMeasureItemStruct==NULL)||(lpMeasureItemStruct->CtlType!=ODT_MENU))break;//Don'thandleitemsotherthanmenu.constuint32_tkIconWidth=24,kIconHeight=24;//Thisisthemostsuitablesizeforshowingaicon.lpMeasureItemStruct->itemWidth=kIconWidth;lpMeasureItemStruct->itemHeight=kIconHeight;}while(0);CFrameWnd::OnMeasureItem(nIDCtl,lpMeasureItemStruct);}voidCMainFrame::OnDrawItem(intnIDCtl,LPDRAWITEMSTRUCTlpDrawItemStruct){staticconstint32_tOFFSET_LEFT=-6,OFFSET_TOP=-4;//Thisisthemostsuitablesize.do{if((lpDrawItemStruct==NULL)||(lpDrawItemStruct->CtlType!=ODT_MENU))break;//Don'thandleitemsotherthanmenu.::DrawIconEx(lpDrawItemStruct->hDC,lpDrawItemStruct->rcItem.left+OFFSET_LEFT,lpDrawItemStruct->rcItem.top+OFFSET_TOP,m_authorized_menu_icons[lpDrawItemStruct->itemID],MENU_ICON_WIDTH,MENU_ICON_HEIGHT,0,NULL,DI_NORMAL);}while(0);CFrameWnd::OnDrawItem(nIDCtl,lpDrawItemStruct);}voidCMainFrame::OnInitMenuPopup(CMenu*pMenu,UINTnIndex,BOOLbSysMenu){CFrameWnd::OnInitMenuPopup(pMenu,nIndex,bSysMenu);if(bSysMenu)pMenu=GetSystemMenu(FALSE);//AllowstheapplicationtoaccesstheControlmenuforcopyingandmodification.//@{Setmenustyle.MENUINFOmnfo;mnfo.cbSize=sizeof(mnfo);mnfo.fMask=MIM_STYLE;mnfo.dwStyle=MNS_CHECKORBMP|MNS_AUTODISMISS;pMenu->SetMenuInfo(&mnfo);//@}//@{Setmenuitemattributes.MENUITEMINFOminfo;minfo.cbSize=sizeof(minfo);//Warning!!!Currentlywehaveonly2menulevels:topmenu&submenu.//Sothisalgorithmisnotgeneralenoughtohandleamenutree.for(intpos=0;pos<pMenu->GetMenuItemCount();++pos){minfo.fMask=MIIM_FTYPE|MIIM_ID;pMenu->GetMenuItemInfo(pos,&minfo,TRUE);if((minfo.fState&MFS_DISABLED)||(minfo.fState&MFS_UNCHECKED)){inti=0;}if(minfo.fType==MFT_SEPARATOR)//Don'thandletheseparator.continue;if(!(minfo.fType&MFT_OWNERDRAW))//Ifnotaownerdrawmenuitem.{minfo.fMask=MIIM_FTYPE|MIIM_BITMAP;//Indicatesthememberstoberetrievedorset:the'hbmpItem'member..//"HBMMENU_CALLBACK"indicatestahtabitmapthatisdrawnbythewindowthatownsthemenu.//TheapplicationmustprocesstheWM_MEASUREITEMandWM_DRAWITEMmessages.minfo.hbmpItem=HBMMENU_CALLBACK;minfo.fType=MFT_STRING;//Displaysthemenuitemusingatextstring.pMenu->SetMenuItemInfo(pos,&minfo,TRUE);}}//@}}voidCMainFrame::OnUpdateToolBarMsgCount(CCmdUI*pCmdUI){if(m_msg_count>0)pCmdUI->Enable(true);elsepCmdUI->Enable(false);}voidCMainFrame::OnToolBarBtnClicked(UINTbtn_id){switch(btn_id){caseRELOAD:m_view.Browser().Reload();break;caseUSER_MESSAGE:ShowUserMessageDlg();break;default:break;}}voidCMainFrame::OnMenuBtnClicked(UINTbtn_id){m_view.Browser().NavigateTo(MenuUrl(btn_id));}voidCMainFrame::OnToolbarDropDown(NMHDR*pNMHDR,LRESULT*pResult){LPNMTOOLBARtool_bar=reinterpret_cast<LPNMTOOLBAR>(pNMHDR);if(USER_ACCOUNT==tool_bar->iItem){CMenumenu;menu.LoadMenu(IDR_ACCOUNT);CMenu*popup_menu=menu.GetSubMenu(0);ASSERT(popup_menu);CRectrc;m_ex_func_tlb.SendMessage(TB_GETRECT,tool_bar->iItem,(LPARAM)&rc);m_ex_func_tlb.ClientToScreen(&rc);popup_menu->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_VERTICAL,rc.left,rc.bottom,this,&rc);}}voidCMainFrame::OnExit(){AfxGetMainWnd()->PostMessage(WM_CLOSE);}voidCMainFrame::OnModifyPwd(){m_user_msg_monitor.Stop();//Stopmonitoringbeforelaunchingthepasswordmodificationdialog.RECTrect;GetWindowRect(&rect);CModifyPwdView(rect).DoModal();m_user_msg_monitor.Start();//Recovermonitoring.}voidCMainFrame::OnModifyConfig(){m_user_msg_monitor.Stop();//Stopmonitoringbeforelaunchingthepasswordmodificationdialog.CConfigDialog().DoModal();m_user_msg_monitor.Start();//Recovermonitoring.}afx_msgLRESULTCMainFrame::OnSessionExpired(WPARAMwParam,LPARAMlParam){m_user_msg_monitor.Stop();//Firststoptheusermessagemonitoring.if(!CLoginDialog(L"当前连接已过期,请重新登录!",this).Launch()){OnExit();return0;}Session::Instance().OnValid();//Ifloginsucceeded,recoverthesessionstatetobe"not expired".m_user_msg_monitor.Start();//Startagainafterreloggedin.return0;}afx_msgLRESULTCMainFrame::OnGotMsgCount(WPARAMwParam,LPARAMlParam){m_msg_count=(int)wParam;return0;}boolCMainFrame::FilterMenuBar(){CWnd*main_wnd=AfxGetApp()->m_pMainWnd;CMenu*menu=main_wnd->GetMenu();//Removeunauthorizedmenu.//!!!Throughreversetraversal,guaranteetheindexorderwillnotdisorderlywhenremovenextmenuitem.MenuResAuthMgr::MenuItemsType::const_reverse_iteratorcriter;constauto&menu_items=m_menu_res_auth_manager.MenuItems();std::vector<uint32_t>::const_iteratormenu_index_iter;for(criter=menu_items.crbegin();criter!=menu_items.crend();++criter){if(!criter->second.is_authorized)//Removethoseunauthorizedmenuitems.{CMenu*sub_menu=menu;//Traversetotheparentmenuoftheleafnodemenu(whichhasnomoresubmenu).constauto&index_list=criter->second.index_list;if(index_list.empty())break;//" -1 "meansonlytraversetotheleafnode'sparentnode.Thentheiterwillbedirectedtotheleadnode.//,thenwecancall"RemoveMenu(*menu_index_iter, MF_BYPOSITION)"toremovetheleafnode.//Thisworksthesametothetoplevelmenu.for(menu_index_iter=index_list.cbegin();menu_index_iter!=index_list.cend()-1;++menu_index_iter){sub_menu=sub_menu->GetSubMenu(*menu_index_iter);if(NULL==sub_menu){std::stringstreamerr_msg;err_msg<<"菜单配置错误, menu resource id: "<<criter->first<<"; menu index: "<<*menu_index_iter<<"!";LOG_ERROR(str_2_wstr(err_msg.str()));break;}}//Hereweonlyneedtoremovethesubmenu,sincewebserverwillnotreturnanemptyparentmenuwhichhasnonesubmenu.if(NULL==sub_menu||!sub_menu->RemoveMenu(*menu_index_iter,MF_BYPOSITION))LOG_ERROR(L"移除未授权菜单失败, menu resource id = "+std::to_wstring(criter->first)+L"!");}else{std::wstringfile_path=MENU_ICON_FOLDER+str_2_wstr(criter->second.icon_name);if(!fs::exists(file_path)){LOG_ERROR(L"图片文件:"+file_path+L"不存在, 请检查!");break;}HICONhicon=(HICON)LoadImage(AfxGetResourceHandle(),file_path.c_str(),IMAGE_ICON,MENU_ICON_WIDTH,MENU_ICON_HEIGHT,LR_DEFAULTCOLOR|LR_LOADFROMFILE);m_authorized_menu_icons.emplace(std::make_pair(criter->first,hicon));//针对需要服务器端授权的菜单项,使用从服务器获取的菜单标题来更新菜单标题,//对于无需服务器端授权的“本地菜单项”,则无需更新。if(!m_menu_res_auth_manager.IsLocalMenuItem(criter->first))menu->ModifyMenu(criter->first,MF_BYCOMMAND,criter->first,criter->second.remark.c_str());}}main_wnd->DrawMenuBar();returntrue;}boolCMainFrame::FilterQuickAccessToolBar(){typedefMenuResAuthMgr::MenuItemsTypeMenuItemsT;constauto&menu_items=m_menu_res_auth_manager.MenuItems();intindex=0;for(autoiter=kQuickAccessBtn.begin();iter!=kQuickAccessBtn.end();){MenuItemsT::const_iteratorcit=menu_items.find(iter->idCommand);if(cit!=menu_items.cend()&&cit->second.is_authorized)//Iffoundandauthorized.{iter->iBitmap=index;//modifytheiconindexmapping.index++;++iter;}else//Ifnotfoundorunauthorized.iter=kQuickAccessBtn.erase(iter);}returntrue;}boolCMainFrame::CreateMainFrmUI(){do{HICONframe_icon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);//Specifiesa32pixelby32pixeliconifTRUE;specifiesa16pixelby16pixeliconifFALSE.SetIcon(frame_icon,TRUE);//SetbigiconSetIcon(frame_icon,FALSE);//Setsmallicon//createaviewtooccupytheclientareaoftheframeif(!m_view.Create(NULL,NULL,AFX_WS_DEFAULT_VIEW,CRect(0,0,0,0),this,AFX_IDW_PANE_FIRST,NULL)){LOG_ERROR(L"Failed to create view window\n");break;}if(!m_status_bar.Create(this)){LOG_ERROR(L"Failed to create status bar\n");break;//failtocreate}m_status_bar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT));//m_status_bar.SetPaneStyle(0,SBPS_NORMAL);//@{if(!CreateWebNaviToolBar()){LOG_ERROR(L"Failed to create web navigation toolbar\n");break;//failtocreate}if(!CreateQuickAccessToolBar()){LOG_ERROR(L"Failed to create quick access toolbar\n");break;//failtocreate}if(!CreateExFuncToolBar()){LOG_ERROR(L"Failed to create extra function toolbar\n");break;//failtocreate}if(!m_re_bar.Create(this)||!m_re_bar.AddBar(&m_web_navi_tlb,NULL,NULL,RBBS_NOGRIPPER)||!m_re_bar.AddBar(&m_quick_access_tlb,NULL,NULL,RBBS_NOGRIPPER)||!m_re_bar.AddBar(&m_ex_func_tlb,NULL,NULL,RBBS_NOGRIPPER)){LOG_ERROR(L"Failed to create rebar\n");break;//failtocreate}//@}m_re_bar.GetReBarCtrl().MinimizeBand(0);returntrue;}while(0);returnfalse;}boolCMainFrame::CreateWebNaviToolBar(){staticconststd::vector<std::wstring>kWebNaviIcon={_T("reload.ico")};staticstd::vector<TBBUTTON>kWebNaviBtn={{0,RELOAD,TBSTATE_ENABLED,BTNS_BUTTON,0,0}};if(!m_web_navi_tlb.CreateEx(this,TBSTYLE_TRANSPARENT))returnfalse;//failtocreateif(!m_web_navi_tlb_imgs.Create(TOOLBAR_ICON_WIDTH,TOOLBAR_ICON_HEIGHT,ILC_COLOR32|ILC_MASK,0,0))returnfalse;for(constauto&icon_name:kWebNaviIcon){std::wstringfile_path=TOOLBAR_ICON_FOLDER+icon_name;if(!fs::exists(file_path)){LOG_ERROR(L"图片文件:"+file_path+L"不存在, 请检查!");returnfalse;}HICONicon=(HICON)LoadImage(AfxGetResourceHandle(),file_path.c_str(),IMAGE_ICON,TOOLBAR_ICON_WIDTH,TOOLBAR_ICON_HEIGHT,LR_DEFAULTCOLOR|LR_LOADFROMFILE);m_web_navi_tlb_imgs.Add(icon);}CToolBarCtrl&tbc=m_web_navi_tlb.GetToolBarCtrl();for(auto&btn:kWebNaviBtn)tbc.AddButtons(1,&btn);tbc.SetImageList(&m_web_navi_tlb_imgs);constuint32_tkPaddingWidth=45;UpdateToolbarBtnSize(m_web_navi_tlb,kPaddingWidth);//Makesuretosettoolbarbuttonsizeafterthebuttontexthasbeenset.returntrue;}boolCMainFrame::CreateQuickAccessToolBar(){if(!m_quick_access_tlb.CreateEx(this,TBSTYLE_TRANSPARENT|TBSTYLE_LIST))returnfalse;//failtocreateif(!m_quick_access_tlb_imgs.Create(TOOLBAR_ICON_WIDTH,TOOLBAR_ICON_HEIGHT,ILC_COLOR32|ILC_MASK,0,0))returnfalse;CToolBarCtrl&tbc=m_quick_access_tlb.GetToolBarCtrl();tbc.SetImageList(&m_quick_access_tlb_imgs);//注意这一句必须放在为“SetButtonText”和“UpdateToolbarBtnSize”之前,否则会出现宽度计算错误constauto&res_auth_map=m_menu_res_auth_manager.MenuItems();intindex=0;for(auto&btn:kQuickAccessBtn){tbc.AddButtons(1,&btn);std::wstringfile_path=TOOLBAR_ICON_FOLDER+str_2_wstr(res_auth_map.at(btn.idCommand).icon_name);if(!fs::exists(file_path)){LOG_ERROR(L"图片文件:"+file_path+L"不存在, 请检查!");returnfalse;}HICONicon=(HICON)LoadImage(AfxGetResourceHandle(),file_path.c_str(),IMAGE_ICON,TOOLBAR_ICON_WIDTH,TOOLBAR_ICON_HEIGHT,LR_DEFAULTCOLOR|LR_LOADFROMFILE);m_quick_access_tlb_imgs.Add(icon);m_quick_access_tlb.SetButtonText(index,res_auth_map.at(btn.idCommand).remark.c_str());index++;}UpdateToolbarBtnSize(m_quick_access_tlb);//Makesuretosettoolbarbuttonsizeafterthebuttontexthasbeenset.returntrue;}boolCMainFrame::CreateExFuncToolBar(){staticstd::vector<std::wstring>kExFuncText={_T("消息"),_T("账户")};staticconststd::vector<std::wstring>kExFuncIcon={_T("message.ico"),_T("user.ico")};//Iconforthedisabledtoolbarbuttons.staticconststd::vector<std::wstring>kExFuncIconDisabled={_T("message_d.ico"),_T("user_d.ico")};staticstd::vector<TBBUTTON>kExFuncBtn={{0,USER_MESSAGE,TBSTATE_ENABLED,BTNS_AUTOSIZE|BTNS_BUTTON,0,0},{1,USER_ACCOUNT,TBSTATE_ENABLED,BTNS_AUTOSIZE|BTNS_BUTTON|BTNS_WHOLEDROPDOWN,0,0}};if(!m_ex_func_tlb.CreateEx(this,TBSTYLE_TRANSPARENT|TBSTYLE_LIST))returnfalse;//failtocreateif(!m_ex_func_tlb_imgs.Create(TOOLBAR_ICON_WIDTH,TOOLBAR_ICON_HEIGHT,ILC_COLOR32|ILC_MASK,0,0)||!m_ex_func_tlb_disabled_imgs.Create(TOOLBAR_ICON_WIDTH,TOOLBAR_ICON_HEIGHT,ILC_COLOR32|ILC_MASK,0,0))returnfalse;for(constauto&icon_name:kExFuncIcon){std::wstringfile_path=TOOLBAR_ICON_FOLDER+icon_name;if(!fs::exists(file_path)){LOG_ERROR(L"图片文件:"+file_path+L"不存在, 请检查!");returnfalse;}HICONicon=(HICON)LoadImage(AfxGetResourceHandle(),file_path.c_str(),IMAGE_ICON,TOOLBAR_ICON_WIDTH,TOOLBAR_ICON_HEIGHT,LR_DEFAULTCOLOR|LR_LOADFROMFILE);m_ex_func_tlb_imgs.Add(icon);}for(constauto&icon_name:kExFuncIconDisabled){std::wstringfile_path=TOOLBAR_ICON_FOLDER+icon_name;if(!fs::exists(file_path)){LOG_ERROR(L"图片文件:"+file_path+L"不存在, 请检查!");returnfalse;}HICONicon=(HICON)LoadImage(AfxGetResourceHandle(),file_path.c_str(),IMAGE_ICON,TOOLBAR_ICON_WIDTH,TOOLBAR_ICON_HEIGHT,LR_DEFAULTCOLOR|LR_LOADFROMFILE);m_ex_func_tlb_disabled_imgs.Add(icon);}CToolBarCtrl&tbc=m_ex_func_tlb.GetToolBarCtrl();for(auto&btn:kExFuncBtn)tbc.AddButtons(1,&btn);tbc.SetImageList(&m_ex_func_tlb_imgs);tbc.SetDisabledImageList(&m_ex_func_tlb_disabled_imgs);intindex=0;for(auto&text:kExFuncText){m_ex_func_tlb.SetButtonText(index,text.c_str());index++;}//设置用户名constintkAccountBtnIndex=1;m_ex_func_tlb.SetButtonText(kAccountBtnIndex,Session::Instance().UserName().c_str());UpdateToolbarBtnSize(m_ex_func_tlb);//Makesuretosettoolbarbuttonsizeafterthebuttontexthasbeenset.returntrue;}voidCMainFrame::UpdateToolbarBtnSize(CToolBar&toolbar,uint32_tpadding_width,uint32_tpadding_height){CRectbtn_rect;inttotal_btns_width=0;intbtns_count=toolbar.GetToolBarCtrl().GetButtonCount();if(btns_count<=0)return;for(intidx=0;idx<btns_count;++idx){toolbar.GetItemRect(idx,&btn_rect);total_btns_width+=btn_rect.Size().cx;}constintbtn_size_x=total_btns_width/btns_count;//计算按钮宽度平均值constintbtn_size_y=btn_rect.Size().cy;toolbar.SetSizes(CSize(btn_size_x+padding_width,btn_size_y+padding_height),CSize(TOOLBAR_ICON_WIDTH,TOOLBAR_ICON_HEIGHT));}boolCMainFrame::LogOut(){boollog_out_res=true;std::stringresponse_body;try{response_body=WinHttpGet(URLConfig::Instance().LogoutPath());}catch(std::exception&ex){LOG_ERROR(L"网络连接有问题,退出系统失败。错误信息: "+gbk_2_wstr(ex.what()));returnfalse;}namespacePT=boost::property_tree;try//Parsetheconfigurationfile{PT::ptreeptree;std::stringstreamss;ss<<response_body;PT::read_json(ss,ptree);std::stringres=ptree.get<std::string>(JSON_TAG_CODE);log_out_res=res.compare(JSON_VAL_SUCC)==0?true:false;if(!log_out_res)LOG_ERROR(L"服务器退出处理失败,返回结果为:"+str_2_wstr(ptree.get<std::string>(JSON_TAG_MSG)));}catch(...){LOG_ERROR(L"解析服务器返回的退出信息时出错!请确认返回数据不为空,返回的数据格式为正确的Json格式!");returnfalse;}returnlog_out_res;}voidCMainFrame::ShowUserMessageDlg(){m_user_msg_monitor.Stop();//Stopmonitoringbeforelaunchingthemsgviewdialog.RECTrect;GetClientRect(&rect);ClientToScreen(&rect);CUserMsgView(rect).DoModal();m_user_msg_monitor.Start();//Recovermonitoring.}std::stringCMainFrame::MenuUrl(uint32_tmenu_res_id)const{auto&url_cfg=URLConfig::Instance();returnurl_cfg.FullHost()+m_menu_res_auth_manager.MenuItems().at(menu_res_id).url_path;}std::stringCMainFrame::WinHttpGet(conststd::string&url_path)const{constuint32_tkHTTPOK=200;auto&url_cfg=URLConfig::Instance();WinHttpwin_http;win_http.ConnectHost(url_cfg.Host(),url_cfg.Port(),url_cfg.IsHttps());auto&request=win_http.OpenRequest(WinHttp::Method::GET,url_path);if(url_cfg.IsHttps()){auto&app_cfg=ApplicationConfig::Instance();request.SetClientCertificate(app_cfg.ClientCertStore(),app_cfg.ClientCertSubject());}request.SetCookies(Session::Instance().Cookies());request.Send();uint32_tstatus_code=request.GetResponseStatus();if(kHTTPOK!=status_code){std::stringerr_msg="网络请求错误! 错误码: "+std::to_string(status_code);throwstd::exception(err_msg.c_str());}std::stringresponse_body=request.ReadResponseBody();if(response_body.empty())throwstd::exception("获取服务器响应数据失败,请确保网络连接正常");returnresponse_body;}LRESULTCMainFrame::OnCrashClose(WPARAMwParam,LPARAMlParam){if(!m_is_view_closing){if(!Session::Instance().IsExpired())//Onlypromptnotificationinloggedinstate.{if(!LogOut()){MessageBox(L"退出系统失败,若无法重新登录请联系维护人员!",L"退出系统提示!",MB_OK|MB_ICONWARNING);LOG_ERROR(L"崩溃时,服务端退出请求处理失败。程序关闭。");}elseLOG_TRACE(L"退出崩溃系统成功。");}/*RequestCETradeClientViewtoclose.thiswillmakeviewtoexitcef,andcefwillsendwm_closemessagetothisframwindow.*/m_view.SendMessage(WM_CLOSE);m_is_view_closing=true;//Enablenexttimeclose.}m_user_msg_monitor.Stop();LOG_TRACE(L"崩溃程序关闭。");CFrameWnd::OnClose();return0;}voidCMainFrame::OnTimer(UINT_PTRnIDEvent){CStringsTime;