Merge branch 'liuyang' into clh
# Conflicts:
# SourceCode/Bond/BondEq/AxisSettingsDlg.cpp
# SourceCode/Bond/BondEq/AxisSettingsDlg.h
# SourceCode/Bond/BondEq/BondEq.rc
# SourceCode/Bond/BondEq/BondEq.vcxproj
# SourceCode/Bond/BondEq/BondEqDlg.cpp
# SourceCode/Bond/BondEq/Model.cpp
# SourceCode/Bond/BondEq/Resource.h
# SourceCode/Bond/x64/Debug/Config/BondEq.db
已重命名1个文件
已添加20个文件
已修改11个文件
已删除1个文件
| | |
| | | #if _MSC_VER >= 1000 |
| | | #pragma once |
| | | #endif // _MSC_VER >= 1000 |
| | | // Label.h : header file |
| | | // |
| | | |
| | | #include <functional> |
| | | |
| | | ///////////////////////////////////////////////////////////////////////////// |
| | | // CBLLabel window |
| | | enum FlashType {None, Text, Background }; |
| | | enum FlashType { None, Text, Background }; |
| | | enum TextAlign { AlignLeft, AlignCenter, AlignRight }; |
| | | |
| | | class AFX_EXT_CLASS CBLLabel : public CStatic |
| | | { |
| | | // Construction |
| | | public: |
| | | CBLLabel(); |
| | | CBLLabel& SetBkColor(COLORREF crBkgnd); |
| | | CBLLabel& SetTextColor(COLORREF crText); |
| | | CBLLabel& SetText(const CString& strText); |
| | | CBLLabel& SetFontBold(BOOL bBold); |
| | | CBLLabel& SetFontName(const CString& strFont); |
| | | CBLLabel& SetFontUnderline(BOOL bSet); |
| | | CBLLabel& SetFontItalic(BOOL bSet); |
| | | CBLLabel& SetFontSize(int nSize); |
| | | CBLLabel& SetSunken(BOOL bSet); |
| | | CBLLabel& SetBorder(BOOL bSet); |
| | | CBLLabel& FlashText(BOOL bActivate); |
| | | CBLLabel& FlashBackground(BOOL bActivate); |
| | | CBLLabel& SetLink(BOOL bLink); |
| | | CBLLabel& SetLinkCursor(HCURSOR hCursor); |
| | | DECLARE_DYNCREATE(CBLLabel) // æ¯æå¨æå建 |
| | | |
| | | // Attributes |
| | | public: |
| | | // æé 䏿æ |
| | | CBLLabel(); |
| | | virtual ~CBLLabel(); |
| | | |
| | | void SetClickCallback(std::function<void()> callback); // 设置ç¹å»äºä»¶çåè°å½æ° |
| | | |
| | | // 屿§è®¾ç½®æ¥å£ |
| | | CBLLabel& SetBkColor(COLORREF crBkgnd); // è®¾ç½®èæ¯é¢è² |
| | | CBLLabel& SetTextColor(COLORREF crText); // è®¾ç½®ææ¬é¢è² |
| | | CBLLabel& SetText(const CString& strText); // è®¾ç½®ææ¬å
容 |
| | | CBLLabel& SetFontBold(BOOL bBold); // 设置åä½å ç² |
| | | CBLLabel& SetFontName(const CString& strFont); // 设置åä½åç§° |
| | | CBLLabel& SetFontUnderline(BOOL bSet); // 设置ä¸å线 |
| | | CBLLabel& SetFontItalic(BOOL bSet); // 设置æä½ |
| | | CBLLabel& SetFontSize(int nSize); // 设置åä½å¤§å° |
| | | CBLLabel& SetAlignment(TextAlign alignment); // è®¾ç½®ææ¬å¯¹é½æ¹å¼ |
| | | CBLLabel& SetDynamicFont(BOOL bDynamic); // 设置æ¯å¦å¨æè°æ´åä½ |
| | | CBLLabel& FlashText(BOOL bActivate); // éªçææ¬ |
| | | CBLLabel& FlashBackground(BOOL bActivate); // éªçèæ¯ |
| | | CBLLabel& SetLink(BOOL bLink); // 设置æ¯å¦å¯ç¨è¶
龿¥ |
| | | CBLLabel& SetLinkCursor(HCURSOR hCursor); // 设置è¶
龿¥å
æ |
| | | |
| | | protected: |
| | | void ReconstructFont(); |
| | | COLORREF m_crText; |
| | | HBRUSH m_hBrush; |
| | | HBRUSH m_hwndBrush; |
| | | LOGFONT m_lf; |
| | | CFont m_font; |
| | | CString m_strText; |
| | | BOOL m_bState; |
| | | BOOL m_bTimer; |
| | | BOOL m_bLink; |
| | | FlashType m_Type; |
| | | HCURSOR m_hCursor; |
| | | // Operations |
| | | public: |
| | | // Overrides |
| | | // ClassWizard generated virtual function overrides |
| | | //{{AFX_VIRTUAL(CBLLabel) |
| | | //}}AFX_VIRTUAL |
| | | // å·¥å
·å½æ° |
| | | void ReconstructFont(); // éæ°æé åä½ |
| | | void UpdateFontSize(); // å¨æè°æ´åä½å¤§å° |
| | | virtual void OnPaint(); // èªå®ä¹ç»å¶ææ¬ |
| | | |
| | | // Implementation |
| | | public: |
| | | virtual ~CBLLabel(); |
| | | // 屿§ |
| | | COLORREF m_crText; // ææ¬é¢è² |
| | | COLORREF m_crBkColor; // èæ¯é¢è² |
| | | HBRUSH m_hBrush; // èæ¯ç»å· |
| | | LOGFONT m_lf; // åä½ä¿¡æ¯ |
| | | CFont m_font; // åä½å¯¹è±¡ |
| | | CString m_strText; // ææ¬å
容 |
| | | BOOL m_bState; // ç¶æï¼ç¨äºéªç |
| | | BOOL m_bTimer; // 宿¶å¨ç¶æ |
| | | BOOL m_bLink; // æ¯å¦ä¸ºè¶
龿¥ |
| | | BOOL m_bDynamicFont; // æ¯å¦å¨æè°æ´åä½å¤§å° |
| | | TextAlign m_alignment; // ææ¬å¯¹é½æ¹å¼ |
| | | FlashType m_Type; // éªçç±»å |
| | | HCURSOR m_hCursor; // è¶
龿¥å
æ |
| | | std::function<void()> m_clickCallback; // ç¹å»äºä»¶çåè°å½æ° |
| | | |
| | | // Generated message map functions |
| | | protected: |
| | | //{{AFX_MSG(CBLLabel) |
| | | afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor); |
| | | afx_msg void OnTimer(UINT_PTR nIDEvent); |
| | | afx_msg void OnLButtonDown(UINT nFlags, CPoint point); |
| | | afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); |
| | | //}}AFX_MSG |
| | | // MFC æ¶æ¯æ å° |
| | | virtual HBRUSH CtlColor(CDC* pDC, UINT nCtlColor); // èæ¯åææ¬é¢è²è®¾ç½® |
| | | afx_msg void OnTimer(UINT_PTR nIDEvent); // 宿¶å¨äºä»¶ |
| | | afx_msg void OnLButtonDown(UINT nFlags, CPoint point); // é¼ æ ç¹å»äºä»¶ |
| | | afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); // 设置å
æ äºä»¶ |
| | | |
| | | DECLARE_MESSAGE_MAP() |
| | | DECLARE_MESSAGE_MAP() |
| | | }; |
| | | |
| | | ///////////////////////////////////////////////////////////////////////////// |
| | | |
| | | //{{AFX_INSERT_LOCATION}} |
| | | // Microsoft Developer Studio will insert additional declarations immediately before the previous line. |
| | | |
| | | #endif // !defined(AFX_BLLABEL_H__A4EABEC5_2E8C_11D1_B79F_00805F9ECE10__INCLUDED_) |
| | |
| | | <Optimization>Disabled</Optimization> |
| | | <PreprocessorDefinitions>_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
| | | <SDLCheck>true</SDLCheck> |
| | | <AdditionalIncludeDirectories>.;.\View;.\DBManager;..\DatabaseSDK\include;..\BLControlsSDK\include;..\BLControlsSDK\GridControl;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
| | | <AdditionalIncludeDirectories>.;.\View;.\DBManager;.\FileManager;..\DatabaseSDK\include;..\BLControlsSDK\include;..\BLControlsSDK\GridControl;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> |
| | | </ClCompile> |
| | | <Link> |
| | | <SubSystem>Windows</SubSystem> |
| | |
| | | <ClInclude Include="Alarm.h" /> |
| | | <ClInclude Include="AlarmMonitor.h" /> |
| | | <ClInclude Include="ApredTreeCtrl.h" /> |
| | | <ClInclude Include="AxisSettingsDlg.h" /> |
| | | <ClInclude Include="BaseSetPage.h" /> |
| | | <ClInclude Include="BlButton.h" /> |
| | | <ClInclude Include="BondEq.h" /> |
| | |
| | | <ClInclude Include="Common.h" /> |
| | | <ClInclude Include="Configuration.h" /> |
| | | <ClInclude Include="CPanelProject.h" /> |
| | | <ClInclude Include="DBManager\AxisManager.h" /> |
| | | <ClInclude Include="DBManager\SystemLogManager.h" /> |
| | | <ClInclude Include="DBManager\UserManager.h" /> |
| | | <ClInclude Include="EQState.h" /> |
| | | <ClInclude Include="EQStateMonitor.h" /> |
| | | <ClInclude Include="FileManager\IOManager.h" /> |
| | | <ClInclude Include="FileManager\pugiconfig.hpp" /> |
| | | <ClInclude Include="FileManager\pugixml.hpp" /> |
| | | <ClInclude Include="FileManager\RecipeManager.h" /> |
| | | <ClInclude Include="GB2860SQLite.h" /> |
| | | <ClInclude Include="HmTab.h" /> |
| | | <ClInclude Include="HmVerticalTab.h" /> |
| | | <ClInclude Include="HorizontalLine.h" /> |
| | | <ClInclude Include="InputDialog.h" /> |
| | | <ClInclude Include="Intent.h" /> |
| | | <ClInclude Include="LoadMonitor.h" /> |
| | | <ClInclude Include="Log.h" /> |
| | |
| | | <ClInclude Include="targetver.h" /> |
| | | <ClInclude Include="ToolUnits.h" /> |
| | | <ClInclude Include="TopToolbar.h" /> |
| | | <ClInclude Include="UserManagerDlg.h" /> |
| | | <ClInclude Include="VerticalLine.h" /> |
| | | <ClInclude Include="View\AxisSettingsDlg.h" /> |
| | | <ClInclude Include="View\ChangePasswordDlg.h" /> |
| | | <ClInclude Include="View\IOMonitoringDlg.h" /> |
| | | <ClInclude Include="View\LoginDlg.h" /> |
| | | <ClInclude Include="View\SystemLogManagerDlg.h" /> |
| | | <ClInclude Include="View\UserManagerDlg.h" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ClCompile Include="CPLC.cpp" /> |
| | |
| | | <ClCompile Include="Alarm.cpp" /> |
| | | <ClCompile Include="AlarmMonitor.cpp" /> |
| | | <ClCompile Include="ApredTreeCtrl.cpp" /> |
| | | <ClCompile Include="AxisSettingsDlg.cpp" /> |
| | | <ClCompile Include="BaseSetPage.cpp" /> |
| | | <ClCompile Include="BlButton.cpp" /> |
| | | <ClCompile Include="BondEq.cpp" /> |
| | |
| | | <ClCompile Include="CProjectPageRemoteEqs.cpp" /> |
| | | <ClCompile Include="Configuration.cpp" /> |
| | | <ClCompile Include="CPanelProject.cpp" /> |
| | | <ClCompile Include="DBManager\AxisManager.cpp" /> |
| | | <ClCompile Include="DBManager\SystemLogManager.cpp" /> |
| | | <ClCompile Include="DBManager\UserManager.cpp" /> |
| | | <ClCompile Include="EQState.cpp" /> |
| | | <ClCompile Include="EQStateMonitor.cpp" /> |
| | | <ClCompile Include="FileManager\IOManager.cpp" /> |
| | | <ClCompile Include="FileManager\pugixml.cpp"> |
| | | <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader> |
| | | </ClCompile> |
| | | <ClCompile Include="FileManager\RecipeManager.cpp" /> |
| | | <ClCompile Include="GB2860SQLite.cpp" /> |
| | | <ClCompile Include="HmTab.cpp" /> |
| | | <ClCompile Include="HmVerticalTab.cpp" /> |
| | | <ClCompile Include="HorizontalLine.cpp" /> |
| | | <ClCompile Include="InputDialog.cpp" /> |
| | | <ClCompile Include="Intent.cpp" /> |
| | | <ClCompile Include="LoadMonitor.cpp" /> |
| | | <ClCompile Include="Log.cpp" /> |
| | |
| | | </ClCompile> |
| | | <ClCompile Include="ToolUnits.cpp" /> |
| | | <ClCompile Include="TopToolbar.cpp" /> |
| | | <ClCompile Include="UserManagerDlg.cpp" /> |
| | | <ClCompile Include="VerticalLine.cpp" /> |
| | | <ClCompile Include="View\AxisSettingsDlg.cpp" /> |
| | | <ClCompile Include="View\ChangePasswordDlg.cpp" /> |
| | | <ClCompile Include="View\IOMonitoringDlg.cpp" /> |
| | | <ClCompile Include="View\LoginDlg.cpp" /> |
| | | <ClCompile Include="View\SystemLogManagerDlg.cpp" /> |
| | | <ClCompile Include="View\UserManagerDlg.cpp" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ResourceCompile Include="BondEq.rc" /> |
| | |
| | | #include "afxdialogex.h" |
| | | #include "Common.h" |
| | | #include "CBonder.h" |
| | | #include "ToolUnits.h" |
| | | #include "SettingsDlg.h" |
| | | #include "UserManager.h" |
| | | #include "InputDialog.h" |
| | | #include "LoginDlg.h" |
| | | #include "ChangePasswordDlg.h" |
| | | #include "UserManagerDlg.h" |
| | | #include "SystemLogManagerDlg.h" |
| | | |
| | | // test |
| | | #include "AxisSettingsDlg.h" |
| | | #include "UserManagerDlg.h" |
| | | |
| | | #include "IOMonitoringDlg.h" |
| | | |
| | | #ifdef _DEBUG |
| | | #define new DEBUG_NEW |
| | |
| | | SetTimer(1, 60000, nullptr); |
| | | #endif |
| | | userManager.loadSession(); |
| | | std::unique_ptr<BL::Database>& db = userManager.getDatabaseInstance(); |
| | | |
| | | // 设置è¿è¡æ¥å¿æ¨¡åçæ°æ®åºè¿æ¥ |
| | | SystemLogManager& logManager = SystemLogManager::getInstance(); |
| | | logManager.setDatabase(db.get()); |
| | | |
| | | // åå§åè¿è¡æ¥å¿è¡¨ |
| | | try { |
| | | if (!logManager.initializeLogTable()) { |
| | | AfxMessageBox("åå§åç³»ç»æ¥å¿æ¨¡å失败ï¼"); |
| | | return FALSE; |
| | | } |
| | | } |
| | | catch (const std::exception& ex) { |
| | | CString errorMsg; |
| | | errorMsg.Format(_T("åå§åç³»ç»æ¥å¿æ¨¡å失败ï¼%s"), CString(ex.what())); |
| | | AfxMessageBox(errorMsg, MB_ICONERROR); |
| | | return FALSE; |
| | | } |
| | | |
| | | // 设置é
æ¹æä»¶å¤¹è·¯å¾ |
| | | RecipeManager& recipeManager = RecipeManager::getInstance(); |
| | | std::string strRecipePath = CToolUnits::getCurrentExePath() + _T("\\Recipe"); |
| | | CToolUnits::createDir(strRecipePath.c_str()); |
| | | recipeManager.setRecipeFolder(strRecipePath); |
| | | |
| | | |
| | | // èå |
| | |
| | | InitRxWindows(); |
| | | |
| | | |
| | | // ç»å½ç®¡ç |
| | | if (userManager.isLoggedIn()) { |
| | | m_pTopToolbar->SetOperatorBtnText(userManager.getCurrentUser().c_str()); |
| | | } |
| | | // æ´æ°ç»å½ç¶æ |
| | | UpdateLoginStatus(); |
| | | logManager.log(SystemLogManager::LogType::Info, _T("BondEqå¯å¨...")); |
| | | |
| | | |
| | | return TRUE; // é¤éå°ç¦ç¹è®¾ç½®å°æ§ä»¶ï¼å¦åè¿å TRUE |
| | |
| | | UserManager::getInstance().terminateIdleDetection(); |
| | | KillTimer(1); |
| | | #endif |
| | | |
| | | SystemLogManager::getInstance().log(SystemLogManager::LogType::Info, _T("BondEqå
³é...")); |
| | | } |
| | | |
| | | void CBondEqDlg::OnSize(UINT nType, int cx, int cy) |
| | |
| | | CAxisSettingsDlg axisDlg; |
| | | axisDlg.SetPLC(theApp.m_model.getBonder().getPLC("PLC(1)")); |
| | | axisDlg.DoModal(); |
| | | // Cavity VacuumBake AfterBake AOI |
| | | CIOMonitoringDlg dlg; |
| | | dlg.SetIOManager("Cavity"); |
| | | dlg.SetPLC(theApp.m_model.getBonder().getPLC("PLC(1)")); |
| | | dlg.DoModal(); |
| | | |
| | | //CAxisSettingsDlg dlg; |
| | | //dlg.SetPLC(theApp.m_model.getBonder().getPLC("PLC(1)")); |
| | | //dlg.SetRecipeName(_T("Default")); |
| | | //dlg.DoModal(); |
| | | |
| | | /* |
| | | CSettingsDlg dlg; |
| | |
| | | LRESULT CBondEqDlg::OnToolbarBtnClicked(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | int id = (int)lParam; |
| | | SystemLogManager& logManager = SystemLogManager::getInstance(); |
| | | if (id == IDC_BUTTON_RUN || id == IDC_BUTTON_STOP || id == IDC_BUTTON_SETTINGS) |
| | | { |
| | | CInputDialog inputDialog(_T("éªè¯ç¨æ·"), _T("请è¾å
¥ç¨æ·å¯ç ï¼")); |
| | | if (inputDialog.DoModal() != IDOK) { |
| | | AfxMessageBox(_T("åæ¶éªè¯ï¼")); |
| | | return 0; |
| | | } |
| | | |
| | | CString inputText = inputDialog.GetInputText(); |
| | | std::string strPass = UserManager::getInstance().getCurrentPass(); |
| | | if (inputText.Compare(strPass.c_str()) != 0) { |
| | | AfxMessageBox(_T("å¯ç é误ï¼")); |
| | | logManager.log(SystemLogManager::LogType::Info, _T("éªè¯æ¶ï¼å¯ç é误ï¼")); |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | if (id == IDC_BUTTON_RUN) { |
| | | m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(FALSE); |
| | | m_pTopToolbar->GetBtn(IDC_BUTTON_STOP)->EnableWindow(TRUE); |
| | | logManager.log(SystemLogManager::LogType::Operation, _T("è¿è¡...")); |
| | | } |
| | | else if (id == IDC_BUTTON_STOP) { |
| | | m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(TRUE); |
| | | m_pTopToolbar->GetBtn(IDC_BUTTON_STOP)->EnableWindow(FALSE); |
| | | logManager.log(SystemLogManager::LogType::Operation, _T("Í£Ö¹...")); |
| | | } |
| | | else if (id == IDC_BUTTON_SETTINGS) { |
| | | CSettingsDlg dlg; |
| | |
| | | int menuId = (int)wParam; |
| | | UserManager& userManager = UserManager::getInstance(); |
| | | if (menuId == 0) { |
| | | ShowLoginDlg(); |
| | | CLoginDlg loginDlg; |
| | | loginDlg.DoModal(); |
| | | } |
| | | else if (1 == menuId) { |
| | | CChangePasswordDlg changePasswordDlg; |
| | | changePasswordDlg.DoModal(); |
| | | } |
| | | else if (2 == menuId) { |
| | | CUserManagerDlg dlg; |
| | | if (dlg.DoModal()!= IDOK) { |
| | | logManager.log(SystemLogManager::LogType::Operation, _T("ç¨æ·ç®¡çç颿ä½è¢«åæ¶ï¼")); |
| | | } |
| | | } |
| | | else if (3 == menuId) { |
| | | CSystemLogManagerDlg dlg; |
| | | dlg.DoModal(); |
| | | } |
| | | else if (4 == menuId) { |
| | | int ret = AfxMessageBox(_T("æ¯å¦åæ¢ç¨æ·ï¼åæ¢ç¨æ·ä¼éåºå½åè´¦å·ï¼"), MB_OKCANCEL | MB_ICONEXCLAMATION); |
| | | if (ret != IDOK) { |
| | | return 0; |
| | | } |
| | | |
| | | logManager.log(SystemLogManager::LogType::Operation, _T("ç¡®è®¤åæ¢è§è²ï¼")); |
| | | if (userManager.isLoggedIn()) { |
| | | logManager.log(SystemLogManager::LogType::Info, _T("éåºç»å½ï¼")); |
| | | userManager.logout(); |
| | | } |
| | | |
| | | ShowLoginDlg(); |
| | | CLoginDlg loginDlg; |
| | | loginDlg.DoModal(); |
| | | } |
| | | else if (2 == menuId) { |
| | | // test |
| | | CUserManagerDlg dlg; |
| | | dlg.DoModal(); |
| | | else { |
| | | CString cstrMessage; |
| | | cstrMessage.Format(_T("æ¯å¦éåºç¨æ· [%s]ï¼"), userManager.getCurrentUser().c_str()); |
| | | int ret = AfxMessageBox(_T(cstrMessage), MB_OKCANCEL | MB_ICONEXCLAMATION); |
| | | if (ret != IDOK) { |
| | | return 0; |
| | | } |
| | | |
| | | logManager.log(SystemLogManager::LogType::Info, _T("éåºç»å½ï¼")); |
| | | userManager.logout(); |
| | | } |
| | | |
| | | UpdateLoginStatus(); |
| | | } |
| | | |
| | | return 0; |
| | |
| | | return pDlg; |
| | | } |
| | | |
| | | void CBondEqDlg::ShowLoginDlg() |
| | | void CBondEqDlg::UpdateLoginStatus() |
| | | { |
| | | CLoginDlg loginDlg; |
| | | loginDlg.DoModal(); |
| | | |
| | | HMENU hMenu = m_pTopToolbar->GetOperatorMenu(); |
| | | UserManager& userManager = UserManager::getInstance(); |
| | | if (userManager.isLoggedIn()) |
| | | { |
| | | ::EnableMenuItem(hMenu, ID_OPEATOR_LOGIN, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); |
| | | ::EnableMenuItem(hMenu, ID_OPERATOR_CHANGE_PASSWORD, MF_BYCOMMAND | MF_ENABLED); |
| | | ::EnableMenuItem(hMenu, ID_OPERATOR_SYSTEM_LOG, MF_BYCOMMAND | MF_ENABLED); |
| | | ::EnableMenuItem(hMenu, ID_OPEATOR_SWITCH, MF_BYCOMMAND | MF_ENABLED); |
| | | ::EnableMenuItem(hMenu, ID_OPERATOR_LOGOUT, MF_BYCOMMAND | MF_ENABLED); |
| | | |
| | | if (userManager.getCurrentUserRole() == UserRole::SuperAdmin) { |
| | | ::EnableMenuItem(hMenu, ID_OPEATOR_USER_MANAGER, MF_BYCOMMAND | MF_ENABLED); |
| | | } |
| | | else { |
| | | ::EnableMenuItem(hMenu, ID_OPEATOR_USER_MANAGER, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); |
| | | } |
| | | |
| | | m_pTopToolbar->SetOperatorBtnText(userManager.getCurrentUser().c_str()); |
| | | } |
| | | else { |
| | | ::EnableMenuItem(hMenu, ID_OPEATOR_LOGIN, MF_BYCOMMAND | MF_ENABLED); |
| | | ::EnableMenuItem(hMenu, ID_OPERATOR_CHANGE_PASSWORD, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); |
| | | ::EnableMenuItem(hMenu, ID_OPEATOR_USER_MANAGER, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); |
| | | ::EnableMenuItem(hMenu, ID_OPERATOR_SYSTEM_LOG, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); |
| | | ::EnableMenuItem(hMenu, ID_OPEATOR_SWITCH, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); |
| | | ::EnableMenuItem(hMenu, ID_OPERATOR_LOGOUT, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); |
| | | |
| | | m_pTopToolbar->SetOperatorBtnText(_T("æªç»å½")); |
| | | } |
| | | } |
| | |
| | | void CloseView(CBaseView* pView); |
| | | CHomeDialog* CreateHomeDlg(); |
| | | CBaseView* CreateRemoteEqView(BEQ::IRemoteEquipment* pEquipment); |
| | | void ShowLoginDlg(); |
| | | void UpdateLoginStatus(); |
| | | |
| | | private: |
| | | COLORREF m_crBkgnd; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include "AxisManager.h" |
| | | #include <sstream> |
| | | #include <stdexcept> |
| | | #include <mutex> |
| | | |
| | | // éææååå§å |
| | | std::mutex AxisManager::m_mutex; |
| | | |
| | | // è·ååä¾å®ä¾ |
| | | AxisManager& AxisManager::getInstance() { |
| | | static AxisManager instance; |
| | | return instance; |
| | | } |
| | | |
| | | AxisManager::AxisManager() : m_pDB(nullptr) {} |
| | | |
| | | AxisManager::~AxisManager() { |
| | | m_pDB = nullptr; |
| | | } |
| | | |
| | | // è®¾ç½®æ°æ®åºè¿æ¥ |
| | | void AxisManager::setDatabase(BL::Database* db) { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | m_pDB = db; |
| | | } |
| | | |
| | | // åå§å轴表åå®ä½ç¹è¡¨ |
| | | bool AxisManager::initializeTables() { |
| | | if (!m_pDB) { |
| | | throw std::runtime_error("Database connection is not set."); |
| | | } |
| | | |
| | | const std::string createAxesTableQuery = R"( |
| | | CREATE TABLE IF NOT EXISTS axes ( |
| | | axis_id INTEGER PRIMARY KEY, |
| | | axis_no TEXT NOT NULL, |
| | | description TEXT NOT NULL, |
| | | start_address TEXT, |
| | | jog_distance REAL, |
| | | manual_speed REAL, |
| | | max_manual_speed REAL, |
| | | min_manual_speed REAL, |
| | | auto_speed REAL, |
| | | max_auto_speed REAL, |
| | | min_auto_speed REAL, |
| | | acceleration_time REAL, |
| | | deceleration_time REAL |
| | | ) |
| | | )"; |
| | | |
| | | const std::string createPositionsTableQuery = R"( |
| | | CREATE TABLE IF NOT EXISTS positions ( |
| | | position_id INTEGER PRIMARY KEY AUTOINCREMENT, |
| | | axis_id INTEGER NOT NULL, |
| | | description TEXT, |
| | | position_value REAL, |
| | | plc_address TEXT, |
| | | FOREIGN KEY (axis_id) REFERENCES axes(axis_id) |
| | | ) |
| | | )"; |
| | | |
| | | return m_pDB->executeQuery(createAxesTableQuery) && m_pDB->executeQuery(createPositionsTableQuery); |
| | | } |
| | | |
| | | // åå§åé»è®¤æ°æ® |
| | | bool AxisManager::initializeDefaultData() { |
| | | if (!m_pDB) { |
| | | throw std::runtime_error("Database connection is not set."); |
| | | } |
| | | |
| | | for (int axisId = 1; axisId <= 12; ++axisId) { |
| | | std::ostringstream axisQuery; |
| | | axisQuery << "INSERT OR IGNORE INTO axes (axis_id, axis_no, description, start_address, jog_distance, manual_speed, " |
| | | << "max_manual_speed, min_manual_speed, auto_speed, max_auto_speed, min_auto_speed, acceleration_time, deceleration_time) " |
| | | << "VALUES (" << axisId << ", 'M" << axisId * 10 << "', 'è½´ " << axisId << "', 'D" << (5090 + axisId * 2) << "', " |
| | | << "0.5, 10.0, 20.0, 5.0, 15.0, 25.0, 10.0, 0.2, 0.3)"; |
| | | m_pDB->executeQuery(axisQuery.str()); |
| | | } |
| | | |
| | | for (int axisId = 1; axisId <= 12; ++axisId) { |
| | | for (int positionIndex = 1; positionIndex <= 25; ++positionIndex) { |
| | | std::ostringstream positionQuery; |
| | | positionQuery << "INSERT OR IGNORE INTO positions (axis_id, description, position_value, plc_address) " |
| | | << "VALUES (" << axisId << ", 'å®ä½ç¹ " << positionIndex << "', " << (positionIndex * 10.0) << ", " |
| | | << "'D" << (5240 + positionIndex * 2) << "')"; |
| | | m_pDB->executeQuery(positionQuery.str()); |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | // æ·»å ææ´æ°è½´ä¿¡æ¯ |
| | | bool AxisManager::saveAxis(int axisId, const std::string& axisNo, const std::string& description, |
| | | const std::string& startAddress, double jogDistance, double manualSpeed, |
| | | double maxManualSpeed, double minManualSpeed, double autoSpeed, |
| | | double maxAutoSpeed, double minAutoSpeed, double accelerationTime, |
| | | double decelerationTime) { |
| | | if (!m_pDB) { |
| | | throw std::runtime_error("Database connection is not set."); |
| | | } |
| | | |
| | | std::ostringstream query; |
| | | query << "INSERT INTO axes (axis_id, axis_no, description, start_address, jog_distance, manual_speed, " |
| | | << "max_manual_speed, min_manual_speed, auto_speed, max_auto_speed, min_auto_speed, acceleration_time, deceleration_time) " |
| | | << "VALUES (" << axisId << ", '" << axisNo << "', '" << description << "', '" << startAddress << "', " |
| | | << jogDistance << ", " << manualSpeed << ", " << maxManualSpeed << ", " << minManualSpeed << ", " << autoSpeed |
| | | << ", " << maxAutoSpeed << ", " << minAutoSpeed << ", " << accelerationTime << ", " << decelerationTime << ") " |
| | | << "ON CONFLICT(axis_id) DO UPDATE SET " |
| | | << "axis_no=excluded.axis_no, description=excluded.description, start_address=excluded.start_address, " |
| | | << "jog_distance=excluded.jog_distance, manual_speed=excluded.manual_speed, max_manual_speed=excluded.max_manual_speed, " |
| | | << "min_manual_speed=excluded.min_manual_speed, auto_speed=excluded.auto_speed, max_auto_speed=excluded.max_auto_speed, " |
| | | << "min_auto_speed=excluded.min_auto_speed, acceleration_time=excluded.acceleration_time, deceleration_time=excluded.deceleration_time"; |
| | | |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | return m_pDB->executeQuery(query.str()); |
| | | } |
| | | |
| | | // è·ååä¸ªè½´ä¿¡æ¯ |
| | | std::vector<std::string> AxisManager::getAxis(int axisId) { |
| | | if (!m_pDB) { |
| | | throw std::runtime_error("Database connection is not set."); |
| | | } |
| | | |
| | | std::ostringstream query; |
| | | query << "SELECT * FROM axes WHERE axis_id = " << axisId; |
| | | |
| | | auto result = m_pDB->fetchResults(query.str()); |
| | | return !result.empty() ? result[0] : std::vector<std::string>(); |
| | | } |
| | | |
| | | // è·åææè½´ä¿¡æ¯ |
| | | std::vector<std::vector<std::string>> AxisManager::getAllAxes() { |
| | | if (!m_pDB) { |
| | | throw std::runtime_error("Database connection is not set."); |
| | | } |
| | | |
| | | return m_pDB->fetchResults("SELECT * FROM axes ORDER BY axis_id"); |
| | | } |
| | | |
| | | // å 餿å®è½´ |
| | | bool AxisManager::deleteAxis(int axisId) { |
| | | if (!m_pDB) { |
| | | throw std::runtime_error("Database connection is not set."); |
| | | } |
| | | |
| | | std::ostringstream query; |
| | | query << "DELETE FROM axes WHERE axis_id = " << axisId; |
| | | |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | return m_pDB->executeQuery(query.str()); |
| | | } |
| | | |
| | | // æ·»å ææ´æ°å®ä½ç¹ |
| | | bool AxisManager::savePosition(int axisId, const std::string& description, double positionValue, const std::string& plcAddress) { |
| | | if (!m_pDB) { |
| | | throw std::runtime_error("Database connection is not set."); |
| | | } |
| | | |
| | | std::ostringstream query; |
| | | query << "INSERT INTO positions (axis_id, description, position_value, plc_address) VALUES (" |
| | | << axisId << ", '" << description << "', " << positionValue << ", '" << plcAddress << "') " |
| | | << "ON CONFLICT(axis_id) DO UPDATE SET " |
| | | << "description=excluded.description, position_value=excluded.position_value, plc_address=excluded.plc_address"; |
| | | |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | return m_pDB->executeQuery(query.str()); |
| | | } |
| | | |
| | | // è·åè½´çææå®ä½ç¹ |
| | | std::vector<std::vector<std::string>> AxisManager::getPositions(int axisId, int pageNumber, int pageSize) { |
| | | if (!m_pDB) { |
| | | throw std::runtime_error("Database connection is not set."); |
| | | } |
| | | |
| | | int offset = (pageNumber - 1) * pageSize; |
| | | std::ostringstream query; |
| | | query << "SELECT * FROM positions WHERE axis_id = " << axisId << " LIMIT " << pageSize << " OFFSET " << offset; |
| | | |
| | | return m_pDB->fetchResults(query.str()); |
| | | } |
| | | |
| | | // è·åå®ä½ç¹æ»æ° |
| | | int AxisManager::getTotalPositionCount(int axisId) { |
| | | if (!m_pDB) { |
| | | throw std::runtime_error("Database connection is not set."); |
| | | } |
| | | |
| | | std::ostringstream query; |
| | | query << "SELECT COUNT(*) FROM positions WHERE axis_id = " << axisId; |
| | | |
| | | auto result = m_pDB->fetchResults(query.str()); |
| | | return (!result.empty() && !result[0].empty()) ? std::stoi(result[0][0]) : 0; |
| | | } |
| | | |
| | | // å 餿å®å®ä½ç¹ |
| | | bool AxisManager::deletePosition(int positionId) { |
| | | if (!m_pDB) { |
| | | throw std::runtime_error("Database connection is not set."); |
| | | } |
| | | |
| | | std::ostringstream query; |
| | | query << "DELETE FROM positions WHERE position_id = " << positionId; |
| | | |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | return m_pDB->executeQuery(query.str()); |
| | | } |
| | | |
| | | // è·åææçè½´ID |
| | | std::vector<int> AxisManager::getUsedAxisIds() { |
| | | if (!m_pDB) { |
| | | throw std::runtime_error("Database connection is not set."); |
| | | } |
| | | |
| | | std::vector<int> usedAxisIds; |
| | | std::string query = "SELECT axis_id FROM axes ORDER BY axis_id"; |
| | | auto results = m_pDB->fetchResults(query); |
| | | |
| | | for (const auto& row : results) { |
| | | if (!row.empty()) { |
| | | usedAxisIds.push_back(std::stoi(row[0])); |
| | | } |
| | | } |
| | | |
| | | return usedAxisIds; |
| | | } |
| | | |
| | | // è·åææè½´çè½´NO |
| | | std::vector<std::string> AxisManager::getAllAxisNumbers() { |
| | | if (!m_pDB) { |
| | | throw std::runtime_error("Database connection is not set."); |
| | | } |
| | | |
| | | std::vector<std::string> axisNumbers; |
| | | std::string query = "SELECT axis_no FROM axes ORDER BY axis_id"; |
| | | auto results = m_pDB->fetchResults(query); |
| | | |
| | | for (const auto& row : results) { |
| | | if (!row.empty()) { |
| | | axisNumbers.push_back(row[0]); |
| | | } |
| | | } |
| | | |
| | | return axisNumbers; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #ifndef AXIS_MANAGER_H |
| | | #define AXIS_MANAGER_H |
| | | |
| | | #include <string> |
| | | #include <vector> |
| | | #include <mutex> |
| | | #include "Database.h" |
| | | |
| | | // 轴管çç±» |
| | | class AxisManager { |
| | | public: |
| | | // è·ååä¾å®ä¾ |
| | | static AxisManager& getInstance(); |
| | | |
| | | // è®¾ç½®æ°æ®åºè¿æ¥ |
| | | void setDatabase(BL::Database* db); |
| | | |
| | | // åå§å轴表åå®ä½ç¹è¡¨ |
| | | bool initializeTables(); |
| | | |
| | | // åå§åé»è®¤æ°æ® |
| | | bool initializeDefaultData(); |
| | | |
| | | // æ·»å ææ´æ°è½´ä¿¡æ¯ |
| | | bool saveAxis(int axisId, const std::string& axisNo, const std::string& description, |
| | | const std::string& startAddress, double jogDistance, double manualSpeed, |
| | | double maxManualSpeed, double minManualSpeed, double autoSpeed, |
| | | double maxAutoSpeed, double minAutoSpeed, double accelerationTime, |
| | | double decelerationTime); |
| | | |
| | | // è·ååä¸ªè½´ä¿¡æ¯ |
| | | std::vector<std::string> getAxis(int axisId); |
| | | |
| | | // è·åææè½´ä¿¡æ¯ |
| | | std::vector<std::vector<std::string>> getAllAxes(); |
| | | |
| | | // å 餿å®è½´ |
| | | bool deleteAxis(int axisId); |
| | | |
| | | // æ·»å ææ´æ°å®ä½ç¹ |
| | | bool savePosition(int axisId, const std::string& description, double positionValue, |
| | | const std::string& plcAddress); |
| | | |
| | | // è·åè½´çææå®ä½ç¹ |
| | | std::vector<std::vector<std::string>> getPositions(int axisId, int pageNumber, int pageSize); |
| | | |
| | | // è·åå®ä½ç¹æ»æ° |
| | | int getTotalPositionCount(int axisId); |
| | | |
| | | // å 餿å®å®ä½ç¹ |
| | | bool deletePosition(int positionId); |
| | | |
| | | // è·åææçè½´ID |
| | | std::vector<int> getUsedAxisIds(); |
| | | |
| | | // è·åææè½´çè½´NO |
| | | std::vector<std::string> getAllAxisNumbers(); |
| | | |
| | | private: |
| | | // ç§ææé 彿°åææå½æ° |
| | | AxisManager(); |
| | | ~AxisManager(); |
| | | |
| | | // ç¦æ¢æ·è´åèµå¼ |
| | | AxisManager(const AxisManager&) = delete; |
| | | AxisManager& operator=(const AxisManager&) = delete; |
| | | |
| | | // æ°æ®åºè¿æ¥ |
| | | BL::Database* m_pDB; |
| | | |
| | | // 线ç¨å®å
¨é |
| | | static std::mutex m_mutex; |
| | | }; |
| | | |
| | | #endif // AXIS_MANAGER_H |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include <sstream> |
| | | #include <iostream> |
| | | #include <stdexcept> |
| | | #include <ctime> |
| | | |
| | | // éææååå§å |
| | | std::mutex SystemLogManager::m_mutex; |
| | | |
| | | // è·ååä¾å®ä¾ |
| | | SystemLogManager& SystemLogManager::getInstance() { |
| | | static SystemLogManager instance; |
| | | return instance; |
| | | } |
| | | |
| | | // æé 彿° |
| | | SystemLogManager::SystemLogManager() : m_pDB(nullptr) {} |
| | | |
| | | // ææå½æ° |
| | | SystemLogManager::~SystemLogManager() { |
| | | m_pDB = nullptr; // æ¸
餿éå¼ç¨ |
| | | } |
| | | |
| | | // è®¾ç½®æ°æ®åºè¿æ¥ |
| | | void SystemLogManager::setDatabase(BL::Database* db) { |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | m_pDB = db; |
| | | } |
| | | |
| | | // åå§åæ¥å¿è¡¨ |
| | | bool SystemLogManager::initializeLogTable() { |
| | | if (!m_pDB) { |
| | | throw std::runtime_error("Database connection is not set."); |
| | | } |
| | | |
| | | const std::string createTableQuery = R"( |
| | | CREATE TABLE IF NOT EXISTS system_logs ( |
| | | id INTEGER PRIMARY KEY AUTOINCREMENT, |
| | | log_type TEXT NOT NULL, |
| | | event TEXT NOT NULL, |
| | | username TEXT NOT NULL, |
| | | timestamp DATETIME DEFAULT (datetime('now', 'localtime')) |
| | | ) |
| | | )"; |
| | | |
| | | return m_pDB->executeQuery(createTableQuery); |
| | | } |
| | | |
| | | // æ·»å æ¥å¿ï¼ä½¿ç¨å½åç¨æ·ï¼ |
| | | bool SystemLogManager::log(LogType logType, const std::string& event) { |
| | | if (!m_pDB) { |
| | | throw std::runtime_error("Database connection is not set."); |
| | | } |
| | | |
| | | cleanOldLogs(); |
| | | |
| | | std::string username = UserManager::getInstance().getCurrentUser(); |
| | | if (username.empty()) { |
| | | username = "SYSTEM"; |
| | | } |
| | | |
| | | std::ostringstream query; |
| | | query << "INSERT INTO system_logs (log_type, event, username) VALUES (" |
| | | << "'" << logTypeToString(logType) << "', " |
| | | << "'" << event << "', " |
| | | << "'" << username << "')"; |
| | | |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | return m_pDB->executeQuery(query.str()); |
| | | } |
| | | |
| | | // æ·»å æ¥å¿ï¼æå®ç¨æ·ï¼ |
| | | bool SystemLogManager::log(LogType logType, const std::string& event, const std::string& username) { |
| | | if (!m_pDB) { |
| | | throw std::runtime_error("Database connection is not set."); |
| | | } |
| | | |
| | | cleanOldLogs(); |
| | | |
| | | std::ostringstream query; |
| | | query << "INSERT INTO system_logs (log_type, event, username) VALUES (" |
| | | << "'" << logTypeToString(logType) << "', " |
| | | << "'" << event << "', " |
| | | << "'" << username << "')"; |
| | | |
| | | std::lock_guard<std::mutex> lock(m_mutex); |
| | | return m_pDB->executeQuery(query.str()); |
| | | } |
| | | |
| | | // è·åæ¥å¿å
容 |
| | | std::vector<std::vector<std::string>> SystemLogManager::getLogs(int startPosition, int count) { |
| | | if (!m_pDB) { |
| | | throw std::runtime_error("Database connection is not set."); |
| | | } |
| | | |
| | | std::ostringstream query; |
| | | if (startPosition == -1 && count == -1) { |
| | | query << "SELECT id, log_type, event, username, datetime(timestamp, 'localtime') FROM system_logs"; |
| | | } |
| | | else { |
| | | query << "SELECT id, log_type, event, username, datetime(timestamp, 'localtime') FROM system_logs " |
| | | << "LIMIT " << count << " OFFSET " << startPosition; |
| | | } |
| | | |
| | | return m_pDB->fetchResults(query.str()); |
| | | } |
| | | |
| | | // è·åçéåçæ¥å¿æ°æ® |
| | | std::vector<std::vector<std::string>> SystemLogManager::getFilteredLogs( |
| | | const std::string& logType, |
| | | const std::string& username, |
| | | const std::string& description, |
| | | const std::string& startTime, |
| | | const std::string& endTime, |
| | | int pageNumber, |
| | | int pageSize) |
| | | { |
| | | if (!m_pDB) { |
| | | throw std::runtime_error("Database connection is not set."); |
| | | } |
| | | |
| | | std::ostringstream query; |
| | | query << "SELECT id, log_type, event, username, datetime(timestamp, 'localtime') FROM system_logs WHERE 1=1"; |
| | | |
| | | if (logType != "ALL") { |
| | | query << " AND log_type = '" << logType << "'"; |
| | | } |
| | | if (username != "ALL") { |
| | | query << " AND username = '" << username << "'"; |
| | | } |
| | | if (!description.empty()) { |
| | | query << " AND event LIKE '%" << description << "%'"; |
| | | } |
| | | if (!startTime.empty()) { |
| | | query << " AND timestamp >= '" << startTime << "'"; |
| | | } |
| | | if (!endTime.empty()) { |
| | | query << " AND timestamp <= '" << endTime << "'"; |
| | | } |
| | | |
| | | int offset = (pageNumber - 1) * pageSize; |
| | | query << " ORDER BY timestamp DESC LIMIT " << pageSize << " OFFSET " << offset; |
| | | |
| | | return m_pDB->fetchResults(query.str()); |
| | | } |
| | | |
| | | // è·åç¬¦åæ¡ä»¶çæ¥å¿æ»æ° |
| | | int SystemLogManager::getTotalLogCount( |
| | | const std::string& logType, |
| | | const std::string& username, |
| | | const std::string& description, |
| | | const std::string& startTime, |
| | | const std::string& endTime) |
| | | { |
| | | if (!m_pDB) { |
| | | throw std::runtime_error("Database connection is not set."); |
| | | } |
| | | |
| | | std::ostringstream query; |
| | | query << "SELECT COUNT(*) FROM system_logs WHERE 1=1"; |
| | | |
| | | if (logType != "ALL") { |
| | | query << " AND log_type = '" << logType << "'"; |
| | | } |
| | | if (username != "ALL") { |
| | | query << " AND username = '" << username << "'"; |
| | | } |
| | | if (!description.empty()) { |
| | | query << " AND event LIKE '%" << description << "%'"; |
| | | } |
| | | if (!startTime.empty()) { |
| | | query << " AND timestamp >= '" << startTime << "'"; |
| | | } |
| | | if (!endTime.empty()) { |
| | | query << " AND timestamp <= '" << endTime << "'"; |
| | | } |
| | | |
| | | auto results = m_pDB->fetchResults(query.str()); |
| | | return (!results.empty() && !results[0].empty()) ? std::stoi(results[0][0]) : 0; |
| | | } |
| | | |
| | | // æ¸
çè¶
è¿æå®å¤©æ°çæ§æ¥å¿ |
| | | void SystemLogManager::cleanOldLogs(int daysToKeep) { |
| | | if (!m_pDB) { |
| | | throw std::runtime_error("Database connection is not set."); |
| | | } |
| | | |
| | | std::ostringstream query; |
| | | query << "DELETE FROM system_logs WHERE timestamp < datetime('now', '-" << daysToKeep << " days')"; |
| | | m_pDB->executeQuery(query.str()); |
| | | } |
| | | |
| | | // è½¬æ¢æ¥å¿ç±»å为å符串 |
| | | std::string SystemLogManager::logTypeToString(LogType logType) { |
| | | switch (logType) { |
| | | case LogType::Info: |
| | | return "ä¿¡æ¯"; |
| | | case LogType::Error: |
| | | return "é误"; |
| | | case LogType::Operation: |
| | | return "æä½"; |
| | | default: |
| | | return "δ֪"; |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #ifndef SYSTEM_LOG_MANAGER_H |
| | | #define SYSTEM_LOG_MANAGER_H |
| | | |
| | | #include <string> |
| | | #include <vector> |
| | | #include <mutex> |
| | | #include "Database.h" |
| | | |
| | | // ç³»ç»æ¥å¿ç®¡çç±» |
| | | class SystemLogManager { |
| | | public: |
| | | // æ¥å¿ç±»åå®ä¹ |
| | | enum class LogType { |
| | | Info, |
| | | Error, |
| | | Operation, |
| | | Unknown |
| | | }; |
| | | |
| | | // è·ååä¾å®ä¾ |
| | | static SystemLogManager& getInstance(); |
| | | |
| | | // è®¾ç½®æ°æ®åºè¿æ¥ |
| | | void setDatabase(BL::Database* db); |
| | | |
| | | // åå§åæ¥å¿è¡¨ |
| | | bool initializeLogTable(); |
| | | |
| | | // æ·»å æ¥å¿ |
| | | bool log(LogType logType, const std::string& event); |
| | | bool log(LogType logType, const std::string& event, const std::string& username); |
| | | |
| | | // è·åæ¥å¿å
容 |
| | | std::vector<std::vector<std::string>> getLogs(int startPosition = -1, int count = -1); |
| | | |
| | | // è·åçéåçæ¥å¿æ°æ® |
| | | std::vector<std::vector<std::string>> getFilteredLogs( |
| | | const std::string& logType, |
| | | const std::string& username, |
| | | const std::string& description, |
| | | const std::string& startTime, |
| | | const std::string& endTime, |
| | | int pageNumber, |
| | | int pageSize); |
| | | |
| | | // è·åç¬¦åæ¡ä»¶çæ¥å¿æ»æ° |
| | | int getTotalLogCount( |
| | | const std::string& logType, |
| | | const std::string& username, |
| | | const std::string& description, |
| | | const std::string& startTime, |
| | | const std::string& endTime); |
| | | |
| | | // æ¸
çè¶
è¿æå®å¤©æ°çæ§æ¥å¿ |
| | | void cleanOldLogs(int daysToKeep = 30); |
| | | |
| | | // è½¬æ¢æ¥å¿ç±»å为å符串 |
| | | static std::string logTypeToString(LogType logType); |
| | | |
| | | private: |
| | | // æé 彿°åææå½æ° |
| | | SystemLogManager(); |
| | | ~SystemLogManager(); |
| | | |
| | | // ç¦æ¢æ·è´åèµå¼ |
| | | SystemLogManager(const SystemLogManager&) = delete; |
| | | SystemLogManager& operator=(const SystemLogManager&) = delete; |
| | | |
| | | // æ°æ®åºè¿æ¥ |
| | | BL::Database* m_pDB = nullptr; |
| | | |
| | | // 线ç¨å®å
¨é |
| | | static std::mutex m_mutex; |
| | | }; |
| | | |
| | | #endif // SYSTEM_LOG_MANAGER_H |
| | |
| | | terminateIdleDetection(); |
| | | } |
| | | |
| | | // æä¾æ°æ®åºè¿æ¥ |
| | | std::unique_ptr<BL::Database>& UserManager::getDatabaseInstance() { |
| | | return m_pDB; |
| | | } |
| | | |
| | | // åå§åæ°æ®åºï¼åå»ºç¨æ·è¡¨å¹¶æå
¥åå§ç®¡çåç¨æ· |
| | | bool UserManager::initializeDatabase() { |
| | | std::string dbFilePath = getDatabaseFilePath(); |
| | |
| | | role INT NOT NULL, |
| | | session_timeout INT DEFAULT 30, |
| | | session_expiration INT DEFAULT 72, |
| | | last_login TIMESTAMP |
| | | last_login DATETIME DEFAULT (datetime('now', 'localtime')) |
| | | ) |
| | | )"; |
| | | m_pDB->executeQuery(createTableQuery); |
| | |
| | | return success; |
| | | } |
| | | |
| | | // è·åææç¨æ·åç§° |
| | | std::vector<std::string> UserManager::getUsernames() { |
| | | std::vector<std::string> usernames; |
| | | std::string query = "SELECT username FROM users"; |
| | | auto results = m_pDB->fetchResults(query); |
| | | |
| | | for (const auto& row : results) { |
| | | if (!row.empty()) { |
| | | usernames.push_back(row[0]); // è·åç¨æ·ååçå¼ |
| | | } |
| | | } |
| | | |
| | | return usernames; |
| | | } |
| | | |
| | | // è·åæå®ç¨æ·åçç¨æ·ä¿¡æ¯ |
| | | std::vector<std::string> UserManager::getUserInfo(const std::string& username) |
| | | { |
| | | // æå»ºæ¥è¯¢è¯å¥ |
| | | std::ostringstream query; |
| | | query << "SELECT username, password, role, session_timeout, session_expiration, last_login " |
| | | << "FROM users WHERE username = '" << username << "'"; |
| | | |
| | | // æ§è¡æ¥è¯¢å¹¶è·åç»æ |
| | | auto results = m_pDB->fetchResults(query.str()); |
| | | if (results.empty()) { |
| | | return {}; |
| | | } |
| | | |
| | | // è¿åæ¥è¯¢å°ç第ä¸è¡æ°æ® |
| | | return results[0]; |
| | | } |
| | | |
| | | // æ´æ°æåæ´»å¨æ¶é´ï¼ç¨äºæ æä½è¶
æ¶æ£æµ |
| | | void UserManager::updateActivityTime() { |
| | | m_tpLastActivity = std::chrono::system_clock::now(); |
| | |
| | | return m_strCurrentUser; |
| | | } |
| | | |
| | | // ä¿®æ¹å½åç»å½ç¨æ·å |
| | | void UserManager::setCurrentUser(const std::string& strName) { |
| | | m_strCurrentUser = strName; |
| | | } |
| | | |
| | | // è·åå½åç»å½ç¨æ·å¯ç |
| | | std::string UserManager::getCurrentPass() const { |
| | | return m_strCurrentPass; |
| | | } |
| | | |
| | | // ä¿®æ¹å½åç»å½ç¨æ·å¯ç |
| | | void UserManager::setCurrentPass(const std::string& strPass) { |
| | | m_strCurrentPass = strPass; |
| | | } |
| | | |
| | | // è·åå½åç»å½ç¨æ·è§è² |
| | | UserRole UserManager::getCurrentUserRole() const { |
| | | return m_enCurrentUserRole; |
| | | } |
| | | |
| | | // ä¿®æ¹å½åç»å½ç¨æ·è§è² |
| | | void UserManager::setCurrentUserRole(UserRole emRole) { |
| | | m_enCurrentUserRole = emRole; |
| | | } |
| | | |
| | | // è·åå½åç»å½ç¨æ·çæ æä½è¶
æ¶æ¶é´ |
| | | std::chrono::minutes UserManager::getSessionTimeout() const { |
| | | return m_tmSessionTimeout; |
| | |
| | | UserManager(const UserManager&) = delete; |
| | | UserManager& operator=(const UserManager&) = delete; |
| | | |
| | | // æä¾æ°æ®åºè¿æ¥ |
| | | std::unique_ptr<BL::Database>& getDatabaseInstance(); |
| | | |
| | | // ç¨æ·æä½ |
| | | bool login(const std::string& username, const std::string& password, bool rememberMe = false); |
| | | void logout(); |
| | |
| | | bool changeUserRole(const std::string& username, UserRole newRole); |
| | | bool changeUserSessionTimeout(const std::string& username, int newTimeoutMinutes); |
| | | bool changeUserSessionExpiration(const std::string& username, int newExpirationHours); |
| | | std::vector<std::string> getUsernames(); |
| | | std::vector<std::string> getUserInfo(const std::string& username); |
| | | |
| | | // ä¼è¯æä»¶æä½ |
| | | bool loadSession(); // ä»ä¼è¯æä»¶å è½½ä¼è¯ä¿¡æ¯ |
| | |
| | | // è·åå½åç»å½ç¨æ·å |
| | | std::string getCurrentUser() const; |
| | | |
| | | // ä¿®æ¹å½åç»å½ç¨æ·å |
| | | void setCurrentUser(const std::string& strName); |
| | | |
| | | // è·åå½åç»å½ç¨æ·å¯ç |
| | | std::string getCurrentPass() const; |
| | | |
| | | // ä¿®æ¹å½åç»å½ç¨æ·å¯ç |
| | | void setCurrentPass(const std::string& strPass); |
| | | |
| | | // è·åå½åç»å½ç¨æ·è§è² |
| | | UserRole getCurrentUserRole() const; |
| | | |
| | | // ä¿®æ¹å½åç»å½ç¨æ·è§è² |
| | | void setCurrentUserRole(UserRole emRole); |
| | | |
| | | // è·åå½åç»å½ç¨æ·çæ æä½è¶
æ¶æ¶é´ |
| | | std::chrono::minutes getSessionTimeout() const; |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include "IOManager.h" |
| | | #include <fstream> |
| | | #include <iostream> |
| | | #include "ToolUnits.h" |
| | | |
| | | IOManager::IOManager() { |
| | | m_directory = CToolUnits::getCurrentExePath() + _T("\\Config"); |
| | | if (!CToolUnits::isDirectory(m_directory)) { |
| | | CToolUnits::createDir(m_directory.c_str()); |
| | | } |
| | | } |
| | | |
| | | void IOManager::addMachine(const std::string& machineName, const std::vector<IOData>& data) { |
| | | m_machines[machineName] = data; |
| | | } |
| | | |
| | | void IOManager::addDefaultMachineData(const std::string& machineName) { |
| | | if (machineName == "Cavity") { |
| | | std::vector<IOData> defaultData = { |
| | | {"X1000", "Unit1_æ¥å EMO", "Y1010", "Unit1_åè²ç¯-红"}, |
| | | {"X1001", "Unit1_æ»è¿æ°å忣", "Y1011", "Unit1_åè²ç¯-é»"}, |
| | | {"X1002", "Unit1_伺æçµæçææ¥è¦", "Y1012", "Unit1_åè²ç¯-绿"}, |
| | | {"X1003", "Unit1_å ççµæçææ¥è¦", "Y1013", "Unit1_åè²ç¯-è"}, |
| | | {"X1004", "å®å
¨ç»§çµå¨æ£", "Y1014", "Unit1_è鸣å¨-1"}, |
| | | {"X1005", "", "Y1015", "Unit1_è鸣å¨-2"}, |
| | | {"X1006", "", "Y1016", "Unit1_è鸣å¨-3"}, |
| | | {"X1007", "Unit1_å®å
¨é¨ç£æ£1", "Y1017", "Unit1_è鸣å¨-4"}, |
| | | {"X1008", "Unit1_å®å
¨é¨ç£æ£2", "Y1018", "Unit1_æºå°ç
§æ"}, |
| | | {"X1009", "Unit1_å®å
¨é¨ç£æ£3", "Y1019", "Unit1_å®å
¨é¨éå±è½"}, |
| | | {"X100A", "Unit1_å®å
¨é¨ç£æ£4", "Y101A", ""}, |
| | | {"X100B", "Unit1_å®å
¨é¨ç£æ£5", "Y101B", ""}, |
| | | {"X100C", "Unit1_å®å
¨é¨ç£æ£6", "Y101C", ""}, |
| | | {"X100D", "Unit1_å®å
¨é¨éæ£1", "Y101D", "Unit1_å®å
¨é¨é1"}, |
| | | {"X100E", "Unit1_å®å
¨é¨éæ£2", "Y101E", "Unit1_å®å
¨é¨é2"}, |
| | | {"X100F", "Unit1_å®å
¨é¨éæ£3", "Y101F", "Unit1_å®å
¨é¨é3"}, |
| | | {"X1020", "Unit1_ååæ³µ-Alam(8-14)", "Y1030", "Unit1_ååæ³µå¯å¨(1-9)"}, |
| | | {"X1021", "Unit1_ååæ³µ-è¿ç¨/æ¬å°æ¨¡å¼(7-15)", "Y1031", "Unit1_ååæ³µèéè£
ç½®(2-10)"}, |
| | | {"X1022", "Unit1_ååæ³µ-æ£å¸¸è¿è¡ï¼4-12ï¼", "Y1032", "Unit1_ååæ³µéæææ¿é"}, |
| | | {"X1023", "Unit1_ååæ³µéæææ¿éåä½", "Y1033", "Unit1_æ°åéæé"}, |
| | | {"X1024", "Unit1_ååæ³µéæææ¿éå°ä½", "Y1034", ""}, |
| | | {"X1025", "Unit1_è
使çå·¦æ°ç¼¸åä½", "Y1035", "Unit1_è
使çå·¦æ°ç¼¸åä½"}, |
| | | {"X1026", "Unit1_è
使çå·¦æ°ç¼¸å°ä½", "Y1036", "Unit1_è
使çå·¦æ°ç¼¸å°ä½"}, |
| | | {"X1027", "Unit1_è
使ç峿°ç¼¸åä½", "Y1037", "Unit1_è
使ç峿°ç¼¸åä½"}, |
| | | {"X1028", "Unit1_è
使ç峿°ç¼¸å°ä½", "Y1038", "Unit1_è
使ç峿°ç¼¸å°ä½"}, |
| | | {"X1029", "Unit1_é¨éåéæ°ç¼¸åä½", "Y1039", "Unit1_é¨éåéæ°ç¼¸"}, |
| | | {"X102A", "Unit1_é¨éåéæ°ç¼¸å°ä½", "Y103A", ""}, |
| | | {"X102B", "Unit1_è
ä½ç ´ç空æ°éåä½", "Y103B", "Unit1_è
ä½ç ´ç空æ°é"}, |
| | | {"X102C", "Unit1_è
ä½ç ´ç空æ°éå°ä½", "Y103C", "Unit1_ååæ³µææ°é"}, |
| | | {"X102D", "Unit1_ä¸è
å¹³å°ç空æ£", "Y103D", "Unit1_ä¸è
å¹³å°å¸ç空"}, |
| | | {"X102E", "Unit1_ååæ³µææ°éåä½", "Y103E", "Unit1_ä¸è
å¹³å°ç ´ç空"}, |
| | | {"X102F", "Unit1_ååæ³µææ°éå°ä½", "Y103F", ""}, |
| | | {"X1040", "Unit1_ä¸å çå·²ä¸çµ", "Y1050", "Unit1_ä¸å çä¸çµ"}, |
| | | {"X1041", "Unit1_ä¸ä¸»æ¸©æ§è¡¨æ¥è¦", "Y1051", "Unit1_ä¸å çä¸çµ"}, |
| | | {"X1042", "Unit1_ä¸çæ§æ¸©æ§è¡¨æ¥è¦1", "Y1052", ""}, |
| | | {"X1043", "Unit1_ä¸çæ§æ¸©æ§è¡¨æ¥è¦2", "Y1053", ""}, |
| | | {"X1044", "Unit1_ä¸çæ§æ¸©æ§è¡¨æ¥è¦3", "Y1054", ""}, |
| | | {"X1045", "Unit1_ä¸çæ§æ¸©æ§è¡¨æ¥è¦4", "Y1055", ""}, |
| | | {"X1046", "Unit1_ä¸çæ§æ¸©æ§è¡¨æ¥è¦5", "Y1056", ""}, |
| | | {"X1047", "Unit1_ä¸å çå·²ä¸çµ", "Y1057", ""}, |
| | | {"X1048", "Unit1_ä¸ä¸»æ¸©æ§è¡¨æ¥è¦", "Y1058", ""}, |
| | | {"X1049", "Unit1_ä¸çæ§æ¸©æ§è¡¨æ¥è¦1", "Y1059", ""}, |
| | | {"X104A", "Unit1_ä¸çæ§æ¸©æ§è¡¨æ¥è¦2", "Y105A", ""}, |
| | | {"X104B", "Unit1_ä¸çæ§æ¸©æ§è¡¨æ¥è¦3", "Y105B", ""}, |
| | | {"X104C", "Unit1_ä¸çæ§æ¸©æ§è¡¨æ¥è¦4", "Y105C", ""}, |
| | | {"X104D", "Unit1_ä¸çæ§æ¸©æ§è¡¨æ¥è¦5", "Y105D", ""}, |
| | | {"X104E", "", "Y105E", ""}, |
| | | {"X104F", "", "Y105F", ""}, |
| | | {"X1060", "Unit1_干泵-DVPè¿è¡æ£æµ-11", "Y1070", "Unit1_干泵-DVPå¯å¨-1"}, |
| | | {"X1061", "Unit1_干泵-MBPè¿è¡æ£æµ-12", "Y1071", "Unit1_干泵-MBPå¯å¨-2"}, |
| | | {"X1062", "Unit1_干泵-é误æ¥è¦ä¸-14", "Y1072", "Unit1_干泵-å¼å¸¸è§£é¤-3"}, |
| | | {"X1063", "Unit1_干泵-é误è¦åä¸-16", "Y1073", ""}, |
| | | {"X1064", "Unit1_干泵-è¿ç¨/æ¬å°æ¨¡å¼-18", "Y1074", "Unit1_æ°®æ°éæçµç£é1"}, |
| | | {"X1065", "Unit1_干泵-ç´§æ¥åæ¢ä¸-20", "Y1075", "Unit1_æ°®æ°éæçµç£é2"}, |
| | | {"X1066", "", "Y1076", "Unit1_æ°®æ°éæçµç£é3"}, |
| | | {"X1067", "", "Y1077", "Unit1_æ°®æ°éæçµç£é4"}, |
| | | {"X1068", "", "Y1078", "Unit1_å çæ¿æ°´å·éæçµç£é1"}, |
| | | {"X1069", "", "Y1079", "Unit1_å çæ¿æ°´å·éæçµç£é2"}, |
| | | {"X106A", "", "Y107A", "Unit1_å çæ¿æ°´å·éæçµç£é3"}, |
| | | {"X106B", "", "Y107B", "Unit1_å çæ¿æ°´å·éæçµç£é4"}, |
| | | {"X106C", "", "Y107C", "Unit1_è
ä½åºæ¿éæçµç£é1"}, |
| | | {"X106D", "Unit1_æ°´ç®±ä¸æ¶²ä½æ£", "Y107D", "Unit1_è
ä½åºæ¿éæçµç£é2"}, |
| | | {"X106E", "Unit1_æ°´ç®±ä¸æ¶²ä½æ£", "Y107E", "Unit1_æ°´ç®±è¿æ°´é"}, |
| | | {"X106F", "Unit1_æ°´ç®±ä¸æ¶²ä½æ£", "Y107F", "Unit1_æ°´ç®±åºæ°´é"}, |
| | | {"X1080", "Unit2_æ¥å EMO", "Y1090", "Unit2_åè²ç¯-红"}, |
| | | {"X1081", "Unit2_æ»è¿æ°å忣", "Y1091", "Unit2_åè²ç¯-é»"}, |
| | | {"X1082", "Unit2_伺æçµæçææ¥è¦", "Y1092", "Unit2_åè²ç¯-绿"}, |
| | | {"X1083", "Unit2_å ççµæçææ¥è¦", "Y1093", "Unit2_åè²ç¯-è"}, |
| | | {"X1084", "å®å
¨ç»§çµå¨æ£", "Y1094", "Unit2_è鸣å¨-1"}, |
| | | {"X1085", "", "Y1095", "Unit2_è鸣å¨-2"}, |
| | | {"X1086", "", "Y1096", "Unit2_è鸣å¨-3"}, |
| | | {"X1087", "Unit2_å®å
¨é¨ç£æ£1", "Y1097", "Unit2_è鸣å¨-4"}, |
| | | {"X1088", "Unit2_å®å
¨é¨ç£æ£2", "Y1098", "Unit2_æºå°ç
§æ"}, |
| | | {"X1089", "Unit2_å®å
¨é¨ç£æ£3", "Y1099", "Unit2_å®å
¨é¨éå±è½"}, |
| | | {"X108A", "Unit2_å®å
¨é¨ç£æ£4", "Y109A", ""}, |
| | | {"X108B", "Unit2_å®å
¨é¨ç£æ£5", "Y109B", ""}, |
| | | {"X108C", "Unit2_å®å
¨é¨ç£æ£6", "Y109C", ""}, |
| | | {"X108D", "Unit2_å®å
¨é¨éæ£1", "Y109D", "Unit2_å®å
¨é¨é1"}, |
| | | {"X108E", "Unit2_å®å
¨é¨éæ£2", "Y109E", "Unit2_å®å
¨é¨é2"}, |
| | | {"X108F", "Unit2_å®å
¨é¨éæ£3", "Y109F", "Unit2_å®å
¨é¨é3"}, |
| | | {"X10A0", "Unit2_ååæ³µ-Alam(8-14)", "Y10B0", "Unit2_ååæ³µå¯å¨(1-9)"}, |
| | | {"X10A1", "Unit2_ååæ³µ-è¿ç¨/æ¬å°æ¨¡å¼(7-15)", "Y10B1", "Unit2_ååæ³µèéè£
ç½®(2-10)"}, |
| | | {"X10A2", "Unit2_ååæ³µ-æ£å¸¸è¿è¡ï¼4-12ï¼", "Y10B2", "Unit2_ååæ³µéæææ¿é"}, |
| | | {"X10A3", "", "Y10B3", "Unit2_æ°åéæé"}, |
| | | {"X10A4", "", "Y10B4", ""}, |
| | | {"X10A5", "Unit2_è
使çå·¦æ°ç¼¸åä½", "Y10B5", "Unit2_è
使çå·¦æ°ç¼¸åä½"}, |
| | | {"X10A6", "Unit2_è
使çå·¦æ°ç¼¸å°ä½", "Y10B6", "Unit2_è
使çå·¦æ°ç¼¸å°ä½"}, |
| | | {"X10A7", "Unit2_è
使ç峿°ç¼¸åä½", "Y10B7", "Unit2_è
使ç峿°ç¼¸åä½"}, |
| | | {"X10A8", "Unit2_è
使ç峿°ç¼¸å°ä½", "Y10B8", "Unit2_è
使ç峿°ç¼¸å°ä½"}, |
| | | {"X10A9", "Unit2_é¨éåéæ°ç¼¸åä½", "Y10B9", "Unit2_é¨éåéæ°ç¼¸"}, |
| | | {"X10AA", "Unit2_é¨éåéæ°ç¼¸å°ä½", "Y10BA", ""}, |
| | | {"X10AB", "Unit2_è
ä½ç ´ç空æ°éåä½", "Y10BB", "Unit2_è
ä½ç ´ç空æ°é"}, |
| | | {"X10AC", "Unit2_è
ä½ç ´ç空æ°éå°ä½", "Y10BC", "Unit2_ååæ³µææ°é"}, |
| | | {"X10AD", "Unit2_ä¸è
å¹³å°ç空æ£", "Y10BD", "Unit2_ä¸è
å¹³å°å¸ç空"}, |
| | | {"X10AE", "Unit2_ååæ³µææ°éåä½", "Y10BE", "Unit2_ä¸è
å¹³å°ç ´ç空"}, |
| | | {"X10AF", "Unit2_ååæ³µææ°éå°ä½", "Y10BF", ""}, |
| | | {"X10C0", "Unit2_ä¸å çå·²ä¸çµ", "Y10D0", "Unit2_ä¸å çä¸çµ"}, |
| | | {"X10C1", "Unit2_ä¸ä¸»æ¸©æ§è¡¨æ¥è¦", "Y10D1", "Unit2_ä¸å çä¸çµ"}, |
| | | {"X10C2", "Unit2_ä¸çæ§æ¸©æ§è¡¨æ¥è¦1", "Y10D2", ""}, |
| | | {"X10C3", "Unit2_ä¸çæ§æ¸©æ§è¡¨æ¥è¦2", "Y10D3", ""}, |
| | | {"X10C4", "Unit2_ä¸çæ§æ¸©æ§è¡¨æ¥è¦3", "Y10D4", ""}, |
| | | {"X10C5", "Unit2_ä¸çæ§æ¸©æ§è¡¨æ¥è¦4", "Y10D5", ""}, |
| | | {"X10C6", "Unit2_ä¸çæ§æ¸©æ§è¡¨æ¥è¦5", "Y10D6", ""}, |
| | | {"X10C7", "Unit2_ä¸å çå·²ä¸çµ", "Y10D7", ""}, |
| | | {"X10C8", "Unit2_ä¸ä¸»æ¸©æ§è¡¨æ¥è¦", "Y10D8", ""}, |
| | | {"X10C9", "Unit2_ä¸çæ§æ¸©æ§è¡¨æ¥è¦1", "Y10D9", ""}, |
| | | {"X10CA", "Unit2_ä¸çæ§æ¸©æ§è¡¨æ¥è¦2", "Y10DA", ""}, |
| | | {"X10CB", "Unit2_ä¸çæ§æ¸©æ§è¡¨æ¥è¦3", "Y10DB", ""}, |
| | | {"X10CC", "Unit2_ä¸çæ§æ¸©æ§è¡¨æ¥è¦4", "Y10DC", ""}, |
| | | {"X10CD", "Unit2_ä¸çæ§æ¸©æ§è¡¨æ¥è¦5", "Y10DD", ""}, |
| | | {"X10CE", "", "Y10DE", ""}, |
| | | {"X10CF", "", "Y10DF", ""}, |
| | | {"X10E0", "Unit2_干泵-DVPè¿è¡æ£æµ-11", "Y10F0", "Unit2_干泵-DVPå¯å¨-1"}, |
| | | {"X10E1", "Unit2_干泵-MBPè¿è¡æ£æµ-12", "Y10F1", "Unit2_干泵-MBPå¯å¨-2"}, |
| | | {"X10E2", "Unit2_干泵-é误æ¥è¦ä¸-14", "Y10F2", "Unit2_干泵-å¼å¸¸è§£é¤-3"}, |
| | | {"X10E3", "Unit2_干泵-é误è¦åä¸-16", "Y10F3", ""}, |
| | | {"X10E4", "Unit2_干泵-è¿ç¨/æ¬å°æ¨¡å¼-18", "Y10F4", "Unit2_æ°®æ°éæçµç£é1"}, |
| | | {"X10E5", "Unit2_干泵-ç´§æ¥åæ¢ä¸-20", "Y10F5", "Unit2_æ°®æ°éæçµç£é2"}, |
| | | {"X10E6", "", "Y10F6", "Unit2_æ°®æ°éæçµç£é3"}, |
| | | {"X10E7", "", "Y10F7", "Unit2_æ°®æ°éæçµç£é4"}, |
| | | {"X10E8", "", "Y10F8", "Unit2_å çæ¿æ°´å·éæçµç£é1"}, |
| | | {"X10E9", "", "Y10F9", "Unit2_å çæ¿æ°´å·éæçµç£é2"}, |
| | | {"X10EA", "", "Y10FA", "Unit2_å çæ¿æ°´å·éæçµç£é3"}, |
| | | {"X10EB", "", "Y10FB", "Unit2_å çæ¿æ°´å·éæçµç£é4"}, |
| | | {"X10EC", "", "Y10FC", "Unit2_è
ä½åºæ¿éæçµç£é1"}, |
| | | {"X10ED", "Unit2_æ°´ç®±ä¸æ¶²ä½æ£", "Y10FD", "Unit2_è
ä½åºæ¿éæçµç£é2"}, |
| | | {"X10EE", "Unit2_æ°´ç®±ä¸æ¶²ä½æ£", "Y10FE", "Unit2_æ°´ç®±è¿æ°´é"}, |
| | | {"X10EF", "Unit2_æ°´ç®±ä¸æ¶²ä½æ£", "Y10FF", "Unit2_æ°´ç®±åºæ°´é"} |
| | | }; |
| | | m_machines[machineName] = defaultData; |
| | | } |
| | | else if (machineName == "VacuumBake") { |
| | | std::vector<IOData> defaultData = { |
| | | {"X1100", "æ¥å EMO", "Y1110", "åè²ç¯-红"}, |
| | | {"X1101", "æ»è¿æ°å忣", "Y1111", "åè²ç¯-é»"}, |
| | | {"X1102", "Aå ççµæçææ¥è¦", "Y1112", "åè²ç¯-绿"}, |
| | | {"X1103", "Bå ççµæçææ¥è¦", "Y1113", "åè²ç¯-è"}, |
| | | {"X1104", "å®å
¨ç»§çµå¨æ£", "Y1114", "è鸣å¨-1"}, |
| | | {"X1105", "", "Y1115", "è鸣å¨-2"}, |
| | | {"X1106", "", "Y1116", "è鸣å¨-3"}, |
| | | {"X1107", "", "Y1117", "è鸣å¨-4"}, |
| | | {"X1108", "", "Y1118", "æºå°ç
§æ"}, |
| | | {"X1109", "", "Y1119", "å®å
¨é¨éå±è½"}, |
| | | {"X110A", "å®å
¨é¨ç£æ£1", "Y111A", ""}, |
| | | {"X110B", "å®å
¨é¨ç£æ£2", "Y111B", ""}, |
| | | {"X110C", "å®å
¨é¨éæ£1", "Y111C", "å®å
¨é¨é1"}, |
| | | {"X110D", "å®å
¨é¨éæ£2", "Y111D", "å®å
¨é¨é2"}, |
| | | {"X110E", "å®å
¨é¨éæ£3", "Y111E", "å®å
¨é¨é3"}, |
| | | {"X110F", "å®å
¨é¨éæ£4", "Y111F", "å®å
¨é¨é4"}, |
| | | {"X1120", "Aè
é¨éåéæ°ç¼¸åä½", "Y1130", "Aè
é¨éåéæ°ç¼¸"}, |
| | | {"X1121", "Aè
é¨éåéæ°ç¼¸å°ä½", "Y1131", ""}, |
| | | {"X1122", "Aè
è
使»å¸ç空æ°éåä½", "Y1132", "Aè
è
使»å¸ç空æ°é"}, |
| | | {"X1123", "Aè
è
使»å¸ç空æ°éå°ä½", "Y1133", "Aè
è
使»ç ´ç空æ°é"}, |
| | | {"X1124", "Aè
è
使»ç ´ç空æ°éåä½", "Y1134", "Aè
å·å´æ°´é"}, |
| | | {"X1125", "Aè
è
使»ç ´ç空æ°éå°ä½", "Y1135", ""}, |
| | | {"X1126", "Aè
å çå·²ä¸çµ", "Y1136", "Aè
å çä¸çµ"}, |
| | | {"X1127", "Aè
主温æ§è¡¨æ¥è¦", "Y1137", ""}, |
| | | {"X1128", "Aè
çæ§æ¸©æ§è¡¨æ¥è¦1", "Y1138", ""}, |
| | | {"X1129", "Aè
çæ§æ¸©æ§è¡¨æ¥è¦2", "Y1139", ""}, |
| | | {"X112A", "Aè
çæ§æ¸©æ§è¡¨æ¥è¦3", "Y113A", ""}, |
| | | {"X112B", "Aè
çæ§æ¸©æ§è¡¨æ¥è¦4", "Y113B", ""}, |
| | | {"X112C", "Aè
çæ§æ¸©æ§è¡¨æ¥è¦5", "Y113C", ""}, |
| | | {"X112D", "", "Y113D", ""}, |
| | | {"X112E", "", "Y113E", ""}, |
| | | {"X112F", "", "Y113F", ""}, |
| | | {"X1140", "Bè
é¨éåéæ°ç¼¸åä½", "Y1150", "Bè
é¨éåéæ°ç¼¸"}, |
| | | {"X1141", "Bè
é¨éåéæ°ç¼¸å°ä½", "Y1151", ""}, |
| | | {"X1142", "Bè
è
使»å¸ç空æ°éåä½", "Y1152", "Bè
è
使»å¸ç空æ°é"}, |
| | | {"X1143", "Bè
è
使»å¸ç空æ°éå°ä½", "Y1153", "Bè
è
使»ç ´ç空æ°é"}, |
| | | {"X1144", "Bè
è
使»ç ´ç空æ°éåä½", "Y1154", "Bè
å·å´æ°´é"}, |
| | | {"X1145", "Bè
è
使»ç ´ç空æ°éå°ä½", "Y1155", ""}, |
| | | {"X1146", "Bè
å çå·²ä¸çµ", "Y1156", "Bè
å çä¸çµ"}, |
| | | {"X1147", "Bè
主温æ§è¡¨æ¥è¦", "Y1157", ""}, |
| | | {"X1148", "Bè
çæ§æ¸©æ§è¡¨æ¥è¦1", "Y1158", ""}, |
| | | {"X1149", "Bè
çæ§æ¸©æ§è¡¨æ¥è¦2", "Y1159", ""}, |
| | | {"X114A", "Bè
çæ§æ¸©æ§è¡¨æ¥è¦3", "Y115A", ""}, |
| | | {"X114B", "Bè
çæ§æ¸©æ§è¡¨æ¥è¦4", "Y115B", ""}, |
| | | {"X114C", "Bè
çæ§æ¸©æ§è¡¨æ¥è¦5", "Y115C", ""}, |
| | | {"X114D", "", "Y115D", ""}, |
| | | {"X114E", "", "Y115E", ""}, |
| | | {"X114F", "", "Y115F", ""}, |
| | | {"X1160", "干泵-DVPè¿è¡æ£æµ-11", "Y1170", "干泵-DVPå¯å¨-1"}, |
| | | {"X1161", "干泵-MBPè¿è¡æ£æµ-12", "Y1171", "干泵-MBPå¯å¨-2"}, |
| | | {"X1162", "干泵-é误æ¥è¦ä¸-14", "Y1172", "干泵-å¼å¸¸è§£é¤-3"}, |
| | | {"X1163", "干泵-é误è¦åä¸-16", "Y1173", ""}, |
| | | {"X1164", "干泵-è¿ç¨/æ¬å°æ¨¡å¼-18", "Y1174", ""}, |
| | | {"X1165", "干泵-ç´§æ¥åæ¢ä¸-20", "Y1175", ""}, |
| | | {"X1166", "", "Y1176", ""}, |
| | | {"X1167", "", "Y1177", ""}, |
| | | {"X1168", "", "Y1178", ""}, |
| | | {"X1169", "", "Y1179", ""}, |
| | | {"X116A", "", "Y117A", ""}, |
| | | {"X116B", "", "Y117B", ""}, |
| | | {"X116C", "", "Y117C", ""}, |
| | | {"X116D", "", "Y117D", ""}, |
| | | {"X116E", "", "Y117E", ""}, |
| | | {"X116F", "", "Y117F", ""} |
| | | }; |
| | | m_machines[machineName] = defaultData; |
| | | } |
| | | else if (machineName == "AfterBake") { |
| | | std::vector<IOData> defaultData = { |
| | | {"X200", "æ¥å EMO", "Y400", "åè²ç¯-红"}, |
| | | {"X201", "æ»è¿æ°å忣", "Y401", "åè²ç¯-é»"}, |
| | | {"X202", "Aå ççµæçææ¥è¦", "Y402", "åè²ç¯-绿"}, |
| | | {"X203", "Bå ççµæçææ¥è¦", "Y403", "åè²ç¯-è"}, |
| | | {"X204", "å®å
¨ç»§çµå¨æ£", "Y404", "è鸣å¨-1"}, |
| | | {"X205", "ä¸çµç®±æ¸©æ§æ¥è¦", "Y405", "è鸣å¨-2"}, |
| | | {"X206", "ä¸çµç®±æ¸©æ§æ¥è¦", "Y406", "è鸣å¨-3"}, |
| | | {"X207", "", "Y407", "è鸣å¨-4"}, |
| | | {"X208", "å®å
¨é¨ç£æ£1", "Y408", "æºå°ç
§æ"}, |
| | | {"X209", "å®å
¨é¨ç£æ£2", "Y409", "å®å
¨é¨éå±è½"}, |
| | | {"X20A", "å®å
¨é¨ç£æ£3", "Y40A", ""}, |
| | | {"X20B", "å®å
¨é¨ç£æ£4", "Y40B", ""}, |
| | | {"X20C", "å®å
¨é¨éæ£1", "Y40C", "å®å
¨é¨é1"}, |
| | | {"X20D", "å®å
¨é¨éæ£2", "Y40D", "å®å
¨é¨é2"}, |
| | | {"X20E", "å®å
¨é¨éæ£3", "Y40E", "å®å
¨é¨é3"}, |
| | | {"X20F", "å®å
¨é¨éæ£4", "Y40F", "å®å
¨é¨é4"}, |
| | | {"X210", "Aä¸è
å¤¹ææ°ç¼¸1åä½", "Y410", "Aä¸è
å¤¹ææ°ç¼¸"}, |
| | | {"X211", "Aä¸è
å¤¹ææ°ç¼¸1å°ä½", "Y411", ""}, |
| | | {"X212", "Aä¸è
å¤¹ææ°ç¼¸2åä½", "Y412", "Aè
æ°´è·¯éæé"}, |
| | | {"X213", "Aä¸è
å¤¹ææ°ç¼¸2å°ä½", "Y413", ""}, |
| | | {"X214", "Aä¸è
å çå·²ä¸çµ", "Y414", ""}, |
| | | {"X215", "Aä¸ä¸»æ¸©æ§è¡¨æ¥è¦", "Y415", ""}, |
| | | {"X216", "Aä¸è
çæ§æ¸©æ§è¡¨æ¥è¦1", "Y416", ""}, |
| | | {"X217", "Aä¸è
çæ§æ¸©æ§è¡¨æ¥è¦2", "Y417", ""}, |
| | | {"X218", "Aä¸è
çæ§æ¸©æ§è¡¨æ¥è¦3", "Y418", ""}, |
| | | {"X219", "Aä¸è
çæ§æ¸©æ§è¡¨æ¥è¦4", "Y419", ""}, |
| | | {"X21A", "Aä¸è
çæ§æ¸©æ§è¡¨æ¥è¦5", "Y41A", ""}, |
| | | {"X21B", "", "Y41B", ""}, |
| | | {"X21C", "è
ä½å·¦ä¸é¨ç£", "Y41C", ""}, |
| | | {"X21D", "è
ä½å·¦ä¸é¨ç£", "Y41D", ""}, |
| | | {"X21E", "è
ä½å³ä¸é¨ç£", "Y41E", ""}, |
| | | {"X21F", "è
ä½å³ä¸é¨ç£", "Y41F", ""}, |
| | | {"X220", "Bä¸è
å¤¹ææ°ç¼¸1åä½", "Y420", "Bä¸è
å¤¹ææ°ç¼¸"}, |
| | | {"X221", "Bä¸è
å¤¹ææ°ç¼¸1å°ä½", "Y421", ""}, |
| | | {"X222", "Bä¸è
å¤¹ææ°ç¼¸2åä½", "Y422", "Bè
æ°´è·¯éæé"}, |
| | | {"X223", "Bä¸è
å¤¹ææ°ç¼¸2å°ä½", "Y423", ""}, |
| | | {"X224", "Bä¸è
å çå·²ä¸çµ", "Y424", ""}, |
| | | {"X225", "Bä¸ä¸»æ¸©æ§è¡¨æ¥è¦", "Y425", ""}, |
| | | {"X226", "Bä¸è
çæ§æ¸©æ§è¡¨æ¥è¦1", "Y426", ""}, |
| | | {"X227", "Bä¸è
çæ§æ¸©æ§è¡¨æ¥è¦2", "Y427", ""}, |
| | | {"X228", "Bä¸è
çæ§æ¸©æ§è¡¨æ¥è¦3", "Y428", ""}, |
| | | {"X229", "Bä¸è
çæ§æ¸©æ§è¡¨æ¥è¦4", "Y429", ""}, |
| | | {"X22A", "Bä¸è
çæ§æ¸©æ§è¡¨æ¥è¦5", "Y42A", ""}, |
| | | {"X22B", "", "Y42B", ""}, |
| | | {"X22C", "Aä¸è
æææ£", "Y42C", ""}, |
| | | {"X22D", "", "Y42D", ""}, |
| | | {"X22E", "", "Y42E", ""}, |
| | | {"X22F", "", "Y42F", ""} |
| | | }; |
| | | m_machines[machineName] = defaultData; |
| | | } |
| | | else if (machineName == "AOI") { |
| | | std::vector<IOData> defaultData = { |
| | | {"X240", "æ¥å EMO", "Y440", "åè²ç¯-红"}, |
| | | {"X241", "æ»è¿æ°åå表", "Y441", "åè²ç¯-é»"}, |
| | | {"X242", "çææ¥è¦", "Y442", "åè²ç¯-绿"}, |
| | | {"X243", "", "Y443", "åè²ç¯-è"}, |
| | | {"X244", "", "Y444", "è鸣å¨-1"}, |
| | | {"X245", "å·¦ä¸é¨ç£æ£", "Y445", "è鸣å¨-2"}, |
| | | {"X246", "å·¦ä¸é¨ç£æ£", "Y446", "è鸣å¨-3"}, |
| | | {"X247", "å³ä¸é¨ç£æ£", "Y447", "è鸣å¨-4"}, |
| | | {"X248", "å³ä¸é¨ç£æ£", "Y448", "æºå°ç
§æ"}, |
| | | {"X249", "å®å
¨é¨ç£æ£1", "Y449", "å®å
¨é¨éå±è½"}, |
| | | {"X24A", "å®å
¨é¨ç£æ£2", "Y44A", ""}, |
| | | {"X24B", "å®å
¨é¨éæ£1", "Y44B", "å®å
¨é¨é1"}, |
| | | {"X24C", "å®å
¨é¨éæ£2", "Y44C", "å®å
¨é¨é2"}, |
| | | {"X24D", "æ£æµæ¬èå忣", "Y44D", ""}, |
| | | {"X24E", "æ£æµå¹³å°ç空æ£", "Y44E", "æ£æµå¹³å°å¸ç空"}, |
| | | {"X24F", "æ£æµå¹³å°æææ£", "Y44F", "æ£æµå¹³å°ç ´ç空"}, |
| | | {"X250", "æ£æµå¹³å°å¯¹ä½æ°ç¼¸A1åä½", "Y450", "æ£æµå¹³å°å¯¹ä½æ°ç¼¸A"}, |
| | | {"X251", "æ£æµå¹³å°å¯¹ä½æ°ç¼¸A1å°ä½", "Y451", ""}, |
| | | {"X252", "æ£æµå¹³å°å¯¹ä½æ°ç¼¸A2åä½", "Y452", ""}, |
| | | {"X253", "æ£æµå¹³å°å¯¹ä½æ°ç¼¸A2å°ä½", "Y453", ""}, |
| | | {"X254", "æ£æµå¹³å°å¯¹ä½åéæ°ç¼¸A1åä½", "Y454", "æ£æµå¹³å°å¯¹ä½åéæ°ç¼¸A"}, |
| | | {"X255", "æ£æµå¹³å°å¯¹ä½åéæ°ç¼¸A1å°ä½", "Y455", ""}, |
| | | {"X256", "æ£æµå¹³å°å¯¹ä½åéæ°ç¼¸A2åä½", "Y456", ""}, |
| | | {"X257", "æ£æµå¹³å°å¯¹ä½åéæ°ç¼¸A2å°ä½", "Y457", ""}, |
| | | {"X258", "æ£æµå¹³å°å¯¹ä½æ°ç¼¸B1åä½", "Y458", "æ£æµå¹³å°å¯¹ä½æ°ç¼¸B"}, |
| | | {"X259", "æ£æµå¹³å°å¯¹ä½æ°ç¼¸B1å°ä½", "Y459", ""}, |
| | | {"X25A", "æ£æµå¹³å°å¯¹ä½æ°ç¼¸B2åä½", "Y45A", ""}, |
| | | {"X25B", "æ£æµå¹³å°å¯¹ä½æ°ç¼¸B2å°ä½", "Y45B", ""}, |
| | | {"X25C", "æ£æµå¹³å°å¯¹ä½åéæ°ç¼¸B1åä½", "Y45C", "æ£æµå¹³å°å¯¹ä½åéæ°ç¼¸B"}, |
| | | {"X25D", "æ£æµå¹³å°å¯¹ä½åéæ°ç¼¸B1å°ä½", "Y45D", ""}, |
| | | {"X25E", "æ£æµå¹³å°å¯¹ä½åéæ°ç¼¸B2åä½", "Y45E", ""}, |
| | | {"X25F", "æ£æµå¹³å°å¯¹ä½åéæ°ç¼¸B2å°ä½", "Y45F", ""}, |
| | | {"X260", "", "Y460", ""}, |
| | | {"X261", "", "Y461", ""}, |
| | | {"X262", "", "Y462", ""}, |
| | | {"X263", "", "Y463", ""}, |
| | | {"X264", "", "Y464", ""}, |
| | | {"X265", "", "Y465", ""}, |
| | | {"X266", "", "Y466", ""}, |
| | | {"X267", "", "Y467", ""}, |
| | | {"X268", "", "Y468", ""}, |
| | | {"X269", "", "Y469", ""}, |
| | | {"X26A", "", "Y46A", ""}, |
| | | {"X26B", "", "Y46B", ""}, |
| | | {"X26C", "", "Y46C", ""}, |
| | | {"X26D", "", "Y46D", ""}, |
| | | {"X26E", "", "Y46E", ""}, |
| | | {"X26F", "", "Y46F", ""} |
| | | }; |
| | | m_machines[machineName] = defaultData; |
| | | } |
| | | } |
| | | |
| | | void IOManager::saveToFile(const std::string& machineName) { |
| | | std::ofstream file(m_directory + "/" + machineName + ".iom"); |
| | | if (!file.is_open()) { |
| | | std::cerr << "Failed to open file for writing: " << machineName << ".iom" << std::endl; |
| | | return; |
| | | } |
| | | |
| | | for (const auto& entry : m_machines[machineName]) { |
| | | file << entry.inputAddress << "," |
| | | << entry.inputDescription << "," |
| | | << entry.outputAddress << "," |
| | | << entry.outputDescription << "\n"; |
| | | } |
| | | |
| | | file.close(); |
| | | } |
| | | |
| | | bool IOManager::loadFromFile(const std::string& machineName) { |
| | | std::ifstream file(m_directory + "/" + machineName + ".iom"); |
| | | if (!file.is_open()) { |
| | | std::cerr << "Failed to open file for reading: " << machineName << ".iom" << std::endl; |
| | | return false; |
| | | } |
| | | |
| | | std::vector<IOData> data; |
| | | std::string line; |
| | | while (std::getline(file, line)) { |
| | | IOData entry; |
| | | size_t pos = 0; |
| | | pos = line.find(","); |
| | | entry.inputAddress = line.substr(0, pos); |
| | | line.erase(0, pos + 1); |
| | | |
| | | pos = line.find(","); |
| | | entry.inputDescription = line.substr(0, pos); |
| | | line.erase(0, pos + 1); |
| | | |
| | | pos = line.find(","); |
| | | entry.outputAddress = line.substr(0, pos); |
| | | line.erase(0, pos + 1); |
| | | |
| | | entry.outputDescription = line; |
| | | data.push_back(entry); |
| | | } |
| | | |
| | | m_machines[machineName] = data; |
| | | file.close(); |
| | | return true; |
| | | } |
| | | |
| | | void IOManager::printMachineData(const std::string& machineName) const { |
| | | auto it = m_machines.find(machineName); |
| | | if (it != m_machines.end()) { |
| | | for (const auto& entry : it->second) { |
| | | std::cout << "Input Address: " << entry.inputAddress |
| | | << ", Input Description: " << entry.inputDescription |
| | | << ", Output Address: " << entry.outputAddress |
| | | << ", Output Description: " << entry.outputDescription << std::endl; |
| | | } |
| | | } |
| | | else { |
| | | std::cerr << "Machine not found: " << machineName << std::endl; |
| | | } |
| | | } |
| | | |
| | | std::vector<IOData> IOManager::GetMachineData(const std::string& machineName) const |
| | | { |
| | | auto it = m_machines.find(machineName); |
| | | if (it != m_machines.end()) { |
| | | return it->second; |
| | | } |
| | | return {}; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #ifndef IOMANAGER_H |
| | | #define IOMANAGER_H |
| | | |
| | | #include <string> |
| | | #include <vector> |
| | | #include <map> |
| | | |
| | | struct IOData { |
| | | std::string inputAddress; |
| | | std::string inputDescription; |
| | | std::string outputAddress; |
| | | std::string outputDescription; |
| | | }; |
| | | |
| | | class IOManager { |
| | | public: |
| | | IOManager(); |
| | | |
| | | void addMachine(const std::string& machineName, const std::vector<IOData>& data); |
| | | void addDefaultMachineData(const std::string& machineName); |
| | | void saveToFile(const std::string& machineName); |
| | | bool loadFromFile(const std::string& machineName); |
| | | void printMachineData(const std::string& machineName) const; |
| | | std::vector<IOData> GetMachineData(const std::string& machineName) const; |
| | | |
| | | private: |
| | | std::string m_directory; |
| | | std::map<std::string, std::vector<IOData>> m_machines; |
| | | }; |
| | | |
| | | #endif // IOMANAGER_H |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include <sstream> |
| | | #include <fstream> |
| | | #include <iostream> |
| | | |
| | | // åä¾è·å |
| | | RecipeManager& RecipeManager::getInstance() { |
| | | static RecipeManager instance; |
| | | return instance; |
| | | } |
| | | |
| | | // æé 彿° |
| | | RecipeManager::RecipeManager() : m_recipeFolder("Recipe") {} |
| | | |
| | | // 设置é
æ¹æä»¶å¤¹ |
| | | void RecipeManager::setRecipeFolder(const std::string& folderPath) { |
| | | m_recipeFolder = folderPath; |
| | | } |
| | | |
| | | // å è½½é
æ¹ï¼å¦ææä»¶ä¸åå¨ï¼å è½½é»è®¤æ°æ®ï¼ |
| | | bool RecipeManager::loadRecipe(const std::string& recipeName) { |
| | | std::string filePath = m_recipeFolder + "/" + recipeName + ".xml"; |
| | | pugi::xml_document doc; |
| | | |
| | | if (!doc.load_file(filePath.c_str())) { |
| | | std::cerr << "Recipe file not found: " << filePath << ". Loading default recipe." << std::endl; |
| | | generateDefaultRecipe(); |
| | | return false; // æä»¶ä¸åå¨ï¼ä½å è½½äºé»è®¤æ°æ® |
| | | } |
| | | |
| | | m_axes.clear(); |
| | | |
| | | auto recipe = doc.child("Recipe"); |
| | | for (auto axisNode : recipe.child("Axes").children("Axis")) { |
| | | AxisInfo axisInfo; |
| | | axisInfo.id = axisNode.attribute("id").as_int(); |
| | | axisInfo.number = axisNode.attribute("number").value(); |
| | | axisInfo.description = axisNode.attribute("description").value(); |
| | | axisInfo.startAddress = axisNode.attribute("start_address").value(); |
| | | axisInfo.jogDistance = axisNode.attribute("jog_distance").as_double(); |
| | | axisInfo.manualSpeed = axisNode.attribute("manual_speed").as_double(); |
| | | axisInfo.autoSpeed = axisNode.attribute("auto_speed").as_double(); |
| | | axisInfo.accelerationTime = axisNode.attribute("acceleration_time").as_double(); |
| | | axisInfo.decelerationTime = axisNode.attribute("deceleration_time").as_double(); |
| | | |
| | | for (auto positionNode : axisNode.child("Positions").children("Position")) { |
| | | std::string description = positionNode.attribute("description").value(); |
| | | double positionValue = positionNode.attribute("value").as_double(); |
| | | axisInfo.positions.emplace_back(description, positionValue); |
| | | } |
| | | |
| | | m_axes[axisInfo.id] = axisInfo; |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | // ä¿åé
æ¹ |
| | | bool RecipeManager::saveRecipe(const std::string& recipeName) { |
| | | // çææä»¶è·¯å¾ |
| | | std::string filePath = m_recipeFolder + "/" + recipeName + ".xml"; |
| | | |
| | | // å建 XML ææ¡£å¯¹è±¡ |
| | | pugi::xml_document doc; |
| | | |
| | | // å¦æè½´æ°æ®ä¸ºç©ºï¼çæé»è®¤é
æ¹ |
| | | if (m_axes.empty()) { |
| | | generateDefaultRecipe(); |
| | | } |
| | | |
| | | // æ·»å é
æ¹æ ¹èç¹ |
| | | auto recipe = doc.append_child("Recipe"); |
| | | |
| | | // æ·»å è½´å表èç¹ |
| | | auto axesNode = recipe.append_child("Axes"); |
| | | |
| | | // éåææè½´æ°æ®å¹¶åå
¥ XML |
| | | for (const auto& axisEntry : m_axes) { |
| | | const AxisInfo& axisInfo = axisEntry.second; |
| | | |
| | | auto axisNode = axesNode.append_child("Axis"); |
| | | axisNode.append_attribute("id") = axisInfo.id; |
| | | axisNode.append_attribute("number") = axisInfo.number.c_str(); |
| | | axisNode.append_attribute("description") = axisInfo.description.c_str(); |
| | | axisNode.append_attribute("start_address") = axisInfo.startAddress.c_str(); |
| | | axisNode.append_attribute("jog_distance") = axisInfo.jogDistance; |
| | | axisNode.append_attribute("manual_speed") = axisInfo.manualSpeed; |
| | | axisNode.append_attribute("auto_speed") = axisInfo.autoSpeed; |
| | | axisNode.append_attribute("acceleration_time") = axisInfo.accelerationTime; |
| | | axisNode.append_attribute("deceleration_time") = axisInfo.decelerationTime; |
| | | |
| | | // æ·»å å®ä½ç¹å表 |
| | | auto positionsNode = axisNode.append_child("Positions"); |
| | | for (const auto& position : axisInfo.positions) { |
| | | auto positionNode = positionsNode.append_child("Position"); |
| | | positionNode.append_attribute("description") = position.first.c_str(); |
| | | positionNode.append_attribute("value") = position.second; |
| | | } |
| | | } |
| | | |
| | | // ä¿å XML æä»¶ |
| | | return doc.save_file(filePath.c_str()); |
| | | } |
| | | |
| | | // çæé»è®¤é
æ¹ |
| | | void RecipeManager::generateDefaultRecipe() { |
| | | m_axes.clear(); |
| | | |
| | | for (int axisId = 1; axisId <= 12; ++axisId) { |
| | | AxisInfo axisInfo; |
| | | axisInfo.id = axisId; |
| | | axisInfo.number = "M100-M" + std::to_string(axisId); |
| | | axisInfo.description = "Default_Axis" + std::to_string(axisId); |
| | | axisInfo.startAddress = "D" + std::to_string(5000 + axisId * 10); |
| | | axisInfo.jogDistance = 0.5; |
| | | axisInfo.manualSpeed = 10.0; |
| | | axisInfo.autoSpeed = 15.0; |
| | | axisInfo.accelerationTime = 0.2; |
| | | axisInfo.decelerationTime = 0.3; |
| | | |
| | | for (int posId = 1; posId <= 25; ++posId) { |
| | | axisInfo.positions.emplace_back("Position " + std::to_string(posId), posId * 10.0); |
| | | } |
| | | |
| | | m_axes[axisId] = axisInfo; |
| | | } |
| | | } |
| | | |
| | | // è·åææè½´ä¿¡æ¯ |
| | | const std::map<int, AxisInfo>& RecipeManager::getAxes() const { |
| | | return m_axes; |
| | | } |
| | | |
| | | // è·ååä¸ªè½´ä¿¡æ¯ |
| | | AxisInfo RecipeManager::getAxis(int axisId) const { |
| | | auto it = m_axes.find(axisId); |
| | | if (it != m_axes.end()) { |
| | | return it->second; |
| | | } |
| | | |
| | | // è¿åä¸ä¸ªæ æç AxisInfo |
| | | return AxisInfo{ -1, "", "", "", 0.0, 0.0, 0.0, 0.0, 0.0, {}}; |
| | | } |
| | | |
| | | // æ´æ°è½´ä¿¡æ¯ |
| | | bool RecipeManager::updateAxis(const AxisInfo& axisInfo) { |
| | | if (m_axes.find(axisInfo.id) == m_axes.end()) { |
| | | return false; // è½´ä¸åå¨ |
| | | } |
| | | m_axes[axisInfo.id] = axisInfo; |
| | | return true; |
| | | } |
| | | |
| | | // æ·»å æ°çè½´ä¿¡æ¯ |
| | | bool RecipeManager::addAxis(const AxisInfo& axisInfo) { |
| | | if (m_axes.find(axisInfo.id) != m_axes.end()) { |
| | | return false; // è½´å·²åå¨ |
| | | } |
| | | m_axes[axisInfo.id] = axisInfo; |
| | | return true; |
| | | } |
| | | |
| | | // å é¤è½´ä¿¡æ¯ |
| | | bool RecipeManager::deleteAxis(int axisId) { |
| | | return m_axes.erase(axisId) > 0; |
| | | } |
| | | |
| | | // è·åææè½´ç¼å· |
| | | std::vector<int> RecipeManager::getAllAxisID() const { |
| | | std::vector<int> axisNumbers; |
| | | for (const auto& axis : m_axes) { |
| | | int axisId = axis.first; |
| | | axisNumbers.push_back(axisId); |
| | | } |
| | | |
| | | return axisNumbers; |
| | | } |
| | | |
| | | // è·åæå®é¡µçå®ä½ç¹ |
| | | std::vector<std::pair<std::string, double>> RecipeManager::getPositions(int axisId, int pageNumber, int pageSize) const { |
| | | std::vector<std::pair<std::string, double>> result; |
| | | |
| | | // æ£æ¥è½´æ¯å¦åå¨ |
| | | auto it = m_axes.find(axisId); |
| | | if (it == m_axes.end()) { |
| | | return result; // å¦æè½´ ID ä¸åå¨ï¼è¿åç©ºç»æ |
| | | } |
| | | |
| | | // è·åæå®è½´çææå®ä½ç¹ |
| | | const auto& positions = it->second.positions; |
| | | |
| | | // ç¡®å®å页èå´ |
| | | int startIndex = (pageNumber - 1) * pageSize; |
| | | int endIndex = startIndex + pageSize; |
| | | |
| | | // éåå®ä½ç¹ï¼æå页æåæ°æ® |
| | | int index = 0; |
| | | for (const auto& pos : positions) { |
| | | const std::string& description = pos.first; // é®ï¼æè¿° |
| | | double value = pos.second; // å¼ï¼ä½ç½®å¼ |
| | | |
| | | if (index >= startIndex && index < endIndex) { |
| | | result.emplace_back(description, value); |
| | | } |
| | | |
| | | ++index; |
| | | if (index >= endIndex) { |
| | | break; // è¾¾å°åé¡µç»æç¹ |
| | | } |
| | | } |
| | | |
| | | return result; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #ifndef RECIPE_MANAGER_H |
| | | #define RECIPE_MANAGER_H |
| | | |
| | | #include <string> |
| | | #include <vector> |
| | | #include <map> |
| | | #include "pugixml.hpp" |
| | | |
| | | // è½´ä¿¡æ¯ç»æä½ |
| | | struct AxisInfo { |
| | | int id; // è½´ID |
| | | std::string number; // è½´ç¼å· |
| | | std::string description; // è½´æè¿° |
| | | std::string startAddress; // èµ·å§å°å |
| | | double jogDistance; // å¾®å¨é |
| | | double manualSpeed; // æå¨é度 |
| | | double autoSpeed; // èªå¨é度 |
| | | double accelerationTime; // å éæ¶é´ |
| | | double decelerationTime; // åéæ¶é´ |
| | | std::vector<std::pair<std::string, double>> positions; // å®ä½ç¹ï¼æè¿°åä½ç½® |
| | | }; |
| | | |
| | | // é
æ¹ç®¡çç±» |
| | | class RecipeManager { |
| | | public: |
| | | // å便¨¡å¼è·åå®ä¾ |
| | | static RecipeManager& getInstance(); |
| | | |
| | | // 设置é
æ¹æä»¶å¤¹è·¯å¾ |
| | | void setRecipeFolder(const std::string& folderPath); |
| | | |
| | | // å è½½é
æ¹ï¼æä»¶ä¸å卿¶å è½½é»è®¤æ°æ®ï¼ |
| | | bool loadRecipe(const std::string& recipeName); |
| | | |
| | | // ä¿åé
æ¹ |
| | | bool saveRecipe(const std::string& recipeName); |
| | | |
| | | // çæé»è®¤é
æ¹ |
| | | void generateDefaultRecipe(); |
| | | |
| | | // è·åææè½´ä¿¡æ¯ |
| | | const std::map<int, AxisInfo>& getAxes() const; |
| | | |
| | | // è·ååä¸ªè½´ä¿¡æ¯ |
| | | AxisInfo getAxis(int axisId) const; |
| | | |
| | | // æ´æ°è½´ä¿¡æ¯ |
| | | bool updateAxis(const AxisInfo& axisInfo); |
| | | |
| | | // æ·»å æ°çè½´ä¿¡æ¯ |
| | | bool addAxis(const AxisInfo& axisInfo); |
| | | |
| | | // å é¤è½´ä¿¡æ¯ |
| | | bool deleteAxis(int axisId); |
| | | |
| | | // è·åææè½´ID |
| | | std::vector<int> getAllAxisID() const; |
| | | |
| | | // è·åæå®é¡µçå®ä½ç¹ |
| | | std::vector<std::pair<std::string, double>> getPositions(int axisId, int pageNumber, int pageSize) const; |
| | | |
| | | private: |
| | | RecipeManager(); |
| | | |
| | | private: |
| | | std::string m_recipeFolder; // é
æ¹æä»¶å¤¹è·¯å¾ |
| | | std::map<int, AxisInfo> m_axes; // è½´ä¿¡æ¯ç¼å |
| | | }; |
| | | |
| | | #endif // RECIPE_MANAGER_H |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | /** |
| | | * pugixml parser - version 1.14 |
| | | * -------------------------------------------------------- |
| | | * Copyright (C) 2006-2023, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) |
| | | * Report bugs and download new versions at https://pugixml.org/ |
| | | * |
| | | * This library is distributed under the MIT License. See notice at the end |
| | | * of this file. |
| | | * |
| | | * This work is based on the pugxml parser, which is: |
| | | * Copyright (C) 2003, by Kristen Wegner (kristen@tima.net) |
| | | */ |
| | | |
| | | #ifndef HEADER_PUGICONFIG_HPP |
| | | #define HEADER_PUGICONFIG_HPP |
| | | |
| | | // Uncomment this to enable wchar_t mode |
| | | // #define PUGIXML_WCHAR_MODE |
| | | |
| | | // Uncomment this to enable compact mode |
| | | // #define PUGIXML_COMPACT |
| | | |
| | | // Uncomment this to disable XPath |
| | | // #define PUGIXML_NO_XPATH |
| | | |
| | | // Uncomment this to disable STL |
| | | // #define PUGIXML_NO_STL |
| | | |
| | | // Uncomment this to disable exceptions |
| | | // #define PUGIXML_NO_EXCEPTIONS |
| | | |
| | | // Set this to control attributes for public classes/functions, i.e.: |
| | | // #define PUGIXML_API __declspec(dllexport) // to export all public symbols from DLL |
| | | // #define PUGIXML_CLASS __declspec(dllimport) // to import all classes from DLL |
| | | // #define PUGIXML_FUNCTION __fastcall // to set calling conventions to all public functions to fastcall |
| | | // In absence of PUGIXML_CLASS/PUGIXML_FUNCTION definitions PUGIXML_API is used instead |
| | | |
| | | // Tune these constants to adjust memory-related behavior |
| | | // #define PUGIXML_MEMORY_PAGE_SIZE 32768 |
| | | // #define PUGIXML_MEMORY_OUTPUT_STACK 10240 |
| | | // #define PUGIXML_MEMORY_XPATH_PAGE_SIZE 4096 |
| | | |
| | | // Tune this constant to adjust max nesting for XPath queries |
| | | // #define PUGIXML_XPATH_DEPTH_LIMIT 1024 |
| | | |
| | | // Uncomment this to switch to header-only version |
| | | // #define PUGIXML_HEADER_ONLY |
| | | |
| | | // Uncomment this to enable long long support |
| | | // #define PUGIXML_HAS_LONG_LONG |
| | | |
| | | #endif |
| | | |
| | | /** |
| | | * Copyright (c) 2006-2023 Arseny Kapoulkine |
| | | * |
| | | * Permission is hereby granted, free of charge, to any person |
| | | * obtaining a copy of this software and associated documentation |
| | | * files (the "Software"), to deal in the Software without |
| | | * restriction, including without limitation the rights to use, |
| | | * copy, modify, merge, publish, distribute, sublicense, and/or sell |
| | | * copies of the Software, and to permit persons to whom the |
| | | * Software is furnished to do so, subject to the following |
| | | * conditions: |
| | | * |
| | | * The above copyright notice and this permission notice shall be |
| | | * included in all copies or substantial portions of the Software. |
| | | * |
| | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| | | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
| | | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| | | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
| | | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
| | | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| | | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| | | * OTHER DEALINGS IN THE SOFTWARE. |
| | | */ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | /** |
| | | * pugixml parser - version 1.14 |
| | | * -------------------------------------------------------- |
| | | * Copyright (C) 2006-2023, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) |
| | | * Report bugs and download new versions at https://pugixml.org/ |
| | | * |
| | | * This library is distributed under the MIT License. See notice at the end |
| | | * of this file. |
| | | * |
| | | * This work is based on the pugxml parser, which is: |
| | | * Copyright (C) 2003, by Kristen Wegner (kristen@tima.net) |
| | | */ |
| | | |
| | | // Define version macro; evaluates to major * 1000 + minor * 10 + patch so that it's safe to use in less-than comparisons |
| | | // Note: pugixml used major * 100 + minor * 10 + patch format up until 1.9 (which had version identifier 190); starting from pugixml 1.10, the minor version number is two digits |
| | | #ifndef PUGIXML_VERSION |
| | | # define PUGIXML_VERSION 1140 // 1.14 |
| | | #endif |
| | | |
| | | // Include user configuration file (this can define various configuration macros) |
| | | #include "pugiconfig.hpp" |
| | | |
| | | #ifndef HEADER_PUGIXML_HPP |
| | | #define HEADER_PUGIXML_HPP |
| | | |
| | | // Include stddef.h for size_t and ptrdiff_t |
| | | #include <stddef.h> |
| | | |
| | | // Include exception header for XPath |
| | | #if !defined(PUGIXML_NO_XPATH) && !defined(PUGIXML_NO_EXCEPTIONS) |
| | | # include <exception> |
| | | #endif |
| | | |
| | | // Include STL headers |
| | | #ifndef PUGIXML_NO_STL |
| | | # include <iterator> |
| | | # include <iosfwd> |
| | | # include <string> |
| | | #endif |
| | | |
| | | // Macro for deprecated features |
| | | #ifndef PUGIXML_DEPRECATED |
| | | # if defined(__GNUC__) |
| | | # define PUGIXML_DEPRECATED __attribute__((deprecated)) |
| | | # elif defined(_MSC_VER) && _MSC_VER >= 1300 |
| | | # define PUGIXML_DEPRECATED __declspec(deprecated) |
| | | # else |
| | | # define PUGIXML_DEPRECATED |
| | | # endif |
| | | #endif |
| | | |
| | | // If no API is defined, assume default |
| | | #ifndef PUGIXML_API |
| | | # define PUGIXML_API |
| | | #endif |
| | | |
| | | // If no API for classes is defined, assume default |
| | | #ifndef PUGIXML_CLASS |
| | | # define PUGIXML_CLASS PUGIXML_API |
| | | #endif |
| | | |
| | | // If no API for functions is defined, assume default |
| | | #ifndef PUGIXML_FUNCTION |
| | | # define PUGIXML_FUNCTION PUGIXML_API |
| | | #endif |
| | | |
| | | // If the platform is known to have long long support, enable long long functions |
| | | #ifndef PUGIXML_HAS_LONG_LONG |
| | | # if __cplusplus >= 201103 |
| | | # define PUGIXML_HAS_LONG_LONG |
| | | # elif defined(_MSC_VER) && _MSC_VER >= 1400 |
| | | # define PUGIXML_HAS_LONG_LONG |
| | | # endif |
| | | #endif |
| | | |
| | | // If the platform is known to have move semantics support, compile move ctor/operator implementation |
| | | #ifndef PUGIXML_HAS_MOVE |
| | | # if __cplusplus >= 201103 |
| | | # define PUGIXML_HAS_MOVE |
| | | # elif defined(_MSC_VER) && _MSC_VER >= 1600 |
| | | # define PUGIXML_HAS_MOVE |
| | | # endif |
| | | #endif |
| | | |
| | | // If C++ is 2011 or higher, add 'noexcept' specifiers |
| | | #ifndef PUGIXML_NOEXCEPT |
| | | # if __cplusplus >= 201103 |
| | | # define PUGIXML_NOEXCEPT noexcept |
| | | # elif defined(_MSC_VER) && _MSC_VER >= 1900 |
| | | # define PUGIXML_NOEXCEPT noexcept |
| | | # else |
| | | # define PUGIXML_NOEXCEPT |
| | | # endif |
| | | #endif |
| | | |
| | | // Some functions can not be noexcept in compact mode |
| | | #ifdef PUGIXML_COMPACT |
| | | # define PUGIXML_NOEXCEPT_IF_NOT_COMPACT |
| | | #else |
| | | # define PUGIXML_NOEXCEPT_IF_NOT_COMPACT PUGIXML_NOEXCEPT |
| | | #endif |
| | | |
| | | // If C++ is 2011 or higher, add 'override' qualifiers |
| | | #ifndef PUGIXML_OVERRIDE |
| | | # if __cplusplus >= 201103 |
| | | # define PUGIXML_OVERRIDE override |
| | | # elif defined(_MSC_VER) && _MSC_VER >= 1700 |
| | | # define PUGIXML_OVERRIDE override |
| | | # else |
| | | # define PUGIXML_OVERRIDE |
| | | # endif |
| | | #endif |
| | | |
| | | // If C++ is 2011 or higher, use 'nullptr' |
| | | #ifndef PUGIXML_NULL |
| | | # if __cplusplus >= 201103 |
| | | # define PUGIXML_NULL nullptr |
| | | # elif defined(_MSC_VER) && _MSC_VER >= 1600 |
| | | # define PUGIXML_NULL nullptr |
| | | # else |
| | | # define PUGIXML_NULL 0 |
| | | # endif |
| | | #endif |
| | | |
| | | // Character interface macros |
| | | #ifdef PUGIXML_WCHAR_MODE |
| | | # define PUGIXML_TEXT(t) L ## t |
| | | # define PUGIXML_CHAR wchar_t |
| | | #else |
| | | # define PUGIXML_TEXT(t) t |
| | | # define PUGIXML_CHAR char |
| | | #endif |
| | | |
| | | namespace pugi |
| | | { |
| | | // Character type used for all internal storage and operations; depends on PUGIXML_WCHAR_MODE |
| | | typedef PUGIXML_CHAR char_t; |
| | | |
| | | #ifndef PUGIXML_NO_STL |
| | | // String type used for operations that work with STL string; depends on PUGIXML_WCHAR_MODE |
| | | typedef std::basic_string<PUGIXML_CHAR, std::char_traits<PUGIXML_CHAR>, std::allocator<PUGIXML_CHAR> > string_t; |
| | | #endif |
| | | } |
| | | |
| | | // The PugiXML namespace |
| | | namespace pugi |
| | | { |
| | | // Tree node types |
| | | enum xml_node_type |
| | | { |
| | | node_null, // Empty (null) node handle |
| | | node_document, // A document tree's absolute root |
| | | node_element, // Element tag, i.e. '<node/>' |
| | | node_pcdata, // Plain character data, i.e. 'text' |
| | | node_cdata, // Character data, i.e. '<![CDATA[text]]>' |
| | | node_comment, // Comment tag, i.e. '<!-- text -->' |
| | | node_pi, // Processing instruction, i.e. '<?name?>' |
| | | node_declaration, // Document declaration, i.e. '<?xml version="1.0"?>' |
| | | node_doctype // Document type declaration, i.e. '<!DOCTYPE doc>' |
| | | }; |
| | | |
| | | // Parsing options |
| | | |
| | | // Minimal parsing mode (equivalent to turning all other flags off). |
| | | // Only elements and PCDATA sections are added to the DOM tree, no text conversions are performed. |
| | | const unsigned int parse_minimal = 0x0000; |
| | | |
| | | // This flag determines if processing instructions (node_pi) are added to the DOM tree. This flag is off by default. |
| | | const unsigned int parse_pi = 0x0001; |
| | | |
| | | // This flag determines if comments (node_comment) are added to the DOM tree. This flag is off by default. |
| | | const unsigned int parse_comments = 0x0002; |
| | | |
| | | // This flag determines if CDATA sections (node_cdata) are added to the DOM tree. This flag is on by default. |
| | | const unsigned int parse_cdata = 0x0004; |
| | | |
| | | // This flag determines if plain character data (node_pcdata) that consist only of whitespace are added to the DOM tree. |
| | | // This flag is off by default; turning it on usually results in slower parsing and more memory consumption. |
| | | const unsigned int parse_ws_pcdata = 0x0008; |
| | | |
| | | // This flag determines if character and entity references are expanded during parsing. This flag is on by default. |
| | | const unsigned int parse_escapes = 0x0010; |
| | | |
| | | // This flag determines if EOL characters are normalized (converted to #xA) during parsing. This flag is on by default. |
| | | const unsigned int parse_eol = 0x0020; |
| | | |
| | | // This flag determines if attribute values are normalized using CDATA normalization rules during parsing. This flag is on by default. |
| | | const unsigned int parse_wconv_attribute = 0x0040; |
| | | |
| | | // This flag determines if attribute values are normalized using NMTOKENS normalization rules during parsing. This flag is off by default. |
| | | const unsigned int parse_wnorm_attribute = 0x0080; |
| | | |
| | | // This flag determines if document declaration (node_declaration) is added to the DOM tree. This flag is off by default. |
| | | const unsigned int parse_declaration = 0x0100; |
| | | |
| | | // This flag determines if document type declaration (node_doctype) is added to the DOM tree. This flag is off by default. |
| | | const unsigned int parse_doctype = 0x0200; |
| | | |
| | | // This flag determines if plain character data (node_pcdata) that is the only child of the parent node and that consists only |
| | | // of whitespace is added to the DOM tree. |
| | | // This flag is off by default; turning it on may result in slower parsing and more memory consumption. |
| | | const unsigned int parse_ws_pcdata_single = 0x0400; |
| | | |
| | | // This flag determines if leading and trailing whitespace is to be removed from plain character data. This flag is off by default. |
| | | const unsigned int parse_trim_pcdata = 0x0800; |
| | | |
| | | // This flag determines if plain character data that does not have a parent node is added to the DOM tree, and if an empty document |
| | | // is a valid document. This flag is off by default. |
| | | const unsigned int parse_fragment = 0x1000; |
| | | |
| | | // This flag determines if plain character data is be stored in the parent element's value. This significantly changes the structure of |
| | | // the document; this flag is only recommended for parsing documents with many PCDATA nodes in memory-constrained environments. |
| | | // This flag is off by default. |
| | | const unsigned int parse_embed_pcdata = 0x2000; |
| | | |
| | | // This flag determines whether determines whether the the two pcdata should be merged or not, if no intermediatory data are parsed in the document. |
| | | // This flag is off by default. |
| | | const unsigned int parse_merge_pcdata = 0x4000; |
| | | |
| | | // The default parsing mode. |
| | | // Elements, PCDATA and CDATA sections are added to the DOM tree, character/reference entities are expanded, |
| | | // End-of-Line characters are normalized, attribute values are normalized using CDATA normalization rules. |
| | | const unsigned int parse_default = parse_cdata | parse_escapes | parse_wconv_attribute | parse_eol; |
| | | |
| | | // The full parsing mode. |
| | | // Nodes of all types are added to the DOM tree, character/reference entities are expanded, |
| | | // End-of-Line characters are normalized, attribute values are normalized using CDATA normalization rules. |
| | | const unsigned int parse_full = parse_default | parse_pi | parse_comments | parse_declaration | parse_doctype; |
| | | |
| | | // These flags determine the encoding of input data for XML document |
| | | enum xml_encoding |
| | | { |
| | | encoding_auto, // Auto-detect input encoding using BOM or < / <? detection; use UTF8 if BOM is not found |
| | | encoding_utf8, // UTF8 encoding |
| | | encoding_utf16_le, // Little-endian UTF16 |
| | | encoding_utf16_be, // Big-endian UTF16 |
| | | encoding_utf16, // UTF16 with native endianness |
| | | encoding_utf32_le, // Little-endian UTF32 |
| | | encoding_utf32_be, // Big-endian UTF32 |
| | | encoding_utf32, // UTF32 with native endianness |
| | | encoding_wchar, // The same encoding wchar_t has (either UTF16 or UTF32) |
| | | encoding_latin1 |
| | | }; |
| | | |
| | | // Formatting flags |
| | | |
| | | // Indent the nodes that are written to output stream with as many indentation strings as deep the node is in DOM tree. This flag is on by default. |
| | | const unsigned int format_indent = 0x01; |
| | | |
| | | // Write encoding-specific BOM to the output stream. This flag is off by default. |
| | | const unsigned int format_write_bom = 0x02; |
| | | |
| | | // Use raw output mode (no indentation and no line breaks are written). This flag is off by default. |
| | | const unsigned int format_raw = 0x04; |
| | | |
| | | // Omit default XML declaration even if there is no declaration in the document. This flag is off by default. |
| | | const unsigned int format_no_declaration = 0x08; |
| | | |
| | | // Don't escape attribute values and PCDATA contents. This flag is off by default. |
| | | const unsigned int format_no_escapes = 0x10; |
| | | |
| | | // Open file using text mode in xml_document::save_file. This enables special character (i.e. new-line) conversions on some systems. This flag is off by default. |
| | | const unsigned int format_save_file_text = 0x20; |
| | | |
| | | // Write every attribute on a new line with appropriate indentation. This flag is off by default. |
| | | const unsigned int format_indent_attributes = 0x40; |
| | | |
| | | // Don't output empty element tags, instead writing an explicit start and end tag even if there are no children. This flag is off by default. |
| | | const unsigned int format_no_empty_element_tags = 0x80; |
| | | |
| | | // Skip characters belonging to range [0; 32) instead of "&#xNN;" encoding. This flag is off by default. |
| | | const unsigned int format_skip_control_chars = 0x100; |
| | | |
| | | // Use single quotes ' instead of double quotes " for enclosing attribute values. This flag is off by default. |
| | | const unsigned int format_attribute_single_quote = 0x200; |
| | | |
| | | // The default set of formatting flags. |
| | | // Nodes are indented depending on their depth in DOM tree, a default declaration is output if document has none. |
| | | const unsigned int format_default = format_indent; |
| | | |
| | | const int default_double_precision = 17; |
| | | const int default_float_precision = 9; |
| | | |
| | | // Forward declarations |
| | | struct xml_attribute_struct; |
| | | struct xml_node_struct; |
| | | |
| | | class xml_node_iterator; |
| | | class xml_attribute_iterator; |
| | | class xml_named_node_iterator; |
| | | |
| | | class xml_tree_walker; |
| | | |
| | | struct xml_parse_result; |
| | | |
| | | class xml_node; |
| | | |
| | | class xml_text; |
| | | |
| | | #ifndef PUGIXML_NO_XPATH |
| | | class xpath_node; |
| | | class xpath_node_set; |
| | | class xpath_query; |
| | | class xpath_variable_set; |
| | | #endif |
| | | |
| | | // Range-based for loop support |
| | | template <typename It> class xml_object_range |
| | | { |
| | | public: |
| | | typedef It const_iterator; |
| | | typedef It iterator; |
| | | |
| | | xml_object_range(It b, It e): _begin(b), _end(e) |
| | | { |
| | | } |
| | | |
| | | It begin() const { return _begin; } |
| | | It end() const { return _end; } |
| | | |
| | | bool empty() const { return _begin == _end; } |
| | | |
| | | private: |
| | | It _begin, _end; |
| | | }; |
| | | |
| | | // Writer interface for node printing (see xml_node::print) |
| | | class PUGIXML_CLASS xml_writer |
| | | { |
| | | public: |
| | | virtual ~xml_writer(); |
| | | |
| | | // Write memory chunk into stream/file/whatever |
| | | virtual void write(const void* data, size_t size) = 0; |
| | | }; |
| | | |
| | | // xml_writer implementation for FILE* |
| | | class PUGIXML_CLASS xml_writer_file: public xml_writer |
| | | { |
| | | public: |
| | | // Construct writer from a FILE* object; void* is used to avoid header dependencies on stdio |
| | | xml_writer_file(void* file); |
| | | |
| | | virtual void write(const void* data, size_t size) PUGIXML_OVERRIDE; |
| | | |
| | | private: |
| | | void* file; |
| | | }; |
| | | |
| | | #ifndef PUGIXML_NO_STL |
| | | // xml_writer implementation for streams |
| | | class PUGIXML_CLASS xml_writer_stream: public xml_writer |
| | | { |
| | | public: |
| | | // Construct writer from an output stream object |
| | | xml_writer_stream(std::basic_ostream<char, std::char_traits<char> >& stream); |
| | | xml_writer_stream(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& stream); |
| | | |
| | | virtual void write(const void* data, size_t size) PUGIXML_OVERRIDE; |
| | | |
| | | private: |
| | | std::basic_ostream<char, std::char_traits<char> >* narrow_stream; |
| | | std::basic_ostream<wchar_t, std::char_traits<wchar_t> >* wide_stream; |
| | | }; |
| | | #endif |
| | | |
| | | // A light-weight handle for manipulating attributes in DOM tree |
| | | class PUGIXML_CLASS xml_attribute |
| | | { |
| | | friend class xml_attribute_iterator; |
| | | friend class xml_node; |
| | | |
| | | private: |
| | | xml_attribute_struct* _attr; |
| | | |
| | | typedef void (*unspecified_bool_type)(xml_attribute***); |
| | | |
| | | public: |
| | | // Default constructor. Constructs an empty attribute. |
| | | xml_attribute(); |
| | | |
| | | // Constructs attribute from internal pointer |
| | | explicit xml_attribute(xml_attribute_struct* attr); |
| | | |
| | | // Safe bool conversion operator |
| | | operator unspecified_bool_type() const; |
| | | |
| | | // Borland C++ workaround |
| | | bool operator!() const; |
| | | |
| | | // Comparison operators (compares wrapped attribute pointers) |
| | | bool operator==(const xml_attribute& r) const; |
| | | bool operator!=(const xml_attribute& r) const; |
| | | bool operator<(const xml_attribute& r) const; |
| | | bool operator>(const xml_attribute& r) const; |
| | | bool operator<=(const xml_attribute& r) const; |
| | | bool operator>=(const xml_attribute& r) const; |
| | | |
| | | // Check if attribute is empty |
| | | bool empty() const; |
| | | |
| | | // Get attribute name/value, or "" if attribute is empty |
| | | const char_t* name() const; |
| | | const char_t* value() const; |
| | | |
| | | // Get attribute value, or the default value if attribute is empty |
| | | const char_t* as_string(const char_t* def = PUGIXML_TEXT("")) const; |
| | | |
| | | // Get attribute value as a number, or the default value if conversion did not succeed or attribute is empty |
| | | int as_int(int def = 0) const; |
| | | unsigned int as_uint(unsigned int def = 0) const; |
| | | double as_double(double def = 0) const; |
| | | float as_float(float def = 0) const; |
| | | |
| | | #ifdef PUGIXML_HAS_LONG_LONG |
| | | long long as_llong(long long def = 0) const; |
| | | unsigned long long as_ullong(unsigned long long def = 0) const; |
| | | #endif |
| | | |
| | | // Get attribute value as bool (returns true if first character is in '1tTyY' set), or the default value if attribute is empty |
| | | bool as_bool(bool def = false) const; |
| | | |
| | | // Set attribute name/value (returns false if attribute is empty or there is not enough memory) |
| | | bool set_name(const char_t* rhs); |
| | | bool set_name(const char_t* rhs, size_t size); |
| | | bool set_value(const char_t* rhs); |
| | | bool set_value(const char_t* rhs, size_t size); |
| | | |
| | | // Set attribute value with type conversion (numbers are converted to strings, boolean is converted to "true"/"false") |
| | | bool set_value(int rhs); |
| | | bool set_value(unsigned int rhs); |
| | | bool set_value(long rhs); |
| | | bool set_value(unsigned long rhs); |
| | | bool set_value(double rhs); |
| | | bool set_value(double rhs, int precision); |
| | | bool set_value(float rhs); |
| | | bool set_value(float rhs, int precision); |
| | | bool set_value(bool rhs); |
| | | |
| | | #ifdef PUGIXML_HAS_LONG_LONG |
| | | bool set_value(long long rhs); |
| | | bool set_value(unsigned long long rhs); |
| | | #endif |
| | | |
| | | // Set attribute value (equivalent to set_value without error checking) |
| | | xml_attribute& operator=(const char_t* rhs); |
| | | xml_attribute& operator=(int rhs); |
| | | xml_attribute& operator=(unsigned int rhs); |
| | | xml_attribute& operator=(long rhs); |
| | | xml_attribute& operator=(unsigned long rhs); |
| | | xml_attribute& operator=(double rhs); |
| | | xml_attribute& operator=(float rhs); |
| | | xml_attribute& operator=(bool rhs); |
| | | |
| | | #ifdef PUGIXML_HAS_LONG_LONG |
| | | xml_attribute& operator=(long long rhs); |
| | | xml_attribute& operator=(unsigned long long rhs); |
| | | #endif |
| | | |
| | | // Get next/previous attribute in the attribute list of the parent node |
| | | xml_attribute next_attribute() const; |
| | | xml_attribute previous_attribute() const; |
| | | |
| | | // Get hash value (unique for handles to the same object) |
| | | size_t hash_value() const; |
| | | |
| | | // Get internal pointer |
| | | xml_attribute_struct* internal_object() const; |
| | | }; |
| | | |
| | | #ifdef __BORLANDC__ |
| | | // Borland C++ workaround |
| | | bool PUGIXML_FUNCTION operator&&(const xml_attribute& lhs, bool rhs); |
| | | bool PUGIXML_FUNCTION operator||(const xml_attribute& lhs, bool rhs); |
| | | #endif |
| | | |
| | | // A light-weight handle for manipulating nodes in DOM tree |
| | | class PUGIXML_CLASS xml_node |
| | | { |
| | | friend class xml_attribute_iterator; |
| | | friend class xml_node_iterator; |
| | | friend class xml_named_node_iterator; |
| | | |
| | | protected: |
| | | xml_node_struct* _root; |
| | | |
| | | typedef void (*unspecified_bool_type)(xml_node***); |
| | | |
| | | public: |
| | | // Default constructor. Constructs an empty node. |
| | | xml_node(); |
| | | |
| | | // Constructs node from internal pointer |
| | | explicit xml_node(xml_node_struct* p); |
| | | |
| | | // Safe bool conversion operator |
| | | operator unspecified_bool_type() const; |
| | | |
| | | // Borland C++ workaround |
| | | bool operator!() const; |
| | | |
| | | // Comparison operators (compares wrapped node pointers) |
| | | bool operator==(const xml_node& r) const; |
| | | bool operator!=(const xml_node& r) const; |
| | | bool operator<(const xml_node& r) const; |
| | | bool operator>(const xml_node& r) const; |
| | | bool operator<=(const xml_node& r) const; |
| | | bool operator>=(const xml_node& r) const; |
| | | |
| | | // Check if node is empty. |
| | | bool empty() const; |
| | | |
| | | // Get node type |
| | | xml_node_type type() const; |
| | | |
| | | // Get node name, or "" if node is empty or it has no name |
| | | const char_t* name() const; |
| | | |
| | | // Get node value, or "" if node is empty or it has no value |
| | | // Note: For <node>text</node> node.value() does not return "text"! Use child_value() or text() methods to access text inside nodes. |
| | | const char_t* value() const; |
| | | |
| | | // Get attribute list |
| | | xml_attribute first_attribute() const; |
| | | xml_attribute last_attribute() const; |
| | | |
| | | // Get children list |
| | | xml_node first_child() const; |
| | | xml_node last_child() const; |
| | | |
| | | // Get next/previous sibling in the children list of the parent node |
| | | xml_node next_sibling() const; |
| | | xml_node previous_sibling() const; |
| | | |
| | | // Get parent node |
| | | xml_node parent() const; |
| | | |
| | | // Get root of DOM tree this node belongs to |
| | | xml_node root() const; |
| | | |
| | | // Get text object for the current node |
| | | xml_text text() const; |
| | | |
| | | // Get child, attribute or next/previous sibling with the specified name |
| | | xml_node child(const char_t* name) const; |
| | | xml_attribute attribute(const char_t* name) const; |
| | | xml_node next_sibling(const char_t* name) const; |
| | | xml_node previous_sibling(const char_t* name) const; |
| | | |
| | | // Get attribute, starting the search from a hint (and updating hint so that searching for a sequence of attributes is fast) |
| | | xml_attribute attribute(const char_t* name, xml_attribute& hint) const; |
| | | |
| | | // Get child value of current node; that is, value of the first child node of type PCDATA/CDATA |
| | | const char_t* child_value() const; |
| | | |
| | | // Get child value of child with specified name. Equivalent to child(name).child_value(). |
| | | const char_t* child_value(const char_t* name) const; |
| | | |
| | | // Set node name/value (returns false if node is empty, there is not enough memory, or node can not have name/value) |
| | | bool set_name(const char_t* rhs); |
| | | bool set_name(const char_t* rhs, size_t size); |
| | | bool set_value(const char_t* rhs); |
| | | bool set_value(const char_t* rhs, size_t size); |
| | | |
| | | // Add attribute with specified name. Returns added attribute, or empty attribute on errors. |
| | | xml_attribute append_attribute(const char_t* name); |
| | | xml_attribute prepend_attribute(const char_t* name); |
| | | xml_attribute insert_attribute_after(const char_t* name, const xml_attribute& attr); |
| | | xml_attribute insert_attribute_before(const char_t* name, const xml_attribute& attr); |
| | | |
| | | // Add a copy of the specified attribute. Returns added attribute, or empty attribute on errors. |
| | | xml_attribute append_copy(const xml_attribute& proto); |
| | | xml_attribute prepend_copy(const xml_attribute& proto); |
| | | xml_attribute insert_copy_after(const xml_attribute& proto, const xml_attribute& attr); |
| | | xml_attribute insert_copy_before(const xml_attribute& proto, const xml_attribute& attr); |
| | | |
| | | // Add child node with specified type. Returns added node, or empty node on errors. |
| | | xml_node append_child(xml_node_type type = node_element); |
| | | xml_node prepend_child(xml_node_type type = node_element); |
| | | xml_node insert_child_after(xml_node_type type, const xml_node& node); |
| | | xml_node insert_child_before(xml_node_type type, const xml_node& node); |
| | | |
| | | // Add child element with specified name. Returns added node, or empty node on errors. |
| | | xml_node append_child(const char_t* name); |
| | | xml_node prepend_child(const char_t* name); |
| | | xml_node insert_child_after(const char_t* name, const xml_node& node); |
| | | xml_node insert_child_before(const char_t* name, const xml_node& node); |
| | | |
| | | // Add a copy of the specified node as a child. Returns added node, or empty node on errors. |
| | | xml_node append_copy(const xml_node& proto); |
| | | xml_node prepend_copy(const xml_node& proto); |
| | | xml_node insert_copy_after(const xml_node& proto, const xml_node& node); |
| | | xml_node insert_copy_before(const xml_node& proto, const xml_node& node); |
| | | |
| | | // Move the specified node to become a child of this node. Returns moved node, or empty node on errors. |
| | | xml_node append_move(const xml_node& moved); |
| | | xml_node prepend_move(const xml_node& moved); |
| | | xml_node insert_move_after(const xml_node& moved, const xml_node& node); |
| | | xml_node insert_move_before(const xml_node& moved, const xml_node& node); |
| | | |
| | | // Remove specified attribute |
| | | bool remove_attribute(const xml_attribute& a); |
| | | bool remove_attribute(const char_t* name); |
| | | |
| | | // Remove all attributes |
| | | bool remove_attributes(); |
| | | |
| | | // Remove specified child |
| | | bool remove_child(const xml_node& n); |
| | | bool remove_child(const char_t* name); |
| | | |
| | | // Remove all children |
| | | bool remove_children(); |
| | | |
| | | // Parses buffer as an XML document fragment and appends all nodes as children of the current node. |
| | | // Copies/converts the buffer, so it may be deleted or changed after the function returns. |
| | | // Note: append_buffer allocates memory that has the lifetime of the owning document; removing the appended nodes does not immediately reclaim that memory. |
| | | xml_parse_result append_buffer(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); |
| | | |
| | | // Find attribute using predicate. Returns first attribute for which predicate returned true. |
| | | template <typename Predicate> xml_attribute find_attribute(Predicate pred) const |
| | | { |
| | | if (!_root) return xml_attribute(); |
| | | |
| | | for (xml_attribute attrib = first_attribute(); attrib; attrib = attrib.next_attribute()) |
| | | if (pred(attrib)) |
| | | return attrib; |
| | | |
| | | return xml_attribute(); |
| | | } |
| | | |
| | | // Find child node using predicate. Returns first child for which predicate returned true. |
| | | template <typename Predicate> xml_node find_child(Predicate pred) const |
| | | { |
| | | if (!_root) return xml_node(); |
| | | |
| | | for (xml_node node = first_child(); node; node = node.next_sibling()) |
| | | if (pred(node)) |
| | | return node; |
| | | |
| | | return xml_node(); |
| | | } |
| | | |
| | | // Find node from subtree using predicate. Returns first node from subtree (depth-first), for which predicate returned true. |
| | | template <typename Predicate> xml_node find_node(Predicate pred) const |
| | | { |
| | | if (!_root) return xml_node(); |
| | | |
| | | xml_node cur = first_child(); |
| | | |
| | | while (cur._root && cur._root != _root) |
| | | { |
| | | if (pred(cur)) return cur; |
| | | |
| | | if (cur.first_child()) cur = cur.first_child(); |
| | | else if (cur.next_sibling()) cur = cur.next_sibling(); |
| | | else |
| | | { |
| | | while (!cur.next_sibling() && cur._root != _root) cur = cur.parent(); |
| | | |
| | | if (cur._root != _root) cur = cur.next_sibling(); |
| | | } |
| | | } |
| | | |
| | | return xml_node(); |
| | | } |
| | | |
| | | // Find child node by attribute name/value |
| | | xml_node find_child_by_attribute(const char_t* name, const char_t* attr_name, const char_t* attr_value) const; |
| | | xml_node find_child_by_attribute(const char_t* attr_name, const char_t* attr_value) const; |
| | | |
| | | #ifndef PUGIXML_NO_STL |
| | | // Get the absolute node path from root as a text string. |
| | | string_t path(char_t delimiter = '/') const; |
| | | #endif |
| | | |
| | | // Search for a node by path consisting of node names and . or .. elements. |
| | | xml_node first_element_by_path(const char_t* path, char_t delimiter = '/') const; |
| | | |
| | | // Recursively traverse subtree with xml_tree_walker |
| | | bool traverse(xml_tree_walker& walker); |
| | | |
| | | #ifndef PUGIXML_NO_XPATH |
| | | // Select single node by evaluating XPath query. Returns first node from the resulting node set. |
| | | xpath_node select_node(const char_t* query, xpath_variable_set* variables = PUGIXML_NULL) const; |
| | | xpath_node select_node(const xpath_query& query) const; |
| | | |
| | | // Select node set by evaluating XPath query |
| | | xpath_node_set select_nodes(const char_t* query, xpath_variable_set* variables = PUGIXML_NULL) const; |
| | | xpath_node_set select_nodes(const xpath_query& query) const; |
| | | |
| | | // (deprecated: use select_node instead) Select single node by evaluating XPath query. |
| | | PUGIXML_DEPRECATED xpath_node select_single_node(const char_t* query, xpath_variable_set* variables = PUGIXML_NULL) const; |
| | | PUGIXML_DEPRECATED xpath_node select_single_node(const xpath_query& query) const; |
| | | |
| | | #endif |
| | | |
| | | // Print subtree using a writer object |
| | | void print(xml_writer& writer, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const; |
| | | |
| | | #ifndef PUGIXML_NO_STL |
| | | // Print subtree to stream |
| | | void print(std::basic_ostream<char, std::char_traits<char> >& os, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const; |
| | | void print(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& os, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, unsigned int depth = 0) const; |
| | | #endif |
| | | |
| | | // Child nodes iterators |
| | | typedef xml_node_iterator iterator; |
| | | |
| | | iterator begin() const; |
| | | iterator end() const; |
| | | |
| | | // Attribute iterators |
| | | typedef xml_attribute_iterator attribute_iterator; |
| | | |
| | | attribute_iterator attributes_begin() const; |
| | | attribute_iterator attributes_end() const; |
| | | |
| | | // Range-based for support |
| | | xml_object_range<xml_node_iterator> children() const; |
| | | xml_object_range<xml_attribute_iterator> attributes() const; |
| | | |
| | | // Range-based for support for all children with the specified name |
| | | // Note: name pointer must have a longer lifetime than the returned object; be careful with passing temporaries! |
| | | xml_object_range<xml_named_node_iterator> children(const char_t* name) const; |
| | | |
| | | // Get node offset in parsed file/string (in char_t units) for debugging purposes |
| | | ptrdiff_t offset_debug() const; |
| | | |
| | | // Get hash value (unique for handles to the same object) |
| | | size_t hash_value() const; |
| | | |
| | | // Get internal pointer |
| | | xml_node_struct* internal_object() const; |
| | | }; |
| | | |
| | | #ifdef __BORLANDC__ |
| | | // Borland C++ workaround |
| | | bool PUGIXML_FUNCTION operator&&(const xml_node& lhs, bool rhs); |
| | | bool PUGIXML_FUNCTION operator||(const xml_node& lhs, bool rhs); |
| | | #endif |
| | | |
| | | // A helper for working with text inside PCDATA nodes |
| | | class PUGIXML_CLASS xml_text |
| | | { |
| | | friend class xml_node; |
| | | |
| | | xml_node_struct* _root; |
| | | |
| | | typedef void (*unspecified_bool_type)(xml_text***); |
| | | |
| | | explicit xml_text(xml_node_struct* root); |
| | | |
| | | xml_node_struct* _data_new(); |
| | | xml_node_struct* _data() const; |
| | | |
| | | public: |
| | | // Default constructor. Constructs an empty object. |
| | | xml_text(); |
| | | |
| | | // Safe bool conversion operator |
| | | operator unspecified_bool_type() const; |
| | | |
| | | // Borland C++ workaround |
| | | bool operator!() const; |
| | | |
| | | // Check if text object is empty |
| | | bool empty() const; |
| | | |
| | | // Get text, or "" if object is empty |
| | | const char_t* get() const; |
| | | |
| | | // Get text, or the default value if object is empty |
| | | const char_t* as_string(const char_t* def = PUGIXML_TEXT("")) const; |
| | | |
| | | // Get text as a number, or the default value if conversion did not succeed or object is empty |
| | | int as_int(int def = 0) const; |
| | | unsigned int as_uint(unsigned int def = 0) const; |
| | | double as_double(double def = 0) const; |
| | | float as_float(float def = 0) const; |
| | | |
| | | #ifdef PUGIXML_HAS_LONG_LONG |
| | | long long as_llong(long long def = 0) const; |
| | | unsigned long long as_ullong(unsigned long long def = 0) const; |
| | | #endif |
| | | |
| | | // Get text as bool (returns true if first character is in '1tTyY' set), or the default value if object is empty |
| | | bool as_bool(bool def = false) const; |
| | | |
| | | // Set text (returns false if object is empty or there is not enough memory) |
| | | bool set(const char_t* rhs); |
| | | bool set(const char_t* rhs, size_t size); |
| | | |
| | | // Set text with type conversion (numbers are converted to strings, boolean is converted to "true"/"false") |
| | | bool set(int rhs); |
| | | bool set(unsigned int rhs); |
| | | bool set(long rhs); |
| | | bool set(unsigned long rhs); |
| | | bool set(double rhs); |
| | | bool set(double rhs, int precision); |
| | | bool set(float rhs); |
| | | bool set(float rhs, int precision); |
| | | bool set(bool rhs); |
| | | |
| | | #ifdef PUGIXML_HAS_LONG_LONG |
| | | bool set(long long rhs); |
| | | bool set(unsigned long long rhs); |
| | | #endif |
| | | |
| | | // Set text (equivalent to set without error checking) |
| | | xml_text& operator=(const char_t* rhs); |
| | | xml_text& operator=(int rhs); |
| | | xml_text& operator=(unsigned int rhs); |
| | | xml_text& operator=(long rhs); |
| | | xml_text& operator=(unsigned long rhs); |
| | | xml_text& operator=(double rhs); |
| | | xml_text& operator=(float rhs); |
| | | xml_text& operator=(bool rhs); |
| | | |
| | | #ifdef PUGIXML_HAS_LONG_LONG |
| | | xml_text& operator=(long long rhs); |
| | | xml_text& operator=(unsigned long long rhs); |
| | | #endif |
| | | |
| | | // Get the data node (node_pcdata or node_cdata) for this object |
| | | xml_node data() const; |
| | | }; |
| | | |
| | | #ifdef __BORLANDC__ |
| | | // Borland C++ workaround |
| | | bool PUGIXML_FUNCTION operator&&(const xml_text& lhs, bool rhs); |
| | | bool PUGIXML_FUNCTION operator||(const xml_text& lhs, bool rhs); |
| | | #endif |
| | | |
| | | // Child node iterator (a bidirectional iterator over a collection of xml_node) |
| | | class PUGIXML_CLASS xml_node_iterator |
| | | { |
| | | friend class xml_node; |
| | | |
| | | private: |
| | | mutable xml_node _wrap; |
| | | xml_node _parent; |
| | | |
| | | xml_node_iterator(xml_node_struct* ref, xml_node_struct* parent); |
| | | |
| | | public: |
| | | // Iterator traits |
| | | typedef ptrdiff_t difference_type; |
| | | typedef xml_node value_type; |
| | | typedef xml_node* pointer; |
| | | typedef xml_node& reference; |
| | | |
| | | #ifndef PUGIXML_NO_STL |
| | | typedef std::bidirectional_iterator_tag iterator_category; |
| | | #endif |
| | | |
| | | // Default constructor |
| | | xml_node_iterator(); |
| | | |
| | | // Construct an iterator which points to the specified node |
| | | xml_node_iterator(const xml_node& node); |
| | | |
| | | // Iterator operators |
| | | bool operator==(const xml_node_iterator& rhs) const; |
| | | bool operator!=(const xml_node_iterator& rhs) const; |
| | | |
| | | xml_node& operator*() const; |
| | | xml_node* operator->() const; |
| | | |
| | | xml_node_iterator& operator++(); |
| | | xml_node_iterator operator++(int); |
| | | |
| | | xml_node_iterator& operator--(); |
| | | xml_node_iterator operator--(int); |
| | | }; |
| | | |
| | | // Attribute iterator (a bidirectional iterator over a collection of xml_attribute) |
| | | class PUGIXML_CLASS xml_attribute_iterator |
| | | { |
| | | friend class xml_node; |
| | | |
| | | private: |
| | | mutable xml_attribute _wrap; |
| | | xml_node _parent; |
| | | |
| | | xml_attribute_iterator(xml_attribute_struct* ref, xml_node_struct* parent); |
| | | |
| | | public: |
| | | // Iterator traits |
| | | typedef ptrdiff_t difference_type; |
| | | typedef xml_attribute value_type; |
| | | typedef xml_attribute* pointer; |
| | | typedef xml_attribute& reference; |
| | | |
| | | #ifndef PUGIXML_NO_STL |
| | | typedef std::bidirectional_iterator_tag iterator_category; |
| | | #endif |
| | | |
| | | // Default constructor |
| | | xml_attribute_iterator(); |
| | | |
| | | // Construct an iterator which points to the specified attribute |
| | | xml_attribute_iterator(const xml_attribute& attr, const xml_node& parent); |
| | | |
| | | // Iterator operators |
| | | bool operator==(const xml_attribute_iterator& rhs) const; |
| | | bool operator!=(const xml_attribute_iterator& rhs) const; |
| | | |
| | | xml_attribute& operator*() const; |
| | | xml_attribute* operator->() const; |
| | | |
| | | xml_attribute_iterator& operator++(); |
| | | xml_attribute_iterator operator++(int); |
| | | |
| | | xml_attribute_iterator& operator--(); |
| | | xml_attribute_iterator operator--(int); |
| | | }; |
| | | |
| | | // Named node range helper |
| | | class PUGIXML_CLASS xml_named_node_iterator |
| | | { |
| | | friend class xml_node; |
| | | |
| | | public: |
| | | // Iterator traits |
| | | typedef ptrdiff_t difference_type; |
| | | typedef xml_node value_type; |
| | | typedef xml_node* pointer; |
| | | typedef xml_node& reference; |
| | | |
| | | #ifndef PUGIXML_NO_STL |
| | | typedef std::bidirectional_iterator_tag iterator_category; |
| | | #endif |
| | | |
| | | // Default constructor |
| | | xml_named_node_iterator(); |
| | | |
| | | // Construct an iterator which points to the specified node |
| | | // Note: name pointer is stored in the iterator and must have a longer lifetime than iterator itself |
| | | xml_named_node_iterator(const xml_node& node, const char_t* name); |
| | | |
| | | // Iterator operators |
| | | bool operator==(const xml_named_node_iterator& rhs) const; |
| | | bool operator!=(const xml_named_node_iterator& rhs) const; |
| | | |
| | | xml_node& operator*() const; |
| | | xml_node* operator->() const; |
| | | |
| | | xml_named_node_iterator& operator++(); |
| | | xml_named_node_iterator operator++(int); |
| | | |
| | | xml_named_node_iterator& operator--(); |
| | | xml_named_node_iterator operator--(int); |
| | | |
| | | private: |
| | | mutable xml_node _wrap; |
| | | xml_node _parent; |
| | | const char_t* _name; |
| | | |
| | | xml_named_node_iterator(xml_node_struct* ref, xml_node_struct* parent, const char_t* name); |
| | | }; |
| | | |
| | | // Abstract tree walker class (see xml_node::traverse) |
| | | class PUGIXML_CLASS xml_tree_walker |
| | | { |
| | | friend class xml_node; |
| | | |
| | | private: |
| | | int _depth; |
| | | |
| | | protected: |
| | | // Get current traversal depth |
| | | int depth() const; |
| | | |
| | | public: |
| | | xml_tree_walker(); |
| | | virtual ~xml_tree_walker(); |
| | | |
| | | // Callback that is called when traversal begins |
| | | virtual bool begin(xml_node& node); |
| | | |
| | | // Callback that is called for each node traversed |
| | | virtual bool for_each(xml_node& node) = 0; |
| | | |
| | | // Callback that is called when traversal ends |
| | | virtual bool end(xml_node& node); |
| | | }; |
| | | |
| | | // Parsing status, returned as part of xml_parse_result object |
| | | enum xml_parse_status |
| | | { |
| | | status_ok = 0, // No error |
| | | |
| | | status_file_not_found, // File was not found during load_file() |
| | | status_io_error, // Error reading from file/stream |
| | | status_out_of_memory, // Could not allocate memory |
| | | status_internal_error, // Internal error occurred |
| | | |
| | | status_unrecognized_tag, // Parser could not determine tag type |
| | | |
| | | status_bad_pi, // Parsing error occurred while parsing document declaration/processing instruction |
| | | status_bad_comment, // Parsing error occurred while parsing comment |
| | | status_bad_cdata, // Parsing error occurred while parsing CDATA section |
| | | status_bad_doctype, // Parsing error occurred while parsing document type declaration |
| | | status_bad_pcdata, // Parsing error occurred while parsing PCDATA section |
| | | status_bad_start_element, // Parsing error occurred while parsing start element tag |
| | | status_bad_attribute, // Parsing error occurred while parsing element attribute |
| | | status_bad_end_element, // Parsing error occurred while parsing end element tag |
| | | status_end_element_mismatch,// There was a mismatch of start-end tags (closing tag had incorrect name, some tag was not closed or there was an excessive closing tag) |
| | | |
| | | status_append_invalid_root, // Unable to append nodes since root type is not node_element or node_document (exclusive to xml_node::append_buffer) |
| | | |
| | | status_no_document_element // Parsing resulted in a document without element nodes |
| | | }; |
| | | |
| | | // Parsing result |
| | | struct PUGIXML_CLASS xml_parse_result |
| | | { |
| | | // Parsing status (see xml_parse_status) |
| | | xml_parse_status status; |
| | | |
| | | // Last parsed offset (in char_t units from start of input data) |
| | | ptrdiff_t offset; |
| | | |
| | | // Source document encoding |
| | | xml_encoding encoding; |
| | | |
| | | // Default constructor, initializes object to failed state |
| | | xml_parse_result(); |
| | | |
| | | // Cast to bool operator |
| | | operator bool() const; |
| | | |
| | | // Get error description |
| | | const char* description() const; |
| | | }; |
| | | |
| | | // Document class (DOM tree root) |
| | | class PUGIXML_CLASS xml_document: public xml_node |
| | | { |
| | | private: |
| | | char_t* _buffer; |
| | | |
| | | char _memory[192]; |
| | | |
| | | // Non-copyable semantics |
| | | xml_document(const xml_document&); |
| | | xml_document& operator=(const xml_document&); |
| | | |
| | | void _create(); |
| | | void _destroy(); |
| | | void _move(xml_document& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT; |
| | | |
| | | public: |
| | | // Default constructor, makes empty document |
| | | xml_document(); |
| | | |
| | | // Destructor, invalidates all node/attribute handles to this document |
| | | ~xml_document(); |
| | | |
| | | #ifdef PUGIXML_HAS_MOVE |
| | | // Move semantics support |
| | | xml_document(xml_document&& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT; |
| | | xml_document& operator=(xml_document&& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT; |
| | | #endif |
| | | |
| | | // Removes all nodes, leaving the empty document |
| | | void reset(); |
| | | |
| | | // Removes all nodes, then copies the entire contents of the specified document |
| | | void reset(const xml_document& proto); |
| | | |
| | | #ifndef PUGIXML_NO_STL |
| | | // Load document from stream. |
| | | xml_parse_result load(std::basic_istream<char, std::char_traits<char> >& stream, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); |
| | | xml_parse_result load(std::basic_istream<wchar_t, std::char_traits<wchar_t> >& stream, unsigned int options = parse_default); |
| | | #endif |
| | | |
| | | // (deprecated: use load_string instead) Load document from zero-terminated string. No encoding conversions are applied. |
| | | PUGIXML_DEPRECATED xml_parse_result load(const char_t* contents, unsigned int options = parse_default); |
| | | |
| | | // Load document from zero-terminated string. No encoding conversions are applied. |
| | | xml_parse_result load_string(const char_t* contents, unsigned int options = parse_default); |
| | | |
| | | // Load document from file |
| | | xml_parse_result load_file(const char* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); |
| | | xml_parse_result load_file(const wchar_t* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); |
| | | |
| | | // Load document from buffer. Copies/converts the buffer, so it may be deleted or changed after the function returns. |
| | | xml_parse_result load_buffer(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); |
| | | |
| | | // Load document from buffer, using the buffer for in-place parsing (the buffer is modified and used for storage of document data). |
| | | // You should ensure that buffer data will persist throughout the document's lifetime, and free the buffer memory manually once document is destroyed. |
| | | xml_parse_result load_buffer_inplace(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); |
| | | |
| | | // Load document from buffer, using the buffer for in-place parsing (the buffer is modified and used for storage of document data). |
| | | // You should allocate the buffer with pugixml allocation function; document will free the buffer when it is no longer needed (you can't use it anymore). |
| | | xml_parse_result load_buffer_inplace_own(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); |
| | | |
| | | // Save XML document to writer (semantics is slightly different from xml_node::print, see documentation for details). |
| | | void save(xml_writer& writer, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; |
| | | |
| | | #ifndef PUGIXML_NO_STL |
| | | // Save XML document to stream (semantics is slightly different from xml_node::print, see documentation for details). |
| | | void save(std::basic_ostream<char, std::char_traits<char> >& stream, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; |
| | | void save(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& stream, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default) const; |
| | | #endif |
| | | |
| | | // Save XML to file |
| | | bool save_file(const char* path, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; |
| | | bool save_file(const wchar_t* path, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; |
| | | |
| | | // Get document element |
| | | xml_node document_element() const; |
| | | }; |
| | | |
| | | #ifndef PUGIXML_NO_XPATH |
| | | // XPath query return type |
| | | enum xpath_value_type |
| | | { |
| | | xpath_type_none, // Unknown type (query failed to compile) |
| | | xpath_type_node_set, // Node set (xpath_node_set) |
| | | xpath_type_number, // Number |
| | | xpath_type_string, // String |
| | | xpath_type_boolean // Boolean |
| | | }; |
| | | |
| | | // XPath parsing result |
| | | struct PUGIXML_CLASS xpath_parse_result |
| | | { |
| | | // Error message (0 if no error) |
| | | const char* error; |
| | | |
| | | // Last parsed offset (in char_t units from string start) |
| | | ptrdiff_t offset; |
| | | |
| | | // Default constructor, initializes object to failed state |
| | | xpath_parse_result(); |
| | | |
| | | // Cast to bool operator |
| | | operator bool() const; |
| | | |
| | | // Get error description |
| | | const char* description() const; |
| | | }; |
| | | |
| | | // A single XPath variable |
| | | class PUGIXML_CLASS xpath_variable |
| | | { |
| | | friend class xpath_variable_set; |
| | | |
| | | protected: |
| | | xpath_value_type _type; |
| | | xpath_variable* _next; |
| | | |
| | | xpath_variable(xpath_value_type type); |
| | | |
| | | // Non-copyable semantics |
| | | xpath_variable(const xpath_variable&); |
| | | xpath_variable& operator=(const xpath_variable&); |
| | | |
| | | public: |
| | | // Get variable name |
| | | const char_t* name() const; |
| | | |
| | | // Get variable type |
| | | xpath_value_type type() const; |
| | | |
| | | // Get variable value; no type conversion is performed, default value (false, NaN, empty string, empty node set) is returned on type mismatch error |
| | | bool get_boolean() const; |
| | | double get_number() const; |
| | | const char_t* get_string() const; |
| | | const xpath_node_set& get_node_set() const; |
| | | |
| | | // Set variable value; no type conversion is performed, false is returned on type mismatch error |
| | | bool set(bool value); |
| | | bool set(double value); |
| | | bool set(const char_t* value); |
| | | bool set(const xpath_node_set& value); |
| | | }; |
| | | |
| | | // A set of XPath variables |
| | | class PUGIXML_CLASS xpath_variable_set |
| | | { |
| | | private: |
| | | xpath_variable* _data[64]; |
| | | |
| | | void _assign(const xpath_variable_set& rhs); |
| | | void _swap(xpath_variable_set& rhs); |
| | | |
| | | xpath_variable* _find(const char_t* name) const; |
| | | |
| | | static bool _clone(xpath_variable* var, xpath_variable** out_result); |
| | | static void _destroy(xpath_variable* var); |
| | | |
| | | public: |
| | | // Default constructor/destructor |
| | | xpath_variable_set(); |
| | | ~xpath_variable_set(); |
| | | |
| | | // Copy constructor/assignment operator |
| | | xpath_variable_set(const xpath_variable_set& rhs); |
| | | xpath_variable_set& operator=(const xpath_variable_set& rhs); |
| | | |
| | | #ifdef PUGIXML_HAS_MOVE |
| | | // Move semantics support |
| | | xpath_variable_set(xpath_variable_set&& rhs) PUGIXML_NOEXCEPT; |
| | | xpath_variable_set& operator=(xpath_variable_set&& rhs) PUGIXML_NOEXCEPT; |
| | | #endif |
| | | |
| | | // Add a new variable or get the existing one, if the types match |
| | | xpath_variable* add(const char_t* name, xpath_value_type type); |
| | | |
| | | // Set value of an existing variable; no type conversion is performed, false is returned if there is no such variable or if types mismatch |
| | | bool set(const char_t* name, bool value); |
| | | bool set(const char_t* name, double value); |
| | | bool set(const char_t* name, const char_t* value); |
| | | bool set(const char_t* name, const xpath_node_set& value); |
| | | |
| | | // Get existing variable by name |
| | | xpath_variable* get(const char_t* name); |
| | | const xpath_variable* get(const char_t* name) const; |
| | | }; |
| | | |
| | | // A compiled XPath query object |
| | | class PUGIXML_CLASS xpath_query |
| | | { |
| | | private: |
| | | void* _impl; |
| | | xpath_parse_result _result; |
| | | |
| | | typedef void (*unspecified_bool_type)(xpath_query***); |
| | | |
| | | // Non-copyable semantics |
| | | xpath_query(const xpath_query&); |
| | | xpath_query& operator=(const xpath_query&); |
| | | |
| | | public: |
| | | // Construct a compiled object from XPath expression. |
| | | // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on compilation errors. |
| | | explicit xpath_query(const char_t* query, xpath_variable_set* variables = PUGIXML_NULL); |
| | | |
| | | // Constructor |
| | | xpath_query(); |
| | | |
| | | // Destructor |
| | | ~xpath_query(); |
| | | |
| | | #ifdef PUGIXML_HAS_MOVE |
| | | // Move semantics support |
| | | xpath_query(xpath_query&& rhs) PUGIXML_NOEXCEPT; |
| | | xpath_query& operator=(xpath_query&& rhs) PUGIXML_NOEXCEPT; |
| | | #endif |
| | | |
| | | // Get query expression return type |
| | | xpath_value_type return_type() const; |
| | | |
| | | // Evaluate expression as boolean value in the specified context; performs type conversion if necessary. |
| | | // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. |
| | | bool evaluate_boolean(const xpath_node& n) const; |
| | | |
| | | // Evaluate expression as double value in the specified context; performs type conversion if necessary. |
| | | // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. |
| | | double evaluate_number(const xpath_node& n) const; |
| | | |
| | | #ifndef PUGIXML_NO_STL |
| | | // Evaluate expression as string value in the specified context; performs type conversion if necessary. |
| | | // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. |
| | | string_t evaluate_string(const xpath_node& n) const; |
| | | #endif |
| | | |
| | | // Evaluate expression as string value in the specified context; performs type conversion if necessary. |
| | | // At most capacity characters are written to the destination buffer, full result size is returned (includes terminating zero). |
| | | // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. |
| | | // If PUGIXML_NO_EXCEPTIONS is defined, returns empty set instead. |
| | | size_t evaluate_string(char_t* buffer, size_t capacity, const xpath_node& n) const; |
| | | |
| | | // Evaluate expression as node set in the specified context. |
| | | // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on type mismatch and std::bad_alloc on out of memory errors. |
| | | // If PUGIXML_NO_EXCEPTIONS is defined, returns empty node set instead. |
| | | xpath_node_set evaluate_node_set(const xpath_node& n) const; |
| | | |
| | | // Evaluate expression as node set in the specified context. |
| | | // Return first node in document order, or empty node if node set is empty. |
| | | // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on type mismatch and std::bad_alloc on out of memory errors. |
| | | // If PUGIXML_NO_EXCEPTIONS is defined, returns empty node instead. |
| | | xpath_node evaluate_node(const xpath_node& n) const; |
| | | |
| | | // Get parsing result (used to get compilation errors in PUGIXML_NO_EXCEPTIONS mode) |
| | | const xpath_parse_result& result() const; |
| | | |
| | | // Safe bool conversion operator |
| | | operator unspecified_bool_type() const; |
| | | |
| | | // Borland C++ workaround |
| | | bool operator!() const; |
| | | }; |
| | | |
| | | #ifndef PUGIXML_NO_EXCEPTIONS |
| | | #if defined(_MSC_VER) |
| | | // C4275 can be ignored in Visual C++ if you are deriving |
| | | // from a type in the Standard C++ Library |
| | | #pragma warning(push) |
| | | #pragma warning(disable: 4275) |
| | | #endif |
| | | // XPath exception class |
| | | class PUGIXML_CLASS xpath_exception: public std::exception |
| | | { |
| | | private: |
| | | xpath_parse_result _result; |
| | | |
| | | public: |
| | | // Construct exception from parse result |
| | | explicit xpath_exception(const xpath_parse_result& result); |
| | | |
| | | // Get error message |
| | | virtual const char* what() const throw() PUGIXML_OVERRIDE; |
| | | |
| | | // Get parse result |
| | | const xpath_parse_result& result() const; |
| | | }; |
| | | #if defined(_MSC_VER) |
| | | #pragma warning(pop) |
| | | #endif |
| | | #endif |
| | | |
| | | // XPath node class (either xml_node or xml_attribute) |
| | | class PUGIXML_CLASS xpath_node |
| | | { |
| | | private: |
| | | xml_node _node; |
| | | xml_attribute _attribute; |
| | | |
| | | typedef void (*unspecified_bool_type)(xpath_node***); |
| | | |
| | | public: |
| | | // Default constructor; constructs empty XPath node |
| | | xpath_node(); |
| | | |
| | | // Construct XPath node from XML node/attribute |
| | | xpath_node(const xml_node& node); |
| | | xpath_node(const xml_attribute& attribute, const xml_node& parent); |
| | | |
| | | // Get node/attribute, if any |
| | | xml_node node() const; |
| | | xml_attribute attribute() const; |
| | | |
| | | // Get parent of contained node/attribute |
| | | xml_node parent() const; |
| | | |
| | | // Safe bool conversion operator |
| | | operator unspecified_bool_type() const; |
| | | |
| | | // Borland C++ workaround |
| | | bool operator!() const; |
| | | |
| | | // Comparison operators |
| | | bool operator==(const xpath_node& n) const; |
| | | bool operator!=(const xpath_node& n) const; |
| | | }; |
| | | |
| | | #ifdef __BORLANDC__ |
| | | // Borland C++ workaround |
| | | bool PUGIXML_FUNCTION operator&&(const xpath_node& lhs, bool rhs); |
| | | bool PUGIXML_FUNCTION operator||(const xpath_node& lhs, bool rhs); |
| | | #endif |
| | | |
| | | // A fixed-size collection of XPath nodes |
| | | class PUGIXML_CLASS xpath_node_set |
| | | { |
| | | public: |
| | | // Collection type |
| | | enum type_t |
| | | { |
| | | type_unsorted, // Not ordered |
| | | type_sorted, // Sorted by document order (ascending) |
| | | type_sorted_reverse // Sorted by document order (descending) |
| | | }; |
| | | |
| | | // Constant iterator type |
| | | typedef const xpath_node* const_iterator; |
| | | |
| | | // We define non-constant iterator to be the same as constant iterator so that various generic algorithms (i.e. boost foreach) work |
| | | typedef const xpath_node* iterator; |
| | | |
| | | // Default constructor. Constructs empty set. |
| | | xpath_node_set(); |
| | | |
| | | // Constructs a set from iterator range; data is not checked for duplicates and is not sorted according to provided type, so be careful |
| | | xpath_node_set(const_iterator begin, const_iterator end, type_t type = type_unsorted); |
| | | |
| | | // Destructor |
| | | ~xpath_node_set(); |
| | | |
| | | // Copy constructor/assignment operator |
| | | xpath_node_set(const xpath_node_set& ns); |
| | | xpath_node_set& operator=(const xpath_node_set& ns); |
| | | |
| | | #ifdef PUGIXML_HAS_MOVE |
| | | // Move semantics support |
| | | xpath_node_set(xpath_node_set&& rhs) PUGIXML_NOEXCEPT; |
| | | xpath_node_set& operator=(xpath_node_set&& rhs) PUGIXML_NOEXCEPT; |
| | | #endif |
| | | |
| | | // Get collection type |
| | | type_t type() const; |
| | | |
| | | // Get collection size |
| | | size_t size() const; |
| | | |
| | | // Indexing operator |
| | | const xpath_node& operator[](size_t index) const; |
| | | |
| | | // Collection iterators |
| | | const_iterator begin() const; |
| | | const_iterator end() const; |
| | | |
| | | // Sort the collection in ascending/descending order by document order |
| | | void sort(bool reverse = false); |
| | | |
| | | // Get first node in the collection by document order |
| | | xpath_node first() const; |
| | | |
| | | // Check if collection is empty |
| | | bool empty() const; |
| | | |
| | | private: |
| | | type_t _type; |
| | | |
| | | xpath_node _storage[1]; |
| | | |
| | | xpath_node* _begin; |
| | | xpath_node* _end; |
| | | |
| | | void _assign(const_iterator begin, const_iterator end, type_t type); |
| | | void _move(xpath_node_set& rhs) PUGIXML_NOEXCEPT; |
| | | }; |
| | | #endif |
| | | |
| | | #ifndef PUGIXML_NO_STL |
| | | // Convert wide string to UTF8 |
| | | std::basic_string<char, std::char_traits<char>, std::allocator<char> > PUGIXML_FUNCTION as_utf8(const wchar_t* str); |
| | | std::basic_string<char, std::char_traits<char>, std::allocator<char> > PUGIXML_FUNCTION as_utf8(const std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >& str); |
| | | |
| | | // Convert UTF8 to wide string |
| | | std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > PUGIXML_FUNCTION as_wide(const char* str); |
| | | std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > PUGIXML_FUNCTION as_wide(const std::basic_string<char, std::char_traits<char>, std::allocator<char> >& str); |
| | | #endif |
| | | |
| | | // Memory allocation function interface; returns pointer to allocated memory or NULL on failure |
| | | typedef void* (*allocation_function)(size_t size); |
| | | |
| | | // Memory deallocation function interface |
| | | typedef void (*deallocation_function)(void* ptr); |
| | | |
| | | // Override default memory management functions. All subsequent allocations/deallocations will be performed via supplied functions. |
| | | void PUGIXML_FUNCTION set_memory_management_functions(allocation_function allocate, deallocation_function deallocate); |
| | | |
| | | // Get current memory management functions |
| | | allocation_function PUGIXML_FUNCTION get_memory_allocation_function(); |
| | | deallocation_function PUGIXML_FUNCTION get_memory_deallocation_function(); |
| | | } |
| | | |
| | | #if !defined(PUGIXML_NO_STL) && (defined(_MSC_VER) || defined(__ICC)) |
| | | namespace std |
| | | { |
| | | // Workarounds for (non-standard) iterator category detection for older versions (MSVC7/IC8 and earlier) |
| | | std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_node_iterator&); |
| | | std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_attribute_iterator&); |
| | | std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_named_node_iterator&); |
| | | } |
| | | #endif |
| | | |
| | | #if !defined(PUGIXML_NO_STL) && defined(__SUNPRO_CC) |
| | | namespace std |
| | | { |
| | | // Workarounds for (non-standard) iterator category detection |
| | | std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_node_iterator&); |
| | | std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_attribute_iterator&); |
| | | std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_named_node_iterator&); |
| | | } |
| | | #endif |
| | | |
| | | #endif |
| | | |
| | | // Make sure implementation is included in header-only mode |
| | | // Use macro expansion in #include to work around QMake (QTBUG-11923) |
| | | #if defined(PUGIXML_HEADER_ONLY) && !defined(PUGIXML_SOURCE) |
| | | # define PUGIXML_SOURCE "pugixml.cpp" |
| | | # include PUGIXML_SOURCE |
| | | #endif |
| | | |
| | | /** |
| | | * Copyright (c) 2006-2023 Arseny Kapoulkine |
| | | * |
| | | * Permission is hereby granted, free of charge, to any person |
| | | * obtaining a copy of this software and associated documentation |
| | | * files (the "Software"), to deal in the Software without |
| | | * restriction, including without limitation the rights to use, |
| | | * copy, modify, merge, publish, distribute, sublicense, and/or sell |
| | | * copies of the Software, and to permit persons to whom the |
| | | * Software is furnished to do so, subject to the following |
| | | * conditions: |
| | | * |
| | | * The above copyright notice and this permission notice shall be |
| | | * included in all copies or substantial portions of the Software. |
| | | * |
| | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| | | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
| | | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| | | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
| | | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
| | | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| | | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| | | * OTHER DEALINGS IN THE SOFTWARE. |
| | | */ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // InputDialog.cpp: å®ç°æä»¶ |
| | | // |
| | | |
| | | #include "stdafx.h" |
| | | #include "BondEq.h" |
| | | #include "afxdialogex.h" |
| | | #include "InputDialog.h" |
| | | |
| | | |
| | | // CInputDialog å¯¹è¯æ¡ |
| | | |
| | | IMPLEMENT_DYNAMIC(CInputDialog, CDialogEx) |
| | | |
| | | CInputDialog::CInputDialog(const CString& strTitle, const CString& strPrompt, CWnd* pParent /*=nullptr*/) |
| | | : CDialogEx(IDD_DIALOG_INPUT, pParent), m_strTitle(strTitle), m_strPrompt(strPrompt), m_strInput(_T("")) |
| | | { |
| | | |
| | | } |
| | | |
| | | CInputDialog::~CInputDialog() |
| | | { |
| | | } |
| | | |
| | | CString CInputDialog::GetInputText() const |
| | | { |
| | | return m_strInput; |
| | | } |
| | | |
| | | void CInputDialog::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | DDX_Control(pDX, IDC_EDIT_INPUT, m_editInput); |
| | | DDX_Control(pDX, IDC_STATIC_PROMPT, m_staticPrompt); |
| | | } |
| | | |
| | | |
| | | BEGIN_MESSAGE_MAP(CInputDialog, CDialogEx) |
| | | ON_BN_CLICKED(IDOK, &CInputDialog::OnBnClickedOk) |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | | // CInputDialog æ¶æ¯å¤çç¨åº |
| | | |
| | | |
| | | BOOL CInputDialog::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | |
| | | // TODO: 卿¤æ·»å é¢å¤çåå§å |
| | | SetWindowText(m_strTitle); |
| | | m_staticPrompt.SetWindowText(m_strPrompt); |
| | | |
| | | return TRUE; // return TRUE unless you set the focus to a control |
| | | // å¼å¸¸: OCX 屿§é¡µåºè¿å FALSE |
| | | } |
| | | |
| | | |
| | | void CInputDialog::OnBnClickedOk() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | m_editInput.GetWindowText(m_strInput); |
| | | if (m_strInput.IsEmpty()) { |
| | | AfxMessageBox(_T("è¾å
¥ä¸è½ä¸ºç©ºï¼")); |
| | | return; |
| | | } |
| | | |
| | | CDialogEx::OnOK(); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include "afxdialogex.h" |
| | | |
| | | |
| | | // CInputDialog å¯¹è¯æ¡ |
| | | |
| | | class CInputDialog : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CInputDialog) |
| | | |
| | | public: |
| | | CInputDialog(const CString& strTitle, const CString& strPrompt, CWnd* pParent = nullptr); |
| | | virtual ~CInputDialog(); |
| | | |
| | | CString GetInputText() const; // è·åè¾å
¥å
容 |
| | | |
| | | // å¯¹è¯æ¡æ°æ® |
| | | #ifdef AFX_DESIGN_TIME |
| | | enum { IDD = IDD_DIALOG_INPUT }; |
| | | #endif |
| | | |
| | | private: |
| | | CEdit m_editInput; |
| | | CStatic m_staticPrompt; |
| | | |
| | | CString m_strTitle; // å¯¹è¯æ¡æ é¢ |
| | | CString m_strPrompt; // æç¤ºææ¬ |
| | | CString m_strInput; // è¾å
¥çææ¬ |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV æ¯æ |
| | | |
| | | DECLARE_MESSAGE_MAP() |
| | | public: |
| | | virtual BOOL OnInitDialog(); |
| | | afx_msg void OnBnClickedOk(); |
| | | }; |
| | |
| | | |
| | | void CToolUnits::createDir(const char* pszDir) |
| | | { |
| | | if (isDirectory(std::string(pszDir))) { |
| | | return; |
| | | } |
| | | |
| | | CString strDir = pszDir; |
| | | int lastIndex = 0; |
| | | int index = strDir.Find(_T("\\"), lastIndex); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // AxisSettingsDlg.cpp: å®ç°æä»¶ |
| | | // |
| | | |
| | | #include "stdafx.h" |
| | | #include "BondEq.h" |
| | | #include "afxdialogex.h" |
| | | #include "AxisSettingsDlg.h" |
| | | #include "ToolUnits.h" |
| | | #include <cctype> |
| | | #include <algorithm> |
| | | |
| | | #define TIMER_INIT 1 |
| | | #define TIMER_READ_PLC_DATA 2 |
| | | #define TIMER_JOG_ADD 3 |
| | | #define TIMER_JOG_SUB 4 |
| | | |
| | | // CAxisSettingsDlg å¯¹è¯æ¡ |
| | | |
| | | IMPLEMENT_DYNAMIC(CAxisSettingsDlg, CDialogEx) |
| | | |
| | | CAxisSettingsDlg::CAxisSettingsDlg(CWnd* pParent /*=nullptr*/) |
| | | : CDialogEx(IDD_DIALOG_AXIS_SETTINGS, pParent) |
| | | { |
| | | m_nInitialWidth = 0; |
| | | m_nInitialHeight = 0; |
| | | m_pPLC = nullptr; |
| | | } |
| | | |
| | | CAxisSettingsDlg::~CAxisSettingsDlg() |
| | | { |
| | | for (auto& pair : m_mapFonts) { |
| | | if (pair.second) { |
| | | pair.second->DeleteObject(); |
| | | delete pair.second; |
| | | } |
| | | } |
| | | m_mapFonts.clear(); |
| | | } |
| | | |
| | | void CAxisSettingsDlg::SetPLC(CPLC* pPLC) |
| | | { |
| | | ASSERT(pPLC); |
| | | m_pPLC = pPLC; |
| | | } |
| | | |
| | | void CAxisSettingsDlg::SetRecipeName(const CString& strRecipeName) |
| | | { |
| | | m_strRecipeName = strRecipeName; |
| | | } |
| | | |
| | | void CAxisSettingsDlg::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | DDX_Control(pDX, IDC_STATIC_AXIS_TEST_FLS, m_staticFLS); |
| | | DDX_Control(pDX, IDC_STATIC_AXIS_TEST_DOG, m_staticDOG); |
| | | DDX_Control(pDX, IDC_STATIC_AXIS_TEST_RLS, m_staticRLS); |
| | | DDX_Control(pDX, IDC_STATIC_AXIS_TEST_READY, m_staticReady); |
| | | DDX_Control(pDX, IDC_STATIC_AXIS_TEST_BUSY, m_staticBusy); |
| | | DDX_Control(pDX, IDC_STATIC_AXIS_TEST_ERR, m_staticErr); |
| | | DDX_Control(pDX, IDC_COMBO_AXIS_NAME, m_comboAxisNO); |
| | | DDX_Control(pDX, IDC_STATIC_AXIS_NUMBER, m_staticAxisNO); |
| | | DDX_Control(pDX, IDC_STATIC_AXIS_DESCRIP, m_staticAxisDescription); |
| | | DDX_Control(pDX, IDC_STATIC_START_ADDRESS, m_staticStartAddress); |
| | | DDX_Control(pDX, IDC_EDIT_AXIS_MODITFY_POS, m_editManualSpeed); |
| | | DDX_Control(pDX, IDC_EDIT_AXIS_MODITFY_AUTO_SPEED, m_editAutoSpeed); |
| | | DDX_Control(pDX, IDC_EDIT_AXIS_MODITFY_ACCE_TIME, m_editAccelerationTime); |
| | | DDX_Control(pDX, IDC_EDIT_AXIS_MODITFY_DECE_TIME, m_editDecelerationTime); |
| | | DDX_Control(pDX, IDC_EDIT_AXIS_MODITFY_MICROMENTUM, m_editJogDistance); |
| | | DDX_Control(pDX, IDC_BUTTON_AXIS_ANCHOR_POINT_GROUP1, m_pageButtons[0]); |
| | | DDX_Control(pDX, IDC_BUTTON_AXIS_ANCHOR_POINT_GROUP2, m_pageButtons[1]); |
| | | DDX_Control(pDX, IDC_BUTTON_AXIS_ANCHOR_POINT_GROUP3, m_pageButtons[2]); |
| | | DDX_Control(pDX, IDC_BUTTON_AXIS_ANCHOR_POINT_GROUP4, m_pageButtons[3]); |
| | | DDX_Control(pDX, IDC_BUTTON_AXIS_ANCHOR_POINT_GROUP5, m_pageButtons[4]); |
| | | } |
| | | |
| | | UINT CAxisSettingsDlg::FindIDByName(const CString& strControlID) |
| | | { |
| | | // å°èµæºæä»¶ä¸å®ä¹çæ§ä»¶åç§°å ID å è½½å°ä¸ä¸ªæ å°ä¸ |
| | | static const std::map<CString, UINT> controlIdMap = { |
| | | {"IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP1", IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP1}, |
| | | {"IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP2", IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP2}, |
| | | {"IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP3", IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP3}, |
| | | {"IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP4", IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP4}, |
| | | {"IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP5", IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP5}, |
| | | {"IDC_EDIT_AXIS_ANCHOR_POINT1", IDC_EDIT_AXIS_ANCHOR_POINT1}, |
| | | {"IDC_EDIT_AXIS_ANCHOR_POINT2", IDC_EDIT_AXIS_ANCHOR_POINT2}, |
| | | {"IDC_EDIT_AXIS_ANCHOR_POINT3", IDC_EDIT_AXIS_ANCHOR_POINT3}, |
| | | {"IDC_EDIT_AXIS_ANCHOR_POINT4", IDC_EDIT_AXIS_ANCHOR_POINT4}, |
| | | {"IDC_EDIT_AXIS_ANCHOR_POINT5", IDC_EDIT_AXIS_ANCHOR_POINT5} |
| | | // å¯ä»¥ç»§ç»æ·»å å
¶ä»æ§ä»¶åç§°å ID |
| | | }; |
| | | |
| | | // æ¥æ¾æ§ä»¶åç§°æ¯å¦å¨æ å°ä¸ |
| | | auto it = controlIdMap.find(strControlID); |
| | | if (it != controlIdMap.end()) { |
| | | return it->second; |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | CFont* CAxisSettingsDlg::GetOrCreateFont(int nFontSize) |
| | | { |
| | | auto it = m_mapFonts.find(nFontSize); |
| | | if (it != m_mapFonts.end()) { |
| | | return it->second; |
| | | } |
| | | |
| | | CFont* font = new CFont(); |
| | | LOGFONT logFont = { 0 }; |
| | | _tcscpy_s(logFont.lfFaceName, _T("Segoe UI")); |
| | | logFont.lfHeight = -nFontSize; |
| | | logFont.lfQuality = CLEARTYPE_QUALITY; |
| | | font->CreateFontIndirect(&logFont); |
| | | m_mapFonts[nFontSize] = font; |
| | | |
| | | return font; |
| | | } |
| | | |
| | | void CAxisSettingsDlg::SetDefaultFont() |
| | | { |
| | | CFont* defaultFont = GetOrCreateFont(12); |
| | | |
| | | // éåæææ§ä»¶ï¼åºç¨é»è®¤åä½ |
| | | CWnd* pWnd = GetWindow(GW_CHILD); |
| | | while (pWnd) { |
| | | pWnd->SetFont(defaultFont, TRUE); |
| | | pWnd = pWnd->GetNextWindow(); |
| | | } |
| | | } |
| | | |
| | | void CAxisSettingsDlg::AdjustControls(float dScaleX, float dScaleY) |
| | | { |
| | | CWnd* pWnd = GetWindow(GW_CHILD); |
| | | while (pWnd) { |
| | | int nCtrlID = pWnd->GetDlgCtrlID(); |
| | | if (nCtrlID != -1 && m_mapCtrlLayouts.find(nCtrlID) != m_mapCtrlLayouts.end()) |
| | | { |
| | | CRect originalRect = m_mapCtrlLayouts[nCtrlID]; |
| | | CRect newRect( |
| | | static_cast<int>(originalRect.left * dScaleX), |
| | | static_cast<int>(originalRect.top * dScaleY), |
| | | static_cast<int>(originalRect.right * dScaleX), |
| | | static_cast<int>(originalRect.bottom * dScaleY)); |
| | | |
| | | TCHAR szClassName[256]; |
| | | GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName)); |
| | | |
| | | if (_tcsicmp(szClassName, _T("ComboBox")) == 0) { |
| | | CComboBox* pComboBox = (CComboBox*)pWnd; |
| | | pComboBox->SetItemHeight(-1, newRect.Height()); // -1 表示ææé¡¹çé«åº¦ |
| | | } |
| | | |
| | | pWnd->MoveWindow(&newRect); |
| | | AdjustControlFont(pWnd, newRect.Width(), newRect.Height()); |
| | | } |
| | | pWnd = pWnd->GetNextWindow(); |
| | | } |
| | | } |
| | | |
| | | void CAxisSettingsDlg::AdjustControlFont(CWnd* pWnd, int nWidth, int nHeight) |
| | | { |
| | | // æ ¹æ®æ§ä»¶é«åº¦å¨æè°æ´åä½å¤§å° |
| | | int fontSize = nHeight / 2; |
| | | if (fontSize < 8) fontSize = 8; |
| | | if (fontSize > 24) fontSize = 24; // æå¤§åä½å¤§å° |
| | | |
| | | // è·åæå建åä½ |
| | | CFont* pFont = GetOrCreateFont(fontSize); |
| | | |
| | | pWnd->SetFont(pFont); |
| | | pWnd->Invalidate(); // å·æ°æ§ä»¶æ¾ç¤º |
| | | } |
| | | |
| | | void CAxisSettingsDlg::AdjustLabelFont(CBLLabel& label) |
| | | { |
| | | // è·åæ§ä»¶çç©å½¢åºå |
| | | CRect rect; |
| | | label.GetClientRect(&rect); |
| | | |
| | | // å¨æè®¡ç®åä½å¤§å°ï¼åºäºæ§ä»¶çé«åº¦ |
| | | int fontSize = rect.Height() / 2; // æ§ä»¶é«åº¦çä¸åä½ä¸ºåä½å¤§å° |
| | | if (fontSize < 8) fontSize = 8; // æå°åä½å¤§å° |
| | | if (fontSize > 30) fontSize = 30; // æå¤§åä½å¤§å° |
| | | |
| | | // 设置åä½å¤§å° |
| | | label.SetFontSize(fontSize); |
| | | |
| | | // å·æ°æ§ä»¶æ¾ç¤º |
| | | label.Invalidate(); |
| | | label.UpdateWindow(); |
| | | } |
| | | |
| | | void CAxisSettingsDlg::SetStatusColor(CBLLabel& label, BOOL bStatus) |
| | | { |
| | | if (bStatus) { |
| | | label.SetBkColor(RGB(0, 255, 0)); // ç»¿è² |
| | | } |
| | | else { |
| | | label.SetBkColor(RGB(255, 0, 0)); // çº¢è² |
| | | } |
| | | |
| | | label.Invalidate(); // æ è®°åºåæ æ |
| | | label.UpdateWindow(); // ç«å³å·æ° |
| | | } |
| | | |
| | | void CAxisSettingsDlg::updatePageButtonStates() |
| | | { |
| | | for (int i = 0; i < 5; ++i) { |
| | | if (i + 1 == m_currentPage) { |
| | | m_pageButtons[i].SetFaceColor(RGB(0, 122, 204)); // éä¸èæ¯è²ï¼èè²ï¼ |
| | | } |
| | | else { |
| | | m_pageButtons[i].SetFaceColor(RGB(240, 240, 240)); // é»è®¤èæ¯è² |
| | | } |
| | | |
| | | m_pageButtons[i].Invalidate(); |
| | | } |
| | | } |
| | | |
| | | int CAxisSettingsDlg::getCurrentSelectedAxisID() |
| | | { |
| | | int currentIndex = m_comboAxisNO.GetCurSel(); |
| | | if (currentIndex == CB_ERR) { |
| | | return -1; |
| | | } |
| | | |
| | | CString strAxisIDStr; |
| | | m_comboAxisNO.GetLBText(currentIndex, strAxisIDStr); |
| | | return _ttoi(strAxisIDStr); |
| | | } |
| | | |
| | | void CAxisSettingsDlg::initializeAxisIDCombo() |
| | | { |
| | | // æ£æ¥é
æ¹æ¯å¦å è½½æå |
| | | RecipeManager& recipeManager = RecipeManager::getInstance(); |
| | | if (m_strRecipeName.IsEmpty() || !recipeManager.loadRecipe(std::string(CT2A(m_strRecipeName)))) { |
| | | AfxMessageBox(_T("å è½½é
æ¹å¤±è´¥ï¼")); |
| | | return; |
| | | } |
| | | |
| | | // è·åææè½´çç¼å· |
| | | auto axisNumbers = recipeManager.getAllAxisID(); |
| | | |
| | | // æ¸
ç©ºä¸ææ¡ |
| | | m_comboAxisNO.ResetContent(); |
| | | |
| | | // å¡«å
æ°æ®å°ä¸ææ¡ |
| | | for (const auto& axisID : axisNumbers) { |
| | | CString axisCString; |
| | | axisCString.Format(_T("%d"), axisID); |
| | | m_comboAxisNO.AddString(axisCString); |
| | | } |
| | | |
| | | // é»è®¤éæ©ç¬¬ä¸é¡¹ |
| | | if (m_comboAxisNO.GetCount() > 0) { |
| | | m_comboAxisNO.SetCurSel(0); |
| | | } |
| | | } |
| | | |
| | | void CAxisSettingsDlg::refreshAxisDetails(int nAxisId) |
| | | { |
| | | // è·åè½´æ°æ® |
| | | RecipeManager& recipeManager = RecipeManager::getInstance(); |
| | | auto axisDetails = recipeManager.getAxis(nAxisId); |
| | | |
| | | auto formatDouble = [](double value) -> CString { |
| | | CString str; |
| | | str.Format(_T("%.3f"), value); |
| | | return str; |
| | | }; |
| | | |
| | | // æ´æ°æ§ä»¶æ¾ç¤º |
| | | m_staticAxisNO.SetWindowText(CString(axisDetails.number.c_str())); // è½´ç¼å· |
| | | m_staticAxisDescription.SetWindowText(CString(axisDetails.description.c_str())); // è½´æè¿° |
| | | m_staticStartAddress.SetWindowText(CString(axisDetails.startAddress.c_str())); // èµ·å§å°å |
| | | m_editJogDistance.SetWindowText(formatDouble(axisDetails.jogDistance)); // å¾®å¨é |
| | | m_editManualSpeed.SetWindowText(formatDouble(axisDetails.manualSpeed)); // æå¨é度 |
| | | m_editAutoSpeed.SetWindowText(formatDouble(axisDetails.autoSpeed)); // èªå¨é度 |
| | | m_editAccelerationTime.SetWindowText(formatDouble(axisDetails.accelerationTime)); // å éæ¶é´ |
| | | m_editDecelerationTime.SetWindowText(formatDouble(axisDetails.decelerationTime)); // åéæ¶é´ |
| | | } |
| | | |
| | | void CAxisSettingsDlg::refreshPositionDetails(int nAxisId, int pageNumber) |
| | | { |
| | | RecipeManager& recipeManager = RecipeManager::getInstance(); |
| | | // æ¯é¡µæ¾ç¤ºçå®ä½ç¹æ°é |
| | | const int pageSize = 5; |
| | | |
| | | // è·åå®ä½ç¹æ°æ® |
| | | auto positions = recipeManager.getPositions(nAxisId, pageNumber, pageSize); |
| | | |
| | | // å·æ° UI |
| | | for (int i = 0; i < pageSize; ++i) { |
| | | CString descriptionCtrlName, positionCtrlName; |
| | | descriptionCtrlName.Format(_T("IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP%d"), i + 1); |
| | | positionCtrlName.Format(_T("IDC_EDIT_AXIS_ANCHOR_POINT%d"), i + 1); |
| | | |
| | | UINT descriptionCtrlId = FindIDByName(descriptionCtrlName); |
| | | UINT positionCtrlId = FindIDByName(positionCtrlName); |
| | | |
| | | CWnd* pDescriptionCtrl = GetDlgItem(descriptionCtrlId); |
| | | CWnd* pPositionCtrl = GetDlgItem(positionCtrlId); |
| | | |
| | | if (i < positions.size()) { |
| | | CString description = CString(positions[i].first.c_str()); |
| | | CString value; |
| | | value.Format(_T("%.3f"), positions[i].second); |
| | | |
| | | if (pDescriptionCtrl) pDescriptionCtrl->SetWindowText(description); |
| | | if (pPositionCtrl) pPositionCtrl->SetWindowText(value); |
| | | } |
| | | else { |
| | | if (pDescriptionCtrl) pDescriptionCtrl->SetWindowText(_T("")); |
| | | if (pPositionCtrl) pPositionCtrl->SetWindowText(_T("")); |
| | | } |
| | | } |
| | | } |
| | | |
| | | void CAxisSettingsDlg::updateAxisSelection(int offset) |
| | | { |
| | | int currentIndex = m_comboAxisNO.GetCurSel(); |
| | | if (currentIndex == CB_ERR) { |
| | | AfxMessageBox(_T("è¯·éæ©ä¸ä¸ªææçè½´ç¼å·ï¼")); |
| | | return; |
| | | } |
| | | |
| | | int newIndex = currentIndex + offset; |
| | | if (newIndex < 0 || newIndex >= m_comboAxisNO.GetCount()) { |
| | | CString error; |
| | | error.Format(_T("å·²ç»å°è¾¾%sä¸ä¸ªè½´ï¼"), offset < 0 ? _T("ä¸") : _T("ä¸")); |
| | | AfxMessageBox(error); |
| | | return; |
| | | } |
| | | |
| | | m_comboAxisNO.SetCurSel(newIndex); |
| | | refreshAxisDetails(newIndex + 1); |
| | | refreshPositionDetails(newIndex + 1, m_currentPage); |
| | | updatePageButtonStates(); |
| | | } |
| | | |
| | | void CAxisSettingsDlg::updateDataFromUI(int nAxisId) |
| | | { |
| | | const int pageSize = 5; // æ¯é¡µæ¾ç¤º 5 个å®ä½ç¹ |
| | | |
| | | RecipeManager& recipeManager = RecipeManager::getInstance(); |
| | | auto axisData = recipeManager.getAxis(nAxisId); |
| | | |
| | | // è·åçé¢ä¸çä¿®æ¹åæ° |
| | | CString text; |
| | | m_editManualSpeed.GetWindowText(text); |
| | | axisData.manualSpeed = _ttof(text); |
| | | |
| | | m_editAutoSpeed.GetWindowText(text); |
| | | axisData.autoSpeed = _ttof(text); |
| | | |
| | | m_editAccelerationTime.GetWindowText(text); |
| | | axisData.accelerationTime = _ttof(text); |
| | | |
| | | m_editDecelerationTime.GetWindowText(text); |
| | | axisData.decelerationTime = _ttof(text); |
| | | |
| | | m_editJogDistance.GetWindowText(text); |
| | | axisData.jogDistance = _ttof(text); |
| | | |
| | | // æ´æ°å®ä½ç¹æ°æ® |
| | | for (int i = 0; i < pageSize; ++i) { |
| | | int index = (m_currentPage - 1) * pageSize + i; |
| | | |
| | | if (index < axisData.positions.size()) { |
| | | CString descriptionName, positionName; |
| | | descriptionName.Format(_T("IDC_EDIT_AXIS_ANCHOR_POINT_DESCRIP%d"), i + 1); |
| | | positionName.Format(_T("IDC_EDIT_AXIS_ANCHOR_POINT%d"), i + 1); |
| | | |
| | | CEdit* pDescriptionEdit = (CEdit*)GetDlgItem(FindIDByName(descriptionName)); |
| | | CEdit* pPositionEdit = (CEdit*)GetDlgItem(FindIDByName(positionName)); |
| | | |
| | | if (pDescriptionEdit && pPositionEdit) { |
| | | CString description, positionValue; |
| | | pDescriptionEdit->GetWindowText(description); |
| | | pPositionEdit->GetWindowText(positionValue); |
| | | |
| | | // æ´æ° RecipeManager ä¸çæ°æ® |
| | | axisData.positions[index].first = CT2A(description); |
| | | axisData.positions[index].second = _ttof(positionValue); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // ä¿åå RecipeManager |
| | | recipeManager.updateAxis(axisData); |
| | | } |
| | | |
| | | void CAxisSettingsDlg::switchToPage(int targetPage) |
| | | { |
| | | try { |
| | | // 妿å½å页é¢å·²ç»æ¯ç®æ 页é¢ï¼ç´æ¥è¿å |
| | | if (m_currentPage == targetPage) { |
| | | return; |
| | | } |
| | | |
| | | // è·åå½åéä¸çè½´ ID |
| | | int axisId = getCurrentSelectedAxisID(); |
| | | if (axisId == -1) { |
| | | AfxMessageBox(_T("è¯·éæ©ä¸ä¸ªææçè½´ç¼å·ï¼")); |
| | | return; |
| | | } |
| | | |
| | | // æ´æ° UI æ°æ®å°å
å |
| | | updateDataFromUI(axisId); |
| | | |
| | | // åæ¢é¡µé¢ |
| | | m_currentPage = targetPage; |
| | | refreshPositionDetails(axisId, targetPage); |
| | | updatePageButtonStates(); |
| | | } |
| | | catch (const std::exception& ex) { |
| | | CString errorMsg; |
| | | errorMsg.Format(_T("å·æ°å®ä½ç»%d失败ï¼%s"), targetPage, CString(ex.what())); |
| | | AfxMessageBox(errorMsg, MB_ICONERROR); |
| | | } |
| | | } |
| | | |
| | | void CAxisSettingsDlg::writeAxisDataToPLC(int nAxisId) |
| | | { |
| | | // ä» RecipeManager è·åè½´æ°æ® |
| | | RecipeManager& recipeManager = RecipeManager::getInstance(); |
| | | auto axisData = recipeManager.getAxis(nAxisId); |
| | | |
| | | // å»é¤éæ°åå符并转æ¢èµ·å§å°å |
| | | std::string cleanAddress = axisData.startAddress; |
| | | cleanAddress.erase(std::remove_if(cleanAddress.begin(), cleanAddress.end(), |
| | | [](char c) { return !std::isdigit(c); }), cleanAddress.end()); |
| | | if (cleanAddress.empty()) { |
| | | AfxMessageBox(_T("æ æçèµ·å§å°åï¼")); |
| | | return; |
| | | } |
| | | int startAddress = std::stoi(cleanAddress); |
| | | |
| | | // åå
¥æå¨é度 |
| | | m_pPLC->writeWord(MC::SOFT_COMPONENT::D, 5120, (int)axisData.manualSpeed, [](IMcChannel* pChannel, int addr, DWORD value, int flag) { |
| | | if (flag == 0) { |
| | | TRACE("\nåå
¥æå: æå¨é度, å°å: %d, å¼: %lu\n", addr, value); |
| | | } |
| | | else { |
| | | TRACE("\nåå
¥å¤±è´¥: æå¨é度, å°å: %d, é误ç : %d\n", addr, flag); |
| | | } |
| | | }); |
| | | |
| | | // åå
¥èªå¨é度 |
| | | m_pPLC->writeWord(MC::SOFT_COMPONENT::D, startAddress + 2, (int)axisData.autoSpeed, [](IMcChannel* pChannel, int addr, DWORD value, int flag) { |
| | | if (flag == 0) { |
| | | TRACE("\nåå
¥æå: èªå¨é度, å°å: %d, å¼: %lu\n", addr, value); |
| | | } |
| | | else { |
| | | TRACE("\nåå
¥å¤±è´¥: èªå¨é度, å°å: %d, é误ç : %d\n", addr, flag); |
| | | } |
| | | }); |
| | | |
| | | // åå
¥å éæ¶é´, 转æ¢ä¸ºæ¯«ç§ |
| | | m_pPLC->writeWord(MC::SOFT_COMPONENT::D, startAddress + 4, (int)(axisData.accelerationTime * 1000), [](IMcChannel* pChannel, int addr, DWORD value, int flag) { |
| | | if (flag == 0) { |
| | | TRACE("\nåå
¥æå: å éæ¶é´, å°å: %d, å¼: %lu\n", addr, value); |
| | | } |
| | | else { |
| | | TRACE("\nåå
¥å¤±è´¥: å éæ¶é´, å°å: %d, é误ç : %d\n", addr, flag); |
| | | } |
| | | }); |
| | | |
| | | // åå
¥åéæ¶é´, 转æ¢ä¸ºæ¯«ç§ |
| | | m_pPLC->writeWord(MC::SOFT_COMPONENT::D, startAddress + 6, (int)(axisData.decelerationTime * 1000), [](IMcChannel* pChannel, int addr, DWORD value, int flag) { |
| | | if (flag == 0) { |
| | | TRACE("\nåå
¥æå: åéæ¶é´, å°å: %d, å¼: %lu\n", addr, value); |
| | | } |
| | | else { |
| | | TRACE("\nåå
¥å¤±è´¥: åéæ¶é´, å°å: %d, é误ç : %d\n", addr, flag); |
| | | } |
| | | }); |
| | | |
| | | // åå
¥å¾®å¨é |
| | | m_pPLC->writeWord(MC::SOFT_COMPONENT::D, startAddress + 8, (int)axisData.jogDistance, [](IMcChannel* pChannel, int addr, DWORD value, int flag) { |
| | | if (flag == 0) { |
| | | TRACE("\nåå
¥æå: å¾®å¨é, å°å: %d, å¼: %lu\n", addr, value); |
| | | } |
| | | else { |
| | | TRACE("\nåå
¥å¤±è´¥: å¾®å¨é, å°å: %d, é误ç : %d\n", addr, flag); |
| | | } |
| | | }); |
| | | |
| | | // åå
¥å®ä½ç¹æ°æ® |
| | | int positionStartAddress = startAddress + 10; |
| | | for (size_t i = 0; i < axisData.positions.size(); ++i) { |
| | | const auto& position = axisData.positions[i]; |
| | | int positionAddress = positionStartAddress + (i * 2); |
| | | |
| | | m_pPLC->writeWord(MC::SOFT_COMPONENT::D, positionAddress, (int)position.second, [i](IMcChannel* pChannel, int addr, DWORD value, int flag) { |
| | | if (flag == 0) { |
| | | TRACE("\nåå
¥æå: å®ä½ç¹ %d, å°å: %d, å¼: %lu\n", i + 1, addr, value); |
| | | } |
| | | else { |
| | | TRACE("\nåå
¥å¤±è´¥: å®ä½ç¹ %d, å°å: %d, é误ç : %d\n", i + 1, addr, flag); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | |
| | | void CAxisSettingsDlg::handleAxisOperation(AxisOperationType eOpType, bool bPressed) |
| | | { |
| | | int nAxisId = getCurrentSelectedAxisID(); |
| | | if (nAxisId == -1) { |
| | | AfxMessageBox(_T("æªéæ©ææçè½´ç¼å·ï¼")); |
| | | return; |
| | | } |
| | | |
| | | // è·åè½´æ°æ® |
| | | RecipeManager& recipeManager = RecipeManager::getInstance(); |
| | | auto axisData = recipeManager.getAxis(nAxisId); |
| | | |
| | | std::string strCleanAddress = axisData.startAddress; |
| | | strCleanAddress.erase(std::remove_if(strCleanAddress.begin(), strCleanAddress.end(), |
| | | [](unsigned char c) { return !std::isdigit(c); }), strCleanAddress.end()); |
| | | if (strCleanAddress.empty()) { |
| | | AfxMessageBox(_T("æ æçèµ·å§å°åï¼")); |
| | | return; |
| | | } |
| | | |
| | | int nStartAddress = std::stoi(strCleanAddress); |
| | | |
| | | // æ ¹æ®æä½ç±»å计ç®ç®æ å°å |
| | | int nTargetAddress = nStartAddress; |
| | | switch (eOpType) { |
| | | case AxisOperationType::OPR: |
| | | nTargetAddress += 10; // OPR ä¿¡å·å°å |
| | | break; |
| | | case AxisOperationType::JOG_ADD: |
| | | nTargetAddress += 12; // JOG+ ä¿¡å·å°å |
| | | break; |
| | | case AxisOperationType::JOG_SUB: |
| | | nTargetAddress += 13; // JOG- ä¿¡å·å°å |
| | | break; |
| | | case AxisOperationType::STOP: |
| | | nTargetAddress += 14; // STOP ä¿¡å·å°å |
| | | break; |
| | | case AxisOperationType::POSITION_1: |
| | | nTargetAddress += 16; // å®ä½ç¹ 1 ä¿¡å·å°å |
| | | break; |
| | | case AxisOperationType::POSITION_2: |
| | | nTargetAddress += 18; // å®ä½ç¹ 2 ä¿¡å·å°å |
| | | break; |
| | | case AxisOperationType::POSITION_3: |
| | | nTargetAddress += 20; // å®ä½ç¹ 3 ä¿¡å·å°å |
| | | break; |
| | | case AxisOperationType::POSITION_4: |
| | | nTargetAddress += 22; // å®ä½ç¹ 4 ä¿¡å·å°å |
| | | break; |
| | | case AxisOperationType::POSITION_5: |
| | | nTargetAddress += 24; // å®ä½ç¹ 5 ä¿¡å·å°å |
| | | break; |
| | | default: |
| | | AfxMessageBox(_T("æªç¥æä½ç±»åï¼")); |
| | | return; |
| | | } |
| | | |
| | | // å PLC åå
¥ä¿¡å· |
| | | m_pPLC->writeBit(MC::SOFT_COMPONENT::D, nTargetAddress, bPressed, [eOpType, nTargetAddress, bPressed](IMcChannel* pChannel, int nAddr, DWORD nValue, int nFlag) { |
| | | if (nFlag == 0) { |
| | | TRACE("æä½æåï¼ç±»å=%dï¼å°å=%dï¼å¼=%d\n", static_cast<int>(eOpType), nAddr, bPressed); |
| | | } |
| | | else { |
| | | TRACE("æä½å¤±è´¥ï¼ç±»å=%dï¼å°å=%dï¼é误ç =%d\n", static_cast<int>(eOpType), nAddr, nFlag); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | |
| | | BEGIN_MESSAGE_MAP(CAxisSettingsDlg, CDialogEx) |
| | | ON_BN_CLICKED(IDC_BUTTON_AXIS_LAST, &CAxisSettingsDlg::OnBnClickedButtonAxisLast) |
| | | ON_BN_CLICKED(IDC_BUTTON_AXIS_NEXT, &CAxisSettingsDlg::OnBnClickedButtonAxisNext) |
| | | ON_BN_CLICKED(IDC_BUTTON_AXIS_ANCHOR_POINT_GROUP1, &CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPointGroup1) |
| | | ON_BN_CLICKED(IDC_BUTTON_AXIS_ANCHOR_POINT_GROUP2, &CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPointGroup2) |
| | | ON_BN_CLICKED(IDC_BUTTON_AXIS_ANCHOR_POINT_GROUP3, &CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPointGroup3) |
| | | ON_BN_CLICKED(IDC_BUTTON_AXIS_ANCHOR_POINT_GROUP4, &CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPointGroup4) |
| | | ON_BN_CLICKED(IDC_BUTTON_AXIS_ANCHOR_POINT_GROUP5, &CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPointGroup5) |
| | | ON_BN_CLICKED(IDC_BUTTON_AXIS_ANCHOR_POINT1, &CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPoint1) |
| | | ON_BN_CLICKED(IDC_BUTTON_AXIS_ANCHOR_POINT2, &CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPoint2) |
| | | ON_BN_CLICKED(IDC_BUTTON_AXIS_ANCHOR_POINT3, &CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPoint3) |
| | | ON_BN_CLICKED(IDC_BUTTON_AXIS_ANCHOR_POINT4, &CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPoint4) |
| | | ON_BN_CLICKED(IDC_BUTTON_AXIS_ANCHOR_POINT5, &CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPoint5) |
| | | ON_BN_CLICKED(IDC_BUTTON_AXIS_TEST_OPR, &CAxisSettingsDlg::OnBnClickedButtonAxisTestOpr) |
| | | ON_BN_CLICKED(IDC_BUTTON_AXIS_TEST_STOP, &CAxisSettingsDlg::OnBnClickedButtonAxisTestStop) |
| | | ON_CBN_SELCHANGE(IDC_COMBO_AXIS_NAME, &CAxisSettingsDlg::OnSelchangeComboAxisName) |
| | | ON_BN_CLICKED(IDC_BUTTON_AXIS_SAVE, &CAxisSettingsDlg::OnBnClickedButtonAxisSave) |
| | | ON_WM_SIZE() |
| | | ON_WM_CTLCOLOR() |
| | | ON_WM_SIZING() |
| | | ON_WM_TIMER() |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | | // CAxisSettingsDlg æ¶æ¯å¤çç¨åº |
| | | |
| | | |
| | | BOOL CAxisSettingsDlg::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | |
| | | // TODO: 卿¤æ·»å é¢å¤çåå§å |
| | | CString strTitle; |
| | | strTitle.Format(_T("Axis设å®(é
æ¹: %s)"), m_strRecipeName); |
| | | SetWindowText(strTitle); |
| | | |
| | | // 设置æµè¯ç¶æ |
| | | CBLLabel* pLabels[] = { &m_staticFLS, &m_staticDOG, &m_staticRLS, &m_staticReady, &m_staticBusy, &m_staticErr }; |
| | | for (auto pLabel : pLabels) { |
| | | SetStatusColor(*pLabel, FALSE); |
| | | pLabel->ModifyStyle(0, SS_NOTIFY); |
| | | pLabel->SetTextColor(RGB(255, 255, 255)); |
| | | pLabel->SetAlignment(AlignCenter); |
| | | pLabel->SetDynamicFont(TRUE); |
| | | } |
| | | |
| | | // åå§åå½å页é¢ä¸ºç¬¬ä¸é¡µ |
| | | m_currentPage = 1; |
| | | updatePageButtonStates(); |
| | | |
| | | initializeAxisIDCombo(); |
| | | refreshAxisDetails(1); |
| | | refreshPositionDetails(1, m_currentPage); |
| | | |
| | | CRect screenRect, dlgRect, clientRect; |
| | | GetClientRect(&clientRect); |
| | | m_nInitialWidth = clientRect.Width(); |
| | | m_nInitialHeight = clientRect.Height(); |
| | | |
| | | // åå§åé»è®¤åä½ |
| | | CFont* pDefaultFont = GetOrCreateFont(12); |
| | | |
| | | // éåææåæ§ä»¶ï¼è®°å½åå§ä½ç½®å¹¶è®¾ç½®é»è®¤åä½ |
| | | CWnd* pWnd = GetWindow(GW_CHILD); |
| | | while (pWnd) { |
| | | int nCtrlID = pWnd->GetDlgCtrlID(); |
| | | if (nCtrlID != -1) { |
| | | // è®°å½æ§ä»¶åå§å¸å± |
| | | CRect ctrlRect; |
| | | pWnd->GetWindowRect(&ctrlRect); |
| | | ScreenToClient(&ctrlRect); |
| | | m_mapCtrlLayouts[nCtrlID] = ctrlRect; |
| | | |
| | | // 设置é»è®¤åä½ |
| | | pWnd->SetFont(pDefaultFont); |
| | | } |
| | | pWnd = pWnd->GetNextWindow(); |
| | | } |
| | | |
| | | GetWindowRect(&dlgRect); |
| | | int dlgWidth = dlgRect.Width() * 2; |
| | | int dlgHeight = dlgRect.Height() * 2; |
| | | |
| | | SystemParametersInfo(SPI_GETWORKAREA, 0, &screenRect, 0); |
| | | if (dlgWidth > screenRect.Width()) { |
| | | dlgWidth = screenRect.Width(); |
| | | } |
| | | if (dlgHeight > screenRect.Height()) { |
| | | dlgHeight = screenRect.Height(); |
| | | } |
| | | |
| | | int centerX = screenRect.left + (screenRect.Width() - dlgWidth) / 2; |
| | | int centerY = screenRect.top + (screenRect.Height() - dlgHeight) / 2; |
| | | MoveWindow(centerX, centerY, dlgWidth, dlgHeight); |
| | | |
| | | SetTimer(TIMER_READ_PLC_DATA, 500, nullptr); |
| | | |
| | | return TRUE; // return TRUE unless you set the focus to a control |
| | | // å¼å¸¸: OCX 屿§é¡µåºè¿å FALSE |
| | | } |
| | | |
| | | BOOL CAxisSettingsDlg::PreTranslateMessage(MSG* pMsg) |
| | | { |
| | | // TODO: 卿¤æ·»å ä¸ç¨ä»£ç å/æè°ç¨åºç±» |
| | | |
| | | if (pMsg->message == WM_LBUTTONDOWN) |
| | | { |
| | | if (pMsg->hwnd == GetDlgItem(IDC_BUTTON_AXIS_TEST_JOG_ADD)->m_hWnd) |
| | | { |
| | | TRACE("JOG+ æé®æä¸\n"); |
| | | m_bJogAddPressed = TRUE; |
| | | |
| | | // å¯å¨å®æ¶å¨è¿ç»åéä¿¡å· |
| | | SetTimer(TIMER_JOG_ADD, 200, nullptr); |
| | | handleAxisOperation(AxisOperationType::JOG_ADD, true); |
| | | } |
| | | else if (pMsg->hwnd == GetDlgItem(IDC_BUTTON_AXIS_TEST_JOG_SUB)->m_hWnd) |
| | | { |
| | | TRACE("JOG- æé®æä¸\n"); |
| | | m_bJogSubPressed = TRUE; |
| | | |
| | | // å¯å¨å®æ¶å¨è¿ç»åéä¿¡å· |
| | | SetTimer(TIMER_JOG_SUB, 200, nullptr); |
| | | handleAxisOperation(AxisOperationType::JOG_SUB, true); |
| | | } |
| | | } |
| | | else if (pMsg->message == WM_LBUTTONUP) |
| | | { |
| | | if (pMsg->hwnd == GetDlgItem(IDC_BUTTON_AXIS_TEST_JOG_ADD)->m_hWnd) |
| | | { |
| | | TRACE("JOG+ æé®æ¾å¼\n"); |
| | | m_bJogAddPressed = FALSE; |
| | | |
| | | // 忢宿¶å¨ |
| | | KillTimer(TIMER_JOG_ADD); |
| | | handleAxisOperation(AxisOperationType::JOG_ADD, false); |
| | | } |
| | | else if (pMsg->hwnd == GetDlgItem(IDC_BUTTON_AXIS_TEST_JOG_SUB)->m_hWnd) |
| | | { |
| | | TRACE("JOG- æé®æ¾å¼\n"); |
| | | m_bJogSubPressed = FALSE; |
| | | |
| | | // 忢宿¶å¨ |
| | | KillTimer(TIMER_JOG_SUB); |
| | | handleAxisOperation(AxisOperationType::JOG_SUB, false); |
| | | } |
| | | } |
| | | |
| | | return CDialogEx::PreTranslateMessage(pMsg); |
| | | } |
| | | |
| | | void CAxisSettingsDlg::OnSize(UINT nType, int cx, int cy) |
| | | { |
| | | CDialogEx::OnSize(nType, cx, cy); |
| | | |
| | | // TODO: 卿¤å¤æ·»å æ¶æ¯å¤çç¨åºä»£ç |
| | | if (nType == SIZE_MINIMIZED || m_mapCtrlLayouts.empty()) { |
| | | return; |
| | | } |
| | | |
| | | float dScaleX = static_cast<float>(cx) / m_nInitialWidth; |
| | | float dScaleY = static_cast<float>(cy) / m_nInitialHeight; |
| | | |
| | | // éåå¯¹è¯æ¡ä¸çæææ§ä»¶ |
| | | AdjustControls(dScaleX, dScaleY); |
| | | |
| | | // å¨æè°æ´å个 CBLLabel çåä½å¤§å° |
| | | CBLLabel* pLabels[] = { &m_staticFLS, &m_staticDOG, &m_staticRLS, &m_staticReady, &m_staticBusy, &m_staticErr }; |
| | | for (auto pLabel : pLabels) { |
| | | AdjustLabelFont(*pLabel); |
| | | } |
| | | |
| | | // è°æ´ä¸ææ¡é«åº¦ |
| | | CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_AXIS_NAME); |
| | | CButton* pButtonLeft = (CButton*)GetDlgItem(IDC_BUTTON_AXIS_LAST); |
| | | CButton* pButtonRight = (CButton*)GetDlgItem(IDC_BUTTON_AXIS_NEXT); |
| | | |
| | | if (pComboBox && pButtonLeft && pButtonRight) { |
| | | CRect rectButton; |
| | | pButtonLeft->GetWindowRect(&rectButton); // è·åæé®å°ºå¯¸ |
| | | ScreenToClient(&rectButton); // 转æ¢ä¸ºå®¢æ·ç«¯åæ |
| | | |
| | | CRect rectComboBox; |
| | | pComboBox->GetWindowRect(&rectComboBox); |
| | | ScreenToClient(&rectComboBox); |
| | | |
| | | // è°æ´ä¸ææ¡é«åº¦ |
| | | int heightAdjustment = 2; |
| | | rectComboBox.top = rectButton.top; |
| | | rectComboBox.bottom = rectButton.bottom + heightAdjustment; |
| | | pComboBox->MoveWindow(&rectComboBox); |
| | | pComboBox->SetItemHeight(-1, rectButton.Height() - 6); |
| | | } |
| | | } |
| | | |
| | | void CAxisSettingsDlg::OnSizing(UINT fwSide, LPRECT pRect) |
| | | { |
| | | if (fwSide == WMSZ_BOTTOMRIGHT) { |
| | | if (pRect->right - pRect->left < 200) { |
| | | pRect->right = pRect->left + 200; |
| | | } |
| | | if (pRect->bottom - pRect->top < 150) { |
| | | pRect->bottom = pRect->top + 150; |
| | | } |
| | | } |
| | | |
| | | CDialogEx::OnSizing(fwSide, pRect); |
| | | } |
| | | |
| | | HBRUSH CAxisSettingsDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) |
| | | { |
| | | HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); |
| | | |
| | | // TODO: 卿¤æ´æ¹ DC çä»»ä½ç¹æ§ |
| | | |
| | | // TODO: 妿é»è®¤ç䏿¯æéç»ç¬ï¼åè¿åå¦ä¸ä¸ªç»ç¬ |
| | | return hbr; |
| | | } |
| | | |
| | | void CAxisSettingsDlg::OnBnClickedButtonAxisLast() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | updateAxisSelection(-1); |
| | | } |
| | | |
| | | void CAxisSettingsDlg::OnBnClickedButtonAxisNext() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | updateAxisSelection(1); |
| | | } |
| | | |
| | | void CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPointGroup1() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | switchToPage(1); |
| | | } |
| | | |
| | | void CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPointGroup2() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | switchToPage(2); |
| | | } |
| | | |
| | | void CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPointGroup3() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | switchToPage(3); |
| | | } |
| | | |
| | | void CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPointGroup4() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | switchToPage(4); |
| | | } |
| | | |
| | | void CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPointGroup5() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | switchToPage(5); |
| | | } |
| | | |
| | | void CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPoint1() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | handleAxisOperation(AxisOperationType::POSITION_1, true); |
| | | } |
| | | |
| | | void CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPoint2() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | handleAxisOperation(AxisOperationType::POSITION_2, true); |
| | | } |
| | | |
| | | void CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPoint3() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | handleAxisOperation(AxisOperationType::POSITION_3, true); |
| | | } |
| | | |
| | | void CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPoint4() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | handleAxisOperation(AxisOperationType::POSITION_4, true); |
| | | } |
| | | |
| | | void CAxisSettingsDlg::OnBnClickedButtonAxisAnchorPoint5() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | handleAxisOperation(AxisOperationType::POSITION_5, true); |
| | | } |
| | | |
| | | void CAxisSettingsDlg::OnBnClickedButtonAxisTestOpr() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | handleAxisOperation(AxisOperationType::OPR, true); |
| | | } |
| | | |
| | | void CAxisSettingsDlg::OnBnClickedButtonAxisTestStop() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | handleAxisOperation(AxisOperationType::STOP, true); |
| | | } |
| | | |
| | | void CAxisSettingsDlg::OnSelchangeComboAxisName() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | int axisId = getCurrentSelectedAxisID(); |
| | | if (axisId == -1) { |
| | | AfxMessageBox(_T("è¯·éæ©ä¸ä¸ªææçè½´ç¼å·ï¼")); |
| | | return; |
| | | } |
| | | |
| | | refreshAxisDetails(axisId); |
| | | refreshPositionDetails(axisId, m_currentPage); |
| | | updatePageButtonStates(); |
| | | } |
| | | |
| | | void CAxisSettingsDlg::OnBnClickedButtonAxisSave() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | int axisId = getCurrentSelectedAxisID(); |
| | | if (axisId == -1) { |
| | | AfxMessageBox(_T("è¯·éæ©ä¸ä¸ªææçè½´ç¼å·ï¼")); |
| | | return; |
| | | } |
| | | |
| | | CString cstrMessage; |
| | | cstrMessage.Format(_T("æ¯å¦ä¿åè½´ [%d] åæ°ï¼"), axisId); |
| | | int ret = AfxMessageBox(_T(cstrMessage), MB_OKCANCEL | MB_ICONEXCLAMATION); |
| | | if (ret != IDOK) { |
| | | return; |
| | | } |
| | | |
| | | updateDataFromUI(axisId); |
| | | if (RecipeManager::getInstance().saveRecipe(std::string(CT2A(m_strRecipeName)))) { |
| | | writeAxisDataToPLC(axisId); |
| | | cstrMessage.Format(_T("ä¿åè½´ [%d] åæ°æåï¼"), axisId); |
| | | SystemLogManager::getInstance().log(SystemLogManager::LogType::Operation, std::string(CT2A(cstrMessage))); |
| | | } |
| | | else { |
| | | cstrMessage.Format(_T("ä¿åè½´ [%d] åæ°å¤±è´¥ï¼"), axisId); |
| | | SystemLogManager::getInstance().log(SystemLogManager::LogType::Error, std::string(CT2A(cstrMessage))); |
| | | } |
| | | |
| | | AfxMessageBox(cstrMessage); |
| | | } |
| | | |
| | | void CAxisSettingsDlg::OnTimer(UINT_PTR nIDEvent) |
| | | { |
| | | if (TIMER_READ_PLC_DATA == nIDEvent) { |
| | | ASSERT(m_pPLC); |
| | | |
| | | int addr1, addr2, readSize; |
| | | addr1 = 5120; |
| | | addr2 = 5425; |
| | | readSize = (addr2 - addr1 + 1) * 2; |
| | | auto funOnReadData = [&, addr1, readSize](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) -> void { |
| | | if (nDataSize == readSize && flag == 0) { |
| | | double fCurPos = CToolUnits::toInt32(pData) * 0.001; |
| | | double fManualSpeed = CToolUnits::toInt32(&pData[(5422- addr1)*2]) * 0.001; |
| | | double fAutoSpeed = CToolUnits::toInt32(&pData[(5424 - addr1) * 2]) * 0.001; |
| | | double fPrm = CToolUnits::toInt32(&pData[(5150 - addr1) * 2]) * 0.1; |
| | | int nLoad = CToolUnits::toInt16(&pData[(5154 - addr1) * 2]); |
| | | int nErrCode = CToolUnits::toInt16(&pData[(5126 - addr1) * 2]); |
| | | int nAlarmCode = CToolUnits::toInt16(&pData[(5127 - addr1) * 2]); |
| | | CToolUnits::setDlgItemDouble(this, IDC_EDIT_AXIS_CURR_POS, fCurPos); |
| | | CToolUnits::setDlgItemDouble(this, IDC_EDIT_AXIS_CURR_MANUAL_SPEED, fManualSpeed); |
| | | CToolUnits::setDlgItemDouble(this, IDC_EDIT_AXIS_CURR_AUTO_SPEED, fAutoSpeed); |
| | | CToolUnits::setDlgItemDouble(this, IDC_EDIT_AXIS_CURR_ROTA_SPEED, fPrm); |
| | | SetDlgItemInt(IDC_EDIT_AXIS_CURR_LOAD, nLoad); |
| | | SetDlgItemInt(IDC_EDIT_AXIS_CURR_ERROR_NUMBER, nErrCode); |
| | | SetDlgItemInt(IDC_EDIT_AXIS_CURR_ALARM_NUMBER, nAlarmCode); |
| | | } |
| | | }; |
| | | m_pPLC->readData(MC::SOFT_COMPONENT::D, addr1, readSize, funOnReadData); |
| | | } |
| | | else if (nIDEvent == TIMER_JOG_ADD && m_bJogAddPressed) { |
| | | TRACE("æç»åé JOG+\n"); |
| | | handleAxisOperation(AxisOperationType::JOG_ADD, true); // æç»åé JOG+ |
| | | Sleep(20); |
| | | } |
| | | else if (nIDEvent == TIMER_JOG_SUB && m_bJogSubPressed) { |
| | | TRACE("æç»åé JOG-\n"); |
| | | handleAxisOperation(AxisOperationType::JOG_SUB, true); // æç»åé JOG- |
| | | Sleep(20); |
| | | } |
| | | |
| | | CDialogEx::OnTimer(nIDEvent); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include "afxdialogex.h" |
| | | #include "BlButton.h" |
| | | #include "BLLabel.h" |
| | | #include "CPLC.h" |
| | | |
| | | // CAxisSettingsDlg å¯¹è¯æ¡ |
| | | |
| | | enum class AxisOperationType { |
| | | OPR = 0, // ååç¹ |
| | | JOG_ADD, // æ£åç¹å¨ |
| | | JOG_SUB, // ååç¹å¨ |
| | | STOP, // 忢æä½ |
| | | POSITION_1, // å®ä½ç¹1 |
| | | POSITION_2, // å®ä½ç¹2 |
| | | POSITION_3, // å®ä½ç¹3 |
| | | POSITION_4, // å®ä½ç¹4 |
| | | POSITION_5 // å®ä½ç¹5 |
| | | }; |
| | | |
| | | class CAxisSettingsDlg : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CAxisSettingsDlg) |
| | | |
| | | public: |
| | | CAxisSettingsDlg(CWnd* pParent = nullptr); // æ åæé 彿° |
| | | virtual ~CAxisSettingsDlg(); |
| | | |
| | | public: |
| | | void SetPLC(CPLC* pPLC); |
| | | void SetRecipeName(const CString& strRecipeName); |
| | | |
| | | // å¯¹è¯æ¡æ°æ® |
| | | #ifdef AFX_DESIGN_TIME |
| | | enum { IDD = IDD_DIALOG_AXIS_SETTINGS }; |
| | | #endif |
| | | |
| | | private: |
| | | UINT FindIDByName(const CString& strControlID); |
| | | CFont* GetOrCreateFont(int nFontSize); |
| | | void SetDefaultFont(); |
| | | void AdjustControls(float dScaleX, float dScaleY); |
| | | void AdjustControlFont(CWnd* pWnd, int nWidth, int nHeight); |
| | | void AdjustLabelFont(CBLLabel& label); |
| | | void SetStatusColor(CBLLabel& label, BOOL bStatus); |
| | | void updatePageButtonStates(); |
| | | int getCurrentSelectedAxisID(); |
| | | void initializeAxisIDCombo(); |
| | | void refreshAxisDetails(int nAxisId); |
| | | void refreshPositionDetails(int nAxisId, int pageNumber); |
| | | void updateAxisSelection(int offset); |
| | | void updateDataFromUI(int nAxisId); |
| | | void switchToPage(int targetPage); |
| | | void writeAxisDataToPLC(int nAxisId); |
| | | void handleAxisOperation(AxisOperationType eOpType, bool bPressed); |
| | | |
| | | |
| | | private: |
| | | CPLC* m_pPLC; |
| | | int m_nInitialWidth; |
| | | int m_nInitialHeight; |
| | | |
| | | // å½åéä¸çå®ä½é¡µé¢ç´¢å¼ |
| | | int m_currentPage; |
| | | |
| | | // é
æ¹åç§° |
| | | CString m_strRecipeName; |
| | | |
| | | // æä¸æ è¯ |
| | | BOOL m_bJogAddPressed; |
| | | BOOL m_bJogSubPressed; |
| | | |
| | | // æ§ä»¶ |
| | | CBLLabel m_staticFLS, m_staticDOG, m_staticRLS, m_staticReady, m_staticBusy, m_staticErr; |
| | | CComboBox m_comboAxisNO; |
| | | CStatic m_staticAxisNO, m_staticAxisDescription, m_staticStartAddress; |
| | | CEdit m_editManualSpeed, m_editAutoSpeed, m_editAccelerationTime, m_editDecelerationTime, m_editJogDistance; |
| | | CBlButton m_pageButtons[5]; |
| | | |
| | | std::map<int, CRect> m_mapCtrlLayouts; |
| | | std::map<int, CFont*> m_mapFonts; |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV æ¯æ |
| | | virtual BOOL OnInitDialog(); |
| | | virtual BOOL PreTranslateMessage(MSG* pMsg); |
| | | afx_msg void OnSize(UINT nType, int cx, int cy); |
| | | afx_msg void OnSizing(UINT fwSide, LPRECT pRect); |
| | | afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); |
| | | afx_msg void OnBnClickedButtonAxisLast(); |
| | | afx_msg void OnBnClickedButtonAxisNext(); |
| | | afx_msg void OnBnClickedButtonAxisAnchorPointGroup1(); |
| | | afx_msg void OnBnClickedButtonAxisAnchorPointGroup2(); |
| | | afx_msg void OnBnClickedButtonAxisAnchorPointGroup3(); |
| | | afx_msg void OnBnClickedButtonAxisAnchorPointGroup4(); |
| | | afx_msg void OnBnClickedButtonAxisAnchorPointGroup5(); |
| | | afx_msg void OnBnClickedButtonAxisAnchorPoint1(); |
| | | afx_msg void OnBnClickedButtonAxisAnchorPoint2(); |
| | | afx_msg void OnBnClickedButtonAxisAnchorPoint3(); |
| | | afx_msg void OnBnClickedButtonAxisAnchorPoint4(); |
| | | afx_msg void OnBnClickedButtonAxisAnchorPoint5(); |
| | | afx_msg void OnBnClickedButtonAxisTestOpr(); |
| | | afx_msg void OnBnClickedButtonAxisTestStop(); |
| | | afx_msg void OnSelchangeComboAxisName(); |
| | | afx_msg void OnBnClickedButtonAxisSave(); |
| | | afx_msg void OnTimer(UINT_PTR nIDEvent); |
| | | DECLARE_MESSAGE_MAP() |
| | | }; |
| | |
| | | #include "BondEq.h" |
| | | #include "afxdialogex.h" |
| | | #include "ChangePasswordDlg.h" |
| | | #include "UserManager.h" |
| | | |
| | | |
| | | // CChangePasswordDlg å¯¹è¯æ¡ |
| | |
| | | return; |
| | | } |
| | | |
| | | SystemLogManager& logManager = SystemLogManager::getInstance(); |
| | | if (newPassword.Compare(currentPassword) == 0) { |
| | | EndDialog(IDCANCEL); |
| | | return; |
| | |
| | | if (userManager.isLoggedIn() && strCurrentPassword.compare(userManager.getCurrentPass()) == 0) { |
| | | if (changeUserPassword(userManager, strUsername, strNewPassword)) { |
| | | EndDialog(IDOK); |
| | | logManager.log(SystemLogManager::LogType::Info, "ä¿®æ¹å¯ç æåï¼", strUsername); |
| | | } |
| | | } |
| | | else { |
| | | if (userManager.login(strUsername, strCurrentPassword)) { |
| | | if (changeUserPassword(userManager, strUsername, strNewPassword)) { |
| | | EndDialog(IDOK); |
| | | logManager.log(SystemLogManager::LogType::Info, "ä¿®æ¹å¯ç æåï¼", strUsername); |
| | | } |
| | | else { |
| | | userManager.logout(); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // IOMonitoringDlg.cpp: å®ç°æä»¶ |
| | | // |
| | | |
| | | #include "stdafx.h" |
| | | #include "BondEq.h" |
| | | #include "afxdialogex.h" |
| | | #include "IOMonitoringDlg.h" |
| | | #include "ToolUnits.h" |
| | | |
| | | #define TIMER_INIT 1 |
| | | #define TIMER_READ_PLC_DATA 2 |
| | | |
| | | // CIOMonitoringDlg å¯¹è¯æ¡ |
| | | |
| | | IMPLEMENT_DYNAMIC(CIOMonitoringDlg, CDialogEx) |
| | | |
| | | CIOMonitoringDlg::CIOMonitoringDlg(CWnd* pParent /*=nullptr*/) |
| | | : CDialogEx(IDD_DIALOG_IO_MONITORING, pParent) |
| | | { |
| | | m_nCurrentPage = 1; |
| | | m_nTotalPages = 1; |
| | | m_nRowsPerPage = 10; |
| | | m_nCols = 6; |
| | | } |
| | | |
| | | CIOMonitoringDlg::~CIOMonitoringDlg() |
| | | { |
| | | for (auto& pair : m_mapFonts) { |
| | | if (pair.second) { |
| | | pair.second->DeleteObject(); |
| | | delete pair.second; |
| | | } |
| | | } |
| | | m_mapFonts.clear(); |
| | | |
| | | ClearDynamicControls(); |
| | | } |
| | | |
| | | void CIOMonitoringDlg::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | DDX_Control(pDX, IDC_STATIC_PAGE_NUMBER, m_staticPageNum); |
| | | } |
| | | |
| | | void CIOMonitoringDlg::SetIOManager(const std::string& machineName) |
| | | { |
| | | IOManager manager; |
| | | manager.loadFromFile(machineName); |
| | | m_machineName = machineName; |
| | | |
| | | // å è½½æ°æ® |
| | | m_displayData = manager.GetMachineData(machineName); |
| | | |
| | | // 计ç®é¡µæ° |
| | | m_nCurrentPage = 1; |
| | | m_nTotalPages = (m_displayData.size() + m_nRowsPerPage - 1) / m_nRowsPerPage; |
| | | } |
| | | |
| | | void CIOMonitoringDlg::SetPLC(CPLC* pPLC) |
| | | { |
| | | ASSERT(pPLC); |
| | | m_pPLC = pPLC; |
| | | } |
| | | |
| | | CFont* CIOMonitoringDlg::GetOrCreateFont(int nFontSize) |
| | | { |
| | | auto it = m_mapFonts.find(nFontSize); |
| | | if (it != m_mapFonts.end()) { |
| | | return it->second; |
| | | } |
| | | |
| | | CFont* font = new CFont(); |
| | | LOGFONT logFont = { 0 }; |
| | | _tcscpy_s(logFont.lfFaceName, _T("Segoe UI")); |
| | | logFont.lfHeight = -nFontSize; |
| | | logFont.lfQuality = CLEARTYPE_QUALITY; |
| | | font->CreateFontIndirect(&logFont); |
| | | m_mapFonts[nFontSize] = font; |
| | | |
| | | return font; |
| | | } |
| | | |
| | | void CIOMonitoringDlg::SetDefaultFont() |
| | | { |
| | | CFont* defaultFont = GetOrCreateFont(12); |
| | | |
| | | // éåæææ§ä»¶ï¼åºç¨é»è®¤åä½ |
| | | CWnd* pWnd = GetWindow(GW_CHILD); |
| | | while (pWnd) { |
| | | pWnd->SetFont(defaultFont, TRUE); |
| | | pWnd = pWnd->GetNextWindow(); |
| | | } |
| | | } |
| | | |
| | | void CIOMonitoringDlg::AdjustControls(float dScaleX, float dScaleY) |
| | | { |
| | | CWnd* pWnd = GetWindow(GW_CHILD); |
| | | while (pWnd) { |
| | | int nCtrlID = pWnd->GetDlgCtrlID(); |
| | | if (nCtrlID != -1 && m_mapCtrlLayouts.find(nCtrlID) != m_mapCtrlLayouts.end()) { |
| | | CRect originalRect = m_mapCtrlLayouts[nCtrlID]; |
| | | CRect newRect( |
| | | static_cast<int>(originalRect.left * dScaleX), |
| | | static_cast<int>(originalRect.top * dScaleY), |
| | | static_cast<int>(originalRect.right * dScaleX), |
| | | static_cast<int>(originalRect.bottom * dScaleY)); |
| | | |
| | | pWnd->MoveWindow(&newRect); |
| | | AdjustControlFont(pWnd, newRect.Width(), newRect.Height()); |
| | | } |
| | | pWnd = pWnd->GetNextWindow(); |
| | | } |
| | | } |
| | | |
| | | void CIOMonitoringDlg::AdjustControlFont(CWnd* pWnd, int nWidth, int nHeight) |
| | | { |
| | | TCHAR szClassName[256]; |
| | | GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName)); |
| | | |
| | | // æ ¹æ®æ§ä»¶é«åº¦å¨æè°æ´åä½å¤§å° |
| | | int fontSize = nHeight / 2; |
| | | if (fontSize < 8) fontSize = 8; |
| | | if (fontSize < 24) fontSize = 24; |
| | | |
| | | // è·åæå建åä½ |
| | | CFont* pFont = GetOrCreateFont(fontSize); |
| | | |
| | | pWnd->SetFont(pFont); |
| | | pWnd->Invalidate(); // å·æ°æ§ä»¶æ¾ç¤º |
| | | } |
| | | |
| | | void CIOMonitoringDlg::UpdatePageInfo() |
| | | { |
| | | // æ ¼å¼å页ç ä¿¡æ¯ä¸º "å½å页/æ»é¡µæ°" |
| | | CString pageInfo; |
| | | pageInfo.Format(_T("%d/%d 页"), m_nCurrentPage, m_nTotalPages); |
| | | m_staticPageNum.SetWindowText(pageInfo); |
| | | } |
| | | |
| | | void CIOMonitoringDlg::CreateDynamicControls() |
| | | { |
| | | CRect rect; |
| | | GetClientRect(&rect); |
| | | |
| | | // è·åæé®çå¤§å° |
| | | CWnd* pPrevButton = GetDlgItem(IDC_BUTTON_PREV_PAGE); |
| | | CWnd* pNextButton = GetDlgItem(IDC_BUTTON_NEXT_PAGE); |
| | | |
| | | CRect prevButtonRect, nextButtonRect; |
| | | pPrevButton->GetWindowRect(&prevButtonRect); |
| | | pNextButton->GetWindowRect(&nextButtonRect); |
| | | |
| | | // è½¬æ¢æé®åæ å°å¯¹è¯æ¡çåæ ç³»ç» |
| | | ScreenToClient(&prevButtonRect); |
| | | ScreenToClient(&nextButtonRect); |
| | | |
| | | int buttonHeight = prevButtonRect.Height(); // æé®çé«åº¦ |
| | | int topMargin = rect.Height() * 0.05; // é¡¶é¨ä¿ç 5% çé«åº¦ |
| | | int bottomMargin = buttonHeight + topMargin; // åºé¨ä¿çæé®é«åº¦å é´è· |
| | | int sideMargin = topMargin; // å·¦å³é´è·ä¸é¡¶é¨é´è·ç¸å |
| | | int groupSpacing = 20; // 两ç»ä¹é´çé´è· |
| | | int verticalSpacing = 10; // åç´é´è· |
| | | |
| | | // æ¯è¡é«åº¦åå宽度 |
| | | int availableHeight = rect.Height() - topMargin - bottomMargin; |
| | | int rowHeight = (availableHeight / m_nRowsPerPage) - verticalSpacing; // æ§ä»¶é«åº¦å
å«é´è· |
| | | |
| | | int availableWidth = rect.Width() - 2 * sideMargin; // å¯ç¨å®½åº¦ï¼åå»å·¦å³é´è·ï¼ |
| | | int colWidthSmall = availableWidth / 14; // å°å®½åº¦åæ´å° |
| | | int colWidthLarge = availableWidth * 4 / 14; // å¤§å®½åº¦åæ¯ä¾ |
| | | int groupWidth = colWidthSmall * 2 + colWidthLarge; // æ¯ç»æ»å®½åº¦ |
| | | |
| | | for (int i = 0; i < m_nRowsPerPage; ++i) { |
| | | // æ¯ä¸è¡çèµ·å§ Y åæ |
| | | int y = topMargin + i * (rowHeight + verticalSpacing); |
| | | |
| | | // å建第 1 ç» (0, 1, 2) |
| | | int x = sideMargin; // ä»å·¦è¾¹è·å¼å§ |
| | | CreateStaticControl(x, y, colWidthSmall, rowHeight, _T("OFF"), true, AlignCenter); |
| | | x += colWidthSmall; |
| | | CreateStaticControl(x, y, colWidthSmall, rowHeight, _T("X1000"), false, AlignCenter); |
| | | x += colWidthSmall; |
| | | CreateStaticControl(x, y, colWidthLarge, rowHeight, _T("æè¿°ææ¬"), false); |
| | | |
| | | // 第 2 ç»èµ·å§ä½ç½®ï¼å ä¸ç»é´è· |
| | | x += colWidthLarge + groupSpacing; |
| | | |
| | | // å建第 2 ç» (3, 4, 5) |
| | | CreateStaticControl(x, y, colWidthSmall, rowHeight, _T("OFF"), true, AlignCenter, [this, i]() { |
| | | // èªå®ä¹ç¹å»äºä»¶çé»è¾ |
| | | auto* pControl = static_cast<CBLLabel*>(m_staticControls[i * m_nCols + 3]); |
| | | CString currentText; |
| | | pControl->GetWindowText(currentText); |
| | | |
| | | BOOL bOn = FALSE; |
| | | if (currentText == _T("OFF")) { |
| | | //pControl->SetBkColor(RGB(0, 255, 0)); // 绿è²èæ¯ |
| | | //pControl->SetText(_T("ON")); // æ´æ°ææ¬ä¸º ON |
| | | bOn = TRUE; |
| | | } |
| | | else { |
| | | //pControl->SetBkColor(RGB(255, 0, 0)); // 红è²èæ¯ |
| | | //pControl->SetText(_T("OFF")); // æ´æ°ææ¬ä¸º OFF |
| | | bOn = FALSE; |
| | | } |
| | | |
| | | pControl = static_cast<CBLLabel*>(m_staticControls[i * m_nCols + 4]); |
| | | pControl->GetWindowText(currentText); |
| | | |
| | | int nAddress; |
| | | MC::SOFT_COMPONENT component; |
| | | if (ParsePLCAddress(currentText, component, nAddress) && m_pPLC) { |
| | | TRACE("å°åè§£ææå: %s\n", currentText); |
| | | m_pPLC->writeBit(component, nAddress, bOn, [](IMcChannel* pChannel, int addr, DWORD value, int flag) { |
| | | if (flag == 0) { |
| | | TRACE("åå
¥æå: å°å: %d, å¼: %lu\n", addr, value); |
| | | } |
| | | else { |
| | | TRACE("åå
¥å¤±è´¥: å°å: %d, é误ç : %d\n", addr, flag); |
| | | } |
| | | }); |
| | | } |
| | | }); |
| | | x += colWidthSmall; |
| | | CreateStaticControl(x, y, colWidthSmall, rowHeight, _T("Y1010"), false, AlignCenter); |
| | | x += colWidthSmall; |
| | | CreateStaticControl(x, y, colWidthLarge, rowHeight, _T("æè¿°ææ¬"), false); |
| | | } |
| | | } |
| | | |
| | | void CIOMonitoringDlg::CreateStaticControl(int x, int y, int width, int height, const CString& text, bool hasBorder, TextAlign alignment, std::function<void()> clickCallback) |
| | | { |
| | | // åå»ºå¨ææ§ä»¶ |
| | | CBLLabel* pStatic = new CBLLabel(); |
| | | DWORD style = WS_CHILD | WS_VISIBLE | SS_CENTERIMAGE; // ç¡®ä¿åç´å±
ä¸ |
| | | if (hasBorder) { |
| | | style |= WS_BORDER; // æ·»å è¾¹æ¡ |
| | | } |
| | | pStatic->Create(text, style, CRect(x, y, x + width, y + height), this); |
| | | |
| | | // è®¾ç½®ææ¬å¯¹é½æ¹å¼ |
| | | pStatic->SetAlignment(alignment); |
| | | |
| | | // è®¾ç½®å¨æåä½è°æ´ï¼å¹¶è®¾ç½®åä½å¤§å°ï¼å¨æåä½ä¼æ ¹æ®æ§ä»¶å¤§å°è°æ´ï¼ |
| | | int nSize = height / 3; |
| | | CFont* pFont = GetOrCreateFont(nSize); |
| | | pStatic->SetFont(pFont); |
| | | pStatic->SetFontSize(nSize); |
| | | pStatic->SetDynamicFont(TRUE); |
| | | |
| | | // 设置åè° |
| | | if (clickCallback) { |
| | | pStatic->SetClickCallback(clickCallback); |
| | | } |
| | | |
| | | // å卿§ä»¶æé |
| | | m_staticControls.push_back(pStatic); |
| | | } |
| | | |
| | | void CIOMonitoringDlg::DisplayCurrentPage() |
| | | { |
| | | int startIndex = (m_nCurrentPage - 1) * m_nRowsPerPage; |
| | | int endIndex = min(startIndex + m_nRowsPerPage, static_cast<int>(m_displayData.size())); |
| | | |
| | | m_inputPLCAddresses.clear(); |
| | | m_outputPLCAddresses.clear(); |
| | | |
| | | for (int i = 0; i < m_nRowsPerPage; ++i) { |
| | | int row = i; |
| | | |
| | | if (startIndex + i < endIndex) { |
| | | const auto& data = m_displayData[startIndex + i]; |
| | | |
| | | // æ·»å PLC å°åå°å®¹å¨ä¸ |
| | | m_inputPLCAddresses.push_back(CString(data.inputAddress.c_str())); // 1 å |
| | | m_outputPLCAddresses.push_back(CString(data.outputAddress.c_str())); // 4 å |
| | | |
| | | // æ¾ç¤ºæ§ä»¶å¹¶è®¾ç½®å
容 |
| | | m_staticControls[row * m_nCols + 0]->SetWindowText(_T("OFF")); |
| | | m_staticControls[row * m_nCols + 0]->ShowWindow(SW_SHOW); |
| | | m_staticControls[row * m_nCols + 0]->SetBkColor(RGB(255, 0, 0)); |
| | | |
| | | m_staticControls[row * m_nCols + 1]->SetWindowText(CString(data.inputAddress.c_str())); |
| | | m_staticControls[row * m_nCols + 1]->ShowWindow(SW_SHOW); |
| | | |
| | | m_staticControls[row * m_nCols + 2]->SetWindowText(CString(data.inputDescription.c_str())); |
| | | m_staticControls[row * m_nCols + 2]->ShowWindow(SW_SHOW); |
| | | |
| | | m_staticControls[row * m_nCols + 3]->SetWindowText(_T("OFF")); |
| | | m_staticControls[row * m_nCols + 3]->ShowWindow(SW_SHOW); |
| | | m_staticControls[row * m_nCols + 3]->SetBkColor(RGB(255, 0, 0)); |
| | | |
| | | m_staticControls[row * m_nCols + 4]->SetWindowText(CString(data.outputAddress.c_str())); |
| | | m_staticControls[row * m_nCols + 4]->ShowWindow(SW_SHOW); |
| | | |
| | | m_staticControls[row * m_nCols + 5]->SetWindowText(CString(data.outputDescription.c_str())); |
| | | m_staticControls[row * m_nCols + 5]->ShowWindow(SW_SHOW); |
| | | } |
| | | else { |
| | | // éèè¿ä¸è¡çæææ§ä»¶ |
| | | for (int col = 0; col < m_nCols; ++col) { |
| | | m_staticControls[row * m_nCols + col]->ShowWindow(SW_HIDE); |
| | | } |
| | | } |
| | | } |
| | | |
| | | UpdatePageInfo(); |
| | | } |
| | | |
| | | void CIOMonitoringDlg::ClearDynamicControls() |
| | | { |
| | | for (auto* pStatic : m_staticControls) { |
| | | if (pStatic) { |
| | | pStatic->DestroyWindow(); |
| | | delete pStatic; |
| | | } |
| | | } |
| | | m_staticControls.clear(); |
| | | } |
| | | |
| | | bool CIOMonitoringDlg::ParsePLCAddress(const CString& address, MC::SOFT_COMPONENT& component, int& addr) |
| | | { |
| | | if (address.GetLength() < 2) { |
| | | return false; |
| | | } |
| | | |
| | | // æåç»ä»¶ç±»åï¼ç¬¬ä¸ä¸ªåç¬¦ï¼ |
| | | TCHAR componentChar = address[0]; |
| | | switch (componentChar) { |
| | | case 'D': |
| | | component = MC::SOFT_COMPONENT::D; |
| | | break; |
| | | case 'M': |
| | | component = MC::SOFT_COMPONENT::M; |
| | | break; |
| | | case 'X': |
| | | component = MC::SOFT_COMPONENT::X; |
| | | break; |
| | | case 'Y': |
| | | component = MC::SOFT_COMPONENT::Y; |
| | | break; |
| | | default: |
| | | return false; |
| | | } |
| | | |
| | | CString hexAddress = address.Mid(1); |
| | | addr = _tcstoul(hexAddress, nullptr, 16); |
| | | |
| | | return true; |
| | | } |
| | | |
| | | void CIOMonitoringDlg::UpdatePLCStates() |
| | | { |
| | | // 示ä¾ï¼ä» PLC è·åå¼ï¼è¿éç¨éæºå¼æ¨¡æ |
| | | //for (size_t i = 0; i < m_inputPLCAddresses.size(); ++i) { |
| | | // // 模æè·åè¾å
¥ç¶æ |
| | | // bool inputState = (rand() % 2 == 0); // å¶å°ä¸º true/false |
| | | // auto* inputControl = static_cast<CBLLabel*>(m_staticControls[i * m_nCols + 0]); |
| | | // inputControl->SetBkColor(inputState ? RGB(0, 255, 0) : RGB(255, 0, 0)); |
| | | // inputControl->SetText(inputState ? _T("ON") : _T("OFF")); |
| | | //} |
| | | |
| | | //for (size_t i = 0; i < m_outputPLCAddresses.size(); ++i) { |
| | | // // 模æè·åè¾åºç¶æ |
| | | // bool outputState = (rand() % 2 == 0); // å¶å°ä¸º true/false |
| | | // auto* outputControl = static_cast<CBLLabel*>(m_staticControls[i * m_nCols + 3]); |
| | | // outputControl->SetBkColor(outputState ? RGB(0, 255, 0) : RGB(255, 0, 0)); |
| | | // outputControl->SetText(outputState ? _T("ON") : _T("OFF")); |
| | | //} |
| | | |
| | | // è¾å
¥å°åç读å |
| | | if (!m_inputPLCAddresses.empty()) { |
| | | // è·åèµ·å§å°ååé¿åº¦ |
| | | CString startAddressStr = m_inputPLCAddresses.front(); |
| | | CString endAddressStr = m_inputPLCAddresses.back(); |
| | | MC::SOFT_COMPONENT component; |
| | | int startAddress, endAddress; |
| | | |
| | | // è§£æèµ·å§åç»æå°å |
| | | if (ParsePLCAddress(startAddressStr, component, startAddress) && |
| | | ParsePLCAddress(endAddressStr, component, endAddress)) { |
| | | int inputSize = endAddress - startAddress + 1; |
| | | |
| | | // åè°å¤çè¾å
¥æ°æ® |
| | | auto funOnReadInput = [this, startAddress](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) { |
| | | if (nDataSize == (unsigned int)(m_inputPLCAddresses.size()) && flag == 0) { |
| | | for (size_t i = 0; i < m_inputPLCAddresses.size(); ++i) { |
| | | int offset = i; |
| | | int value = CToolUnits::toInt16(&pData[offset]); |
| | | |
| | | auto* inputControl = static_cast<CBLLabel*>(m_staticControls[i * m_nCols + 0]); // 第 0 å |
| | | inputControl->SetBkColor(value ? RGB(0, 255, 0) : RGB(255, 0, 0)); // æ´æ°èæ¯é¢è² |
| | | inputControl->SetText(value ? _T("ON") : _T("OFF")); // æ´æ°ææ¬ |
| | | } |
| | | } |
| | | }; |
| | | |
| | | // 读åè¾å
¥æ°æ® |
| | | m_pPLC->readData(component, startAddress, inputSize, funOnReadInput); |
| | | } |
| | | } |
| | | |
| | | // è¾åºå°åç读å |
| | | if (!m_outputPLCAddresses.empty()) { |
| | | // è·åèµ·å§å°ååé¿åº¦ |
| | | CString startAddressStr = m_outputPLCAddresses.front(); |
| | | CString endAddressStr = m_outputPLCAddresses.back(); |
| | | MC::SOFT_COMPONENT component; |
| | | int startAddress, endAddress; |
| | | |
| | | // è§£æèµ·å§åç»æå°å |
| | | if (ParsePLCAddress(startAddressStr, component, startAddress) && |
| | | ParsePLCAddress(endAddressStr, component, endAddress)) { |
| | | int outputSize = endAddress - startAddress + 1; |
| | | |
| | | // åè°å¤çè¾åºæ°æ® |
| | | auto funOnReadOutput = [this, startAddress](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) { |
| | | if (nDataSize == (unsigned int)(m_outputPLCAddresses.size()) && flag == 0) { |
| | | for (size_t i = 0; i < m_outputPLCAddresses.size(); ++i) { |
| | | int offset = i; |
| | | int value = CToolUnits::toInt16(&pData[offset]); |
| | | |
| | | auto* outputControl = static_cast<CBLLabel*>(m_staticControls[i * m_nCols + 3]); // 第 3 å |
| | | outputControl->SetBkColor(value ? RGB(0, 255, 0) : RGB(255, 0, 0)); // æ´æ°èæ¯é¢è² |
| | | outputControl->SetText(value ? _T("ON") : _T("OFF")); // æ´æ°ææ¬ |
| | | } |
| | | } |
| | | }; |
| | | |
| | | // 读åè¾åºæ°æ® |
| | | m_pPLC->readData(component, startAddress, outputSize, funOnReadOutput); |
| | | } |
| | | } |
| | | } |
| | | |
| | | BEGIN_MESSAGE_MAP(CIOMonitoringDlg, CDialogEx) |
| | | ON_BN_CLICKED(IDC_BUTTON_PREV_PAGE, &CIOMonitoringDlg::OnBnClickedButtonPrevPage) |
| | | ON_BN_CLICKED(IDC_BUTTON_NEXT_PAGE, &CIOMonitoringDlg::OnBnClickedButtonNextPage) |
| | | ON_WM_SIZE() |
| | | ON_WM_TIMER() |
| | | ON_WM_CLOSE() |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | | // CIOMonitoringDlg æ¶æ¯å¤çç¨åº |
| | | |
| | | |
| | | BOOL CIOMonitoringDlg::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | |
| | | // TODO: 卿¤æ·»å é¢å¤çåå§å |
| | | CRect screenRect, dlgRect, clientRect; |
| | | SystemParametersInfo(SPI_GETWORKAREA, 0, &screenRect, 0); |
| | | |
| | | GetClientRect(&clientRect); |
| | | m_nInitialWidth = clientRect.Width(); |
| | | m_nInitialHeight = clientRect.Height(); |
| | | |
| | | // åå§åé»è®¤åä½ |
| | | CFont* pDefaultFont = GetOrCreateFont(12); |
| | | |
| | | // éåææåæ§ä»¶ï¼è®°å½åå§ä½ç½®å¹¶è®¾ç½®é»è®¤åä½ |
| | | CWnd* pWnd = GetWindow(GW_CHILD); |
| | | while (pWnd) { |
| | | int nCtrlID = pWnd->GetDlgCtrlID(); |
| | | if (nCtrlID != -1) { |
| | | // è®°å½æ§ä»¶åå§å¸å± |
| | | CRect ctrlRect; |
| | | pWnd->GetWindowRect(&ctrlRect); |
| | | ScreenToClient(&ctrlRect); |
| | | m_mapCtrlLayouts[nCtrlID] = ctrlRect; |
| | | |
| | | // è·³è¿ç¹æ®æ§ä»¶ï¼å¦ MFCGridCtrlï¼ |
| | | TCHAR szClassName[256]; |
| | | GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName)); |
| | | if (_tcsicmp(szClassName, _T("MFCGridCtrl")) == 0) { |
| | | pWnd = pWnd->GetNextWindow(); |
| | | continue; |
| | | } |
| | | |
| | | // 设置é»è®¤åä½ |
| | | pWnd->SetFont(pDefaultFont); |
| | | } |
| | | pWnd = pWnd->GetNextWindow(); |
| | | } |
| | | |
| | | GetWindowRect(&dlgRect); |
| | | int dlgWidth = dlgRect.Width() * 2; |
| | | int dlgHeight = dlgRect.Height() * 2; |
| | | |
| | | if (dlgWidth > screenRect.Width()) { |
| | | dlgWidth = screenRect.Width(); |
| | | } |
| | | if (dlgHeight > screenRect.Height()) { |
| | | dlgHeight = screenRect.Height(); |
| | | } |
| | | |
| | | int centerX = screenRect.left + (screenRect.Width() - dlgWidth) / 2; |
| | | int centerY = screenRect.top + (screenRect.Height() - dlgHeight) / 2; |
| | | MoveWindow(centerX, centerY, dlgWidth, dlgHeight); |
| | | |
| | | CreateDynamicControls(); |
| | | DisplayCurrentPage(); |
| | | |
| | | SetTimer(TIMER_READ_PLC_DATA, 500, nullptr); |
| | | |
| | | return TRUE; // return TRUE unless you set the focus to a control |
| | | // å¼å¸¸: OCX 屿§é¡µåºè¿å FALSE |
| | | } |
| | | |
| | | void CIOMonitoringDlg::OnSize(UINT nType, int cx, int cy) |
| | | { |
| | | CDialogEx::OnSize(nType, cx, cy); |
| | | |
| | | // TODO: 卿¤å¤æ·»å æ¶æ¯å¤çç¨åºä»£ç |
| | | if (nType == SIZE_MINIMIZED || m_mapCtrlLayouts.empty()) { |
| | | return; |
| | | } |
| | | |
| | | float dScaleX = static_cast<float>(cx) / m_nInitialWidth; |
| | | float dScaleY = static_cast<float>(cy) / m_nInitialHeight; |
| | | |
| | | // éåå¯¹è¯æ¡ä¸çæææ§ä»¶ |
| | | AdjustControls(dScaleX, dScaleY); |
| | | } |
| | | |
| | | void CIOMonitoringDlg::OnBnClickedButtonPrevPage() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | if (m_nCurrentPage > 1) { |
| | | --m_nCurrentPage; |
| | | DisplayCurrentPage(); |
| | | } |
| | | else { |
| | | AfxMessageBox(_T("å·²ç»æ¯ç¬¬ä¸é¡µï¼")); |
| | | } |
| | | } |
| | | |
| | | void CIOMonitoringDlg::OnBnClickedButtonNextPage() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | if (m_nCurrentPage < m_nTotalPages) { |
| | | ++m_nCurrentPage; |
| | | DisplayCurrentPage(); |
| | | } |
| | | else { |
| | | AfxMessageBox(_T("å·²ç»æ¯æåä¸é¡µï¼")); |
| | | } |
| | | } |
| | | |
| | | void CIOMonitoringDlg::OnTimer(UINT_PTR nIDEvent) |
| | | { |
| | | // TODO: 卿¤æ·»å æ¶æ¯å¤çç¨åºä»£ç å/æè°ç¨é»è®¤å¼ |
| | | if (TIMER_READ_PLC_DATA == nIDEvent) { |
| | | ASSERT(m_pPLC); |
| | | UpdatePLCStates(); |
| | | Sleep(100); |
| | | } |
| | | CDialogEx::OnTimer(nIDEvent); |
| | | } |
| | | |
| | | void CIOMonitoringDlg::OnClose() |
| | | { |
| | | // TODO: 卿¤æ·»å æ¶æ¯å¤çç¨åºä»£ç å/æè°ç¨é»è®¤å¼ |
| | | KillTimer(TIMER_READ_PLC_DATA); |
| | | CDialogEx::OnClose(); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include "afxdialogex.h" |
| | | #include "IOManager.h" |
| | | #include "BLLabel.h" |
| | | #include "CPLC.h" |
| | | |
| | | |
| | | // CIOMonitoringDlg å¯¹è¯æ¡ |
| | | |
| | | class CIOMonitoringDlg : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CIOMonitoringDlg) |
| | | |
| | | public: |
| | | CIOMonitoringDlg(CWnd* pParent = nullptr); // æ åæé 彿° |
| | | virtual ~CIOMonitoringDlg(); |
| | | void SetIOManager(const std::string& machineName); // 设置 IOManager åæºå¨å |
| | | void SetPLC(CPLC* pPLC); // 设置 PLC |
| | | |
| | | // å¯¹è¯æ¡æ°æ® |
| | | #ifdef AFX_DESIGN_TIME |
| | | enum { IDD = IDD_DIALOG_IO_MONITORING }; |
| | | #endif |
| | | |
| | | private: |
| | | CFont* GetOrCreateFont(int nFontSize); // è·åæå建åä½ |
| | | void SetDefaultFont(); // 设置é»è®¤åä½ |
| | | void AdjustControls(float dScaleX, float dScaleY); // è°æ´æ§ä»¶å¤§å° |
| | | void AdjustControlFont(CWnd* pWnd, int nWidth, int nHeight); // è°æ´æ§ä»¶åä½å¤§å° |
| | | |
| | | void UpdatePageInfo(); // æ´æ°åé¡µä¿¡æ¯ |
| | | void CreateDynamicControls(); // 卿å建æ§ä»¶ |
| | | void CreateStaticControl(int x, int y, int width, int height, const CString& text, bool hasBorder = false, TextAlign alignment = AlignLeft, std::function<void()> clickCallback = nullptr); // åå»ºéææ§ä»¶ |
| | | void DisplayCurrentPage(); // æ¾ç¤ºå½åé¡µæ°æ® |
| | | void ClearDynamicControls(); // æ¸
é¤å¨æåå»ºçæ§ä»¶ |
| | | bool ParsePLCAddress(const CString& address, MC::SOFT_COMPONENT& component, int& addr); // è§£æ PLC å°å |
| | | void UpdatePLCStates(); // 宿¶å¨æ´æ°ç¶æçæ¹æ³ |
| | | |
| | | private: |
| | | CPLC* m_pPLC; |
| | | int m_nInitialWidth; |
| | | int m_nInitialHeight; |
| | | int m_nCurrentPage; // å½å页 |
| | | int m_nTotalPages; // æ»é¡µæ° |
| | | int m_nRowsPerPage; // æ¯é¡µæ¾ç¤ºçè¡æ° |
| | | int m_nCols; // æ¯è¡çæ§ä»¶ç»æ° |
| | | std::string m_machineName; // å½åæºå¨å |
| | | std::map<int, CFont*> m_mapFonts; // å使 å° |
| | | std::map<int, CRect> m_mapCtrlLayouts; // æ§ä»¶å¸å±æ å° |
| | | std::vector<IOData> m_displayData; // å½åæ¾ç¤ºçæ°æ® |
| | | std::vector<CString> m_inputPLCAddresses; // åå¨ 1 å PLC å°å |
| | | std::vector<CString> m_outputPLCAddresses; // åå¨ 4 å PLC å°å |
| | | |
| | | private: |
| | | CStatic m_staticPageNum; |
| | | std::vector<CBLLabel*> m_staticControls; // 卿å建çéææ§ä»¶ |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV æ¯æ |
| | | |
| | | DECLARE_MESSAGE_MAP() |
| | | public: |
| | | virtual BOOL OnInitDialog(); |
| | | afx_msg void OnSize(UINT nType, int cx, int cy); |
| | | afx_msg void OnBnClickedButtonPrevPage(); |
| | | afx_msg void OnBnClickedButtonNextPage(); |
| | | afx_msg void OnTimer(UINT_PTR nIDEvent); |
| | | afx_msg void OnClose(); |
| | | }; |
| | |
| | | #include "BondEq.h" |
| | | #include "afxdialogex.h" |
| | | #include "LoginDlg.h" |
| | | #include "UserManager.h" |
| | | #include "ChangePasswordDlg.h" |
| | | |
| | | |
| | |
| | | |
| | | void CLoginDlg::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | DDX_Control(pDX, IDC_EDIT_USERNAME, m_editUsername); |
| | | DDX_Control(pDX, IDC_EDIT_PASSWORD, m_editPassword); |
| | | DDX_Control(pDX, IDC_COMBO_ROLE, m_comboRole); |
| | | DDX_Control(pDX, IDC_CHECK_REMEMBER_PASSWORD, m_checkRememberPassword); |
| | | CDialogEx::DoDataExchange(pDX); |
| | | DDX_Control(pDX, IDC_STATIC_IMAGE, m_staticImage); |
| | | DDX_Control(pDX, IDC_EDIT_USERNAME, m_editUsername); |
| | | DDX_Control(pDX, IDC_EDIT_PASSWORD, m_editPassword); |
| | | DDX_Control(pDX, IDC_CHECK_REMEMBER_PASSWORD, m_checkRememberPassword); |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | // 设置çªå£æ é¢ååå§å¼ |
| | | SetWindowText(_T("ç»å½")); |
| | | m_comboRole.AddString(_T("管çå")); |
| | | m_comboRole.AddString(_T("å·¥ç¨å¸")); |
| | | m_comboRole.AddString(_T("æä½å")); |
| | | m_comboRole.SetCurSel(0); |
| | | |
| | | CString strIconPath; |
| | | strIconPath.Format(_T("%s\\Res\\Operator_High_32.ico"), (LPTSTR)(LPCTSTR)theApp.m_strAppDir); |
| | | |
| | | // å è½½å¾æ |
| | | HICON hIcon = (HICON)::LoadImage( |
| | | nullptr, |
| | | strIconPath, |
| | | IMAGE_ICON, |
| | | 32, // 徿 宽度 |
| | | 32, // 徿 é«åº¦ |
| | | LR_LOADFROMFILE); |
| | | |
| | | if (hIcon) { |
| | | // 设置 CStatic æ§ä»¶ä¸ºå¾æ æ ·å¼ |
| | | m_staticImage.ModifyStyle(0xF, SS_ICON); |
| | | m_staticImage.SetIcon(hIcon); |
| | | } |
| | | |
| | | // æ·»å SS_NOTIFYæ ·å¼ |
| | | CStatic* pStatic = (CStatic*)GetDlgItem(IDC_STATIC_CHANGE_PASSWORD); |
| | |
| | | |
| | | UserManager& userManager = UserManager::getInstance(); |
| | | if (userManager.isLoggedIn()) { |
| | | int nRole = (int)userManager.getCurrentUserRole(); |
| | | if (nRole <= m_comboRole.GetCount()) { |
| | | m_comboRole.SetCurSel(nRole); |
| | | } |
| | | |
| | | if (userManager.isRememberMe()) { |
| | | m_checkRememberPassword.SetCheck(BST_CHECKED); |
| | | } |
| | |
| | | CString username, password, role; |
| | | m_editUsername.GetWindowText(username); |
| | | m_editPassword.GetWindowText(password); |
| | | m_comboRole.GetLBText(m_comboRole.GetCurSel(), role); |
| | | |
| | | if (username.IsEmpty() || password.IsEmpty()) { |
| | | AfxMessageBox(_T("请è¾å
¥ç¨æ·ååå¯ç ã")); |
| | |
| | | #endif |
| | | |
| | | UserManager& userManager = UserManager::getInstance(); |
| | | SystemLogManager& logManager = SystemLogManager::getInstance(); |
| | | if (!userManager.login(strUsername, strPassword, (m_checkRememberPassword.GetCheck() == BST_CHECKED))) { |
| | | AfxMessageBox(_T("ç»å½å¤±è´¥ã")); |
| | | return; |
| | | } |
| | | |
| | | EndDialog(IDOK); |
| | | logManager.log(SystemLogManager::LogType::Info, _T("ç»å½æå...")); |
| | | } |
| | | |
| | | void CLoginDlg::OnBnClickedChangePassword() |
| | |
| | | enum { IDD = IDD_DIALOG_LOGIN }; |
| | | #endif |
| | | |
| | | private: |
| | | CStatic m_staticImage; |
| | | CEdit m_editUsername; |
| | | CEdit m_editPassword; |
| | | CButton m_checkRememberPassword; |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV æ¯æ |
| | | virtual BOOL OnInitDialog(); |
| | | afx_msg void OnBnClickedLogin(); |
| | | afx_msg void OnBnClickedChangePassword(); |
| | | DECLARE_MESSAGE_MAP() |
| | | |
| | | private: |
| | | CEdit m_editUsername; |
| | | CEdit m_editPassword; |
| | | CComboBox m_comboRole; |
| | | CButton m_checkRememberPassword; |
| | | }; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // SystemLogManagerDlg.cpp: å®ç°æä»¶ |
| | | // |
| | | |
| | | #include "stdafx.h" |
| | | #include "BondEq.h" |
| | | #include "afxdialogex.h" |
| | | #include "SystemLogManagerDlg.h" |
| | | |
| | | |
| | | // CSystemLogManagerDlg å¯¹è¯æ¡ |
| | | |
| | | IMPLEMENT_DYNAMIC(CSystemLogManagerDlg, CDialogEx) |
| | | |
| | | CSystemLogManagerDlg::CSystemLogManagerDlg(CWnd* pParent /*=nullptr*/) |
| | | : CDialogEx(IDD_DIALOG_SYSTEM_LOG_MANAGER, pParent) |
| | | { |
| | | m_nInitialWidth = 0; |
| | | m_nInitialHeight = 0; |
| | | } |
| | | |
| | | CSystemLogManagerDlg::~CSystemLogManagerDlg() |
| | | { |
| | | for (auto& pair : m_mapFonts) { |
| | | if (pair.second) { |
| | | pair.second->DeleteObject(); |
| | | delete pair.second; |
| | | } |
| | | } |
| | | m_mapFonts.clear(); |
| | | } |
| | | |
| | | void CSystemLogManagerDlg::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | DDX_Control(pDX, IDC_COMBO_TYPE, m_comboType); |
| | | DDX_Control(pDX, IDC_COMBO_USER, m_comboUser); |
| | | DDX_Control(pDX, IDC_DATETIMEPICKER_START, m_dateTimeStart); |
| | | DDX_Control(pDX, IDC_DATETIMEPICKER_END, m_dateTimeEnd); |
| | | DDX_Control(pDX, IDC_EDIT_DESCRIPTION, m_editDescription); |
| | | DDX_Control(pDX, IDC_CUSTOM_LIST_LOGS, m_listLogs); |
| | | DDX_Control(pDX, IDC_STATIC_PAGE_NUMBER, m_staticPageNum); |
| | | } |
| | | |
| | | void CSystemLogManagerDlg::InitSystemLogManager() |
| | | { |
| | | if (m_listLogs.GetSafeHwnd() == NULL) |
| | | return; |
| | | |
| | | int nRows = 21; // å
æ¬è¡¨å¤´ï¼1 è¡ï¼åæ°æ®ï¼20 è¡ï¼ |
| | | int nCols = 5; |
| | | |
| | | int nFixRows = 1; |
| | | int nFixCols = 0; |
| | | int nRowIdx = 0; |
| | | int nColIdx = 0; |
| | | |
| | | m_listLogs.DeleteAllItems(); |
| | | m_listLogs.SetVirtualMode(FALSE); |
| | | m_listLogs.GetDefaultCell(TRUE, FALSE)->SetBackClr(g_nGridFixCellColor); // 设置åºå®è¡èæ¯è² |
| | | m_listLogs.GetDefaultCell(FALSE, TRUE)->SetBackClr(g_nGridFixCellColor); // 设置åºå®åèæ¯è² |
| | | m_listLogs.GetDefaultCell(FALSE, FALSE)->SetBackClr(g_nGridCellColor); // 设置åå
æ ¼èæ¯è² |
| | | m_listLogs.SetFixedTextColor(g_nGridFixFontColor); // 设置åºå®è¡ååä½é¢è² |
| | | |
| | | m_listLogs.SetRowCount(nRows); |
| | | m_listLogs.SetColumnCount(nCols); |
| | | m_listLogs.SetFixedRowCount(nFixRows); |
| | | m_listLogs.SetFixedColumnCount(nFixCols); |
| | | |
| | | // Col |
| | | m_listLogs.SetColumnWidth(nColIdx, 10); |
| | | m_listLogs.SetItemText(nRowIdx, nColIdx++, _T("No.")); |
| | | m_listLogs.SetColumnWidth(nColIdx, 10); |
| | | m_listLogs.SetItemText(nRowIdx, nColIdx++, _T("ç±»å")); |
| | | m_listLogs.SetColumnWidth(nColIdx, 100); |
| | | m_listLogs.SetItemText(nRowIdx, nColIdx++, _T("äºä»¶")); |
| | | m_listLogs.SetColumnWidth(nColIdx, 30); |
| | | m_listLogs.SetItemText(nRowIdx, nColIdx++, _T("ç¨æ·")); |
| | | m_listLogs.SetColumnWidth(nColIdx, 50); |
| | | m_listLogs.SetItemText(nRowIdx, nColIdx++, _T("æ¶é´")); |
| | | |
| | | // å建 20 è¡ç©ºç½æ°æ®è¡ |
| | | for (int i = 1; i < nRows; ++i) { |
| | | for (int j = 0; j < nCols; ++j) { |
| | | m_listLogs.SetItemText(i, j, _T("")); // åå§å为空å符串 |
| | | } |
| | | } |
| | | |
| | | m_listLogs.SetFixedRowSelection(FALSE); |
| | | m_listLogs.SetFixedColumnSelection(FALSE); |
| | | m_listLogs.SetEditable(FALSE); |
| | | m_listLogs.SetRowResize(FALSE); |
| | | m_listLogs.SetColumnResize(TRUE); |
| | | m_listLogs.ExpandColumnsToFit(TRUE); |
| | | m_listLogs.SetListMode(TRUE); // å¯ç¨åè¡¨æ¨¡å¼ |
| | | m_listLogs.EnableSelection(TRUE); // å¯ç¨éæ© |
| | | m_listLogs.SetSingleRowSelection(TRUE); // èªå¨æ´è¡é«äº®ï¼éå¶ä¸ºåè¡éæ©ï¼ |
| | | m_listLogs.ExpandLastColumn(); // æåä¸åå¡«å
ç½æ ¼ |
| | | |
| | | try { |
| | | FillSystemLogManager(); |
| | | } |
| | | catch (const std::exception& ex) { |
| | | CString errorMsg; |
| | | errorMsg.Format(_T("åå§åè¿è¡æ¥å¿å¤±è´¥ï¼%s"), CString(ex.what())); |
| | | AfxMessageBox(errorMsg, MB_ICONERROR); |
| | | } |
| | | } |
| | | |
| | | void CSystemLogManagerDlg::FillSystemLogManager() |
| | | { |
| | | // è·åç鿡件 |
| | | CString selectedType, selectedUser, description; |
| | | m_comboType.GetLBText(m_comboType.GetCurSel(), selectedType); |
| | | m_comboUser.GetLBText(m_comboUser.GetCurSel(), selectedUser); |
| | | m_editDescription.GetWindowText(description); |
| | | |
| | | COleDateTime startTime, endTime; |
| | | m_dateTimeStart.GetTime(startTime); |
| | | m_dateTimeEnd.GetTime(endTime); |
| | | CString strStartTime = startTime.Format(_T("%Y-%m-%d %H:%M:%S")); |
| | | CString strEndTime = endTime.Format(_T("%Y-%m-%d %H:%M:%S")); |
| | | |
| | | std::string type = CT2A(selectedType); |
| | | std::string user = CT2A(selectedUser); |
| | | std::string desc = CT2A(description); |
| | | std::string start = CT2A(strStartTime); |
| | | std::string end = CT2A(strEndTime); |
| | | |
| | | // è·åæ¥å¿ç®¡çå®ä¾ |
| | | SystemLogManager& logManager = SystemLogManager::getInstance(); |
| | | |
| | | int pageSize = 20; // æ¯é¡µæ¾ç¤º 20 æ¡è®°å½ |
| | | int totalRecords = logManager.getTotalLogCount(type, user, desc, start, end); |
| | | m_nTotalPages = (totalRecords + pageSize - 1) / pageSize; |
| | | auto logs = logManager.getFilteredLogs(type, user, desc, start, end, m_nCurrentPage, pageSize); |
| | | |
| | | // æ´æ°è¡¨æ ¼æ°æ® |
| | | int rowIdx = 1; |
| | | for (const auto& log : logs) { |
| | | m_listLogs.SetItemText(rowIdx, 0, CString(std::to_string(rowIdx).c_str())); // åºå· |
| | | m_listLogs.SetItemText(rowIdx, 1, CString(log[1].c_str())); // ç±»å |
| | | m_listLogs.SetItemText(rowIdx, 2, CString(log[2].c_str())); // äºä»¶ |
| | | m_listLogs.SetItemText(rowIdx, 3, CString(log[3].c_str())); // ç¨æ· |
| | | m_listLogs.SetItemText(rowIdx, 4, CString(log[4].c_str())); // æ¶é´ |
| | | ++rowIdx; |
| | | } |
| | | |
| | | // æ¸
空å¤ä½è¡ |
| | | for (; rowIdx <= 20; ++rowIdx) { |
| | | m_listLogs.SetItemText(rowIdx, 0, CString(std::to_string(rowIdx).c_str())); // åºå·å |
| | | for (int colIdx = 1; colIdx < m_listLogs.GetColumnCount(); ++colIdx) { |
| | | m_listLogs.SetItemText(rowIdx, colIdx, _T("")); |
| | | } |
| | | } |
| | | |
| | | m_listLogs.ExpandColumnsToFit(FALSE); |
| | | m_listLogs.ExpandLastColumn(); |
| | | m_listLogs.Invalidate(); |
| | | m_listLogs.UpdateWindow(); |
| | | |
| | | UpdatePageInfo(); |
| | | } |
| | | |
| | | CFont* CSystemLogManagerDlg::GetOrCreateFont(int nFontSize) |
| | | { |
| | | auto it = m_mapFonts.find(nFontSize); |
| | | if (it != m_mapFonts.end()) { |
| | | return it->second; |
| | | } |
| | | |
| | | CFont* font = new CFont(); |
| | | LOGFONT logFont = { 0 }; |
| | | _tcscpy_s(logFont.lfFaceName, _T("Segoe UI")); |
| | | logFont.lfHeight = -nFontSize; |
| | | logFont.lfQuality = CLEARTYPE_QUALITY; |
| | | font->CreateFontIndirect(&logFont); |
| | | m_mapFonts[nFontSize] = font; |
| | | |
| | | return font; |
| | | } |
| | | |
| | | void CSystemLogManagerDlg::UpdatePageInfo() |
| | | { |
| | | // æ ¼å¼å页ç ä¿¡æ¯ä¸º "å½å页/æ»é¡µæ°" |
| | | CString pageInfo; |
| | | pageInfo.Format(_T("%d/%d 页"), m_nCurrentPage, m_nTotalPages); |
| | | m_staticPageNum.SetWindowText(pageInfo); |
| | | } |
| | | |
| | | void CSystemLogManagerDlg::SetDefaultFont() |
| | | { |
| | | CFont* defaultFont = GetOrCreateFont(12); |
| | | |
| | | // éåæææ§ä»¶ï¼åºç¨é»è®¤åä½ |
| | | CWnd* pWnd = GetWindow(GW_CHILD); |
| | | while (pWnd) { |
| | | // è·³è¿ç¹æ®æ§ä»¶ï¼å¦ MFCGridCtrlï¼ |
| | | TCHAR szClassName[256]; |
| | | GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName)); |
| | | if (_tcsicmp(szClassName, _T("MFCGridCtrl")) == 0) { |
| | | pWnd = pWnd->GetNextWindow(); |
| | | continue; |
| | | } |
| | | |
| | | pWnd->SetFont(defaultFont, TRUE); |
| | | pWnd = pWnd->GetNextWindow(); |
| | | } |
| | | } |
| | | |
| | | void CSystemLogManagerDlg::AdjustControls(float dScaleX, float dScaleY) |
| | | { |
| | | CWnd* pWnd = GetWindow(GW_CHILD); |
| | | while (pWnd) { |
| | | int nCtrlID = pWnd->GetDlgCtrlID(); |
| | | if (nCtrlID != -1 && m_mapCtrlLayouts.find(nCtrlID) != m_mapCtrlLayouts.end()) |
| | | { |
| | | CRect originalRect = m_mapCtrlLayouts[nCtrlID]; |
| | | CRect newRect( |
| | | static_cast<int>(originalRect.left * dScaleX), |
| | | static_cast<int>(originalRect.top * dScaleY), |
| | | static_cast<int>(originalRect.right * dScaleX), |
| | | static_cast<int>(originalRect.bottom * dScaleY)); |
| | | |
| | | TCHAR szClassName[256]; |
| | | GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName)); |
| | | |
| | | if (_tcsicmp(szClassName, _T("ComboBox")) == 0) { |
| | | CComboBox* pComboBox = (CComboBox*)pWnd; |
| | | pComboBox->SetItemHeight(-1, newRect.Height()); // -1 表示ææé¡¹çé«åº¦ |
| | | } |
| | | |
| | | if (_tcsicmp(szClassName, _T("MFCGridCtrl")) == 0) { |
| | | CGridCtrl* pGridCtrl = (CGridCtrl*)pWnd; |
| | | pGridCtrl->SetDefCellHeight(newRect.Height() / 21); |
| | | pGridCtrl->ExpandColumnsToFit(TRUE); |
| | | pGridCtrl->ExpandLastColumn(); |
| | | pGridCtrl->Invalidate(); |
| | | pGridCtrl->UpdateWindow(); |
| | | } |
| | | |
| | | pWnd->MoveWindow(&newRect); |
| | | AdjustControlFont(pWnd, newRect.Width(), newRect.Height()); |
| | | } |
| | | pWnd = pWnd->GetNextWindow(); |
| | | } |
| | | } |
| | | |
| | | void CSystemLogManagerDlg::AdjustControlFont(CWnd* pWnd, int nWidth, int nHeight) |
| | | { |
| | | TCHAR szClassName[256]; |
| | | GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName)); |
| | | |
| | | // è·³è¿ç¹æ®æ§ä»¶ï¼å¦ MFCGridCtrlï¼ |
| | | if (_tcsicmp(szClassName, _T("MFCGridCtrl")) == 0) { |
| | | return; |
| | | } |
| | | |
| | | // æ ¹æ®æ§ä»¶é«åº¦å¨æè°æ´åä½å¤§å° |
| | | int fontSize = nHeight / 2; |
| | | if (fontSize < 8) fontSize = 8; |
| | | |
| | | // è·åæå建åä½ |
| | | CFont* pFont = GetOrCreateFont(fontSize); |
| | | |
| | | pWnd->SetFont(pFont); |
| | | pWnd->Invalidate(); // å·æ°æ§ä»¶æ¾ç¤º |
| | | } |
| | | |
| | | |
| | | void CSystemLogManagerDlg::AdjustComboBoxStyle(CComboBox& comboBox) |
| | | { |
| | | DWORD dwStyle = comboBox.GetStyle(); |
| | | comboBox.ModifyStyle(0, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_OWNERDRAWFIXED); |
| | | |
| | | comboBox.Invalidate(); |
| | | comboBox.UpdateWindow(); |
| | | } |
| | | |
| | | |
| | | void CSystemLogManagerDlg::AdjustDateTimeCtrlStyle(CDateTimeCtrl& dateTimeCtrl) |
| | | { |
| | | dateTimeCtrl.ModifyStyle(0, DTS_RIGHTALIGN); |
| | | dateTimeCtrl.Invalidate(); |
| | | dateTimeCtrl.UpdateWindow(); |
| | | } |
| | | |
| | | |
| | | BEGIN_MESSAGE_MAP(CSystemLogManagerDlg, CDialogEx) |
| | | ON_BN_CLICKED(IDC_BUTTON_SEARCH, &CSystemLogManagerDlg::OnBnClickedButtonSearch) |
| | | ON_BN_CLICKED(IDC_BUTTON_PREV_PAGE, &CSystemLogManagerDlg::OnBnClickedButtonPrevPage) |
| | | ON_BN_CLICKED(IDC_BUTTON_NEXT_PAGE, &CSystemLogManagerDlg::OnBnClickedButtonNextPage) |
| | | ON_CBN_SELCHANGE(IDC_COMBO_TYPE, &CSystemLogManagerDlg::OnSelchangeComboType) |
| | | ON_CBN_SELCHANGE(IDC_COMBO_USER, &CSystemLogManagerDlg::OnSelchangeComboUser) |
| | | ON_WM_SIZE() |
| | | ON_WM_GETMINMAXINFO() |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | | // CSystemLogManagerDlg æ¶æ¯å¤çç¨åº |
| | | |
| | | |
| | | BOOL CSystemLogManagerDlg::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | |
| | | // TODO: 卿¤æ·»å é¢å¤çåå§å |
| | | SetWindowText(_T("ç³»ç»è¿è¡æ¥å¿")); |
| | | |
| | | m_nCurrentPage = 1; // ä»ç¬¬ä¸é¡µå¼å§ |
| | | m_nTotalPages = 1; // é»è®¤æ»é¡µæ°ä¸º 1 |
| | | |
| | | m_comboType.AddString(_T("ALL")); |
| | | m_comboType.AddString(_T("ä¿¡æ¯")); |
| | | m_comboType.AddString(_T("æä½")); |
| | | m_comboType.AddString(_T("é误")); |
| | | m_comboType.AddString(_T("æªç¥")); |
| | | m_comboType.SetCurSel(0); |
| | | |
| | | m_comboUser.AddString(_T("ALL")); |
| | | m_comboUser.AddString(_T("SYSTEM")); |
| | | auto usernames = UserManager::getInstance().getUsernames(); |
| | | for (const auto& username : usernames) { |
| | | CString cstrUsername(username.c_str()); |
| | | m_comboUser.AddString(cstrUsername); |
| | | } |
| | | m_comboUser.SetCurSel(0); |
| | | |
| | | // 设置为 30 天å |
| | | COleDateTime currentTime = COleDateTime::GetCurrentTime(); |
| | | COleDateTime defaultStartTime = currentTime - COleDateTimeSpan(30, 0, 0, 0); |
| | | m_dateTimeStart.SetTime(defaultStartTime); |
| | | |
| | | CRect screenRect, dlgRect, clientRect; |
| | | GetClientRect(&clientRect); |
| | | m_nInitialWidth = clientRect.Width(); |
| | | m_nInitialHeight = clientRect.Height(); |
| | | |
| | | // åå§åé»è®¤åä½ |
| | | CFont* pDefaultFont = GetOrCreateFont(12); |
| | | |
| | | // éåææåæ§ä»¶ï¼è®°å½åå§ä½ç½®å¹¶è®¾ç½®é»è®¤åä½ |
| | | CWnd* pWnd = GetWindow(GW_CHILD); |
| | | while (pWnd) { |
| | | int nCtrlID = pWnd->GetDlgCtrlID(); |
| | | if (nCtrlID != -1) { |
| | | // è®°å½æ§ä»¶åå§å¸å± |
| | | CRect ctrlRect; |
| | | pWnd->GetWindowRect(&ctrlRect); |
| | | ScreenToClient(&ctrlRect); |
| | | m_mapCtrlLayouts[nCtrlID] = ctrlRect; |
| | | |
| | | // è·³è¿ç¹æ®æ§ä»¶ï¼å¦ MFCGridCtrlï¼ |
| | | TCHAR szClassName[256]; |
| | | GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName)); |
| | | if (_tcsicmp(szClassName, _T("MFCGridCtrl")) == 0) { |
| | | pWnd = pWnd->GetNextWindow(); |
| | | continue; |
| | | } |
| | | |
| | | // 设置é»è®¤åä½ |
| | | pWnd->SetFont(pDefaultFont); |
| | | } |
| | | pWnd = pWnd->GetNextWindow(); |
| | | } |
| | | |
| | | GetWindowRect(&dlgRect); |
| | | int dlgWidth = dlgRect.Width() * 2; |
| | | int dlgHeight = dlgRect.Height() * 2; |
| | | |
| | | SystemParametersInfo(SPI_GETWORKAREA, 0, &screenRect, 0); |
| | | if (dlgWidth > screenRect.Width()) { |
| | | dlgWidth = screenRect.Width(); |
| | | } |
| | | if (dlgHeight > screenRect.Height()) { |
| | | dlgHeight = screenRect.Height(); |
| | | } |
| | | |
| | | int centerX = screenRect.left + (screenRect.Width() - dlgWidth) / 2; |
| | | int centerY = screenRect.top + (screenRect.Height() - dlgHeight) / 2; |
| | | MoveWindow(centerX, centerY, dlgWidth, dlgHeight); |
| | | |
| | | InitSystemLogManager(); |
| | | |
| | | return TRUE; // return TRUE unless you set the focus to a control |
| | | // å¼å¸¸: OCX 屿§é¡µåºè¿å FALSE |
| | | } |
| | | |
| | | |
| | | void CSystemLogManagerDlg::OnSize(UINT nType, int cx, int cy) |
| | | { |
| | | CDialogEx::OnSize(nType, cx, cy); |
| | | |
| | | // TODO: 卿¤å¤æ·»å æ¶æ¯å¤çç¨åºä»£ç |
| | | if (nType == SIZE_MINIMIZED || m_mapCtrlLayouts.empty()) { |
| | | return; |
| | | } |
| | | |
| | | float dScaleX = static_cast<float>(cx) / m_nInitialWidth; |
| | | float dScaleY = static_cast<float>(cy) / m_nInitialHeight; |
| | | |
| | | // éåå¯¹è¯æ¡ä¸çæææ§ä»¶ |
| | | AdjustControls(dScaleX, dScaleY); |
| | | } |
| | | |
| | | |
| | | void CSystemLogManagerDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI) |
| | | { |
| | | // TODO: 卿¤æ·»å æ¶æ¯å¤çç¨åºä»£ç å/æè°ç¨é»è®¤å¼ |
| | | lpMMI->ptMinTrackSize.x = 400; // æå°å®½åº¦ |
| | | lpMMI->ptMinTrackSize.y = 300; // æå°é«åº¦ |
| | | |
| | | CDialogEx::OnGetMinMaxInfo(lpMMI); |
| | | } |
| | | |
| | | |
| | | void CSystemLogManagerDlg::OnBnClickedButtonSearch() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | try { |
| | | m_nCurrentPage = 1; |
| | | FillSystemLogManager(); |
| | | } |
| | | catch (const std::exception& ex) { |
| | | CString errorMsg; |
| | | errorMsg.Format(_T("æç´¢å¤±è´¥ï¼%s"), CString(ex.what())); |
| | | AfxMessageBox(errorMsg, MB_ICONERROR); |
| | | } |
| | | } |
| | | |
| | | |
| | | void CSystemLogManagerDlg::OnBnClickedButtonPrevPage() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | try { |
| | | if (m_nCurrentPage > 1) { |
| | | m_nCurrentPage--; |
| | | FillSystemLogManager(); |
| | | } |
| | | else { |
| | | AfxMessageBox(_T("å·²ç»æ¯ç¬¬ä¸é¡µï¼")); |
| | | } |
| | | } |
| | | catch (const std::exception& ex) { |
| | | CString errorMsg; |
| | | errorMsg.Format(_T("忢å°ä¸ä¸é¡µå¤±è´¥ï¼%s"), CString(ex.what())); |
| | | AfxMessageBox(errorMsg, MB_ICONERROR); |
| | | } |
| | | } |
| | | |
| | | |
| | | void CSystemLogManagerDlg::OnBnClickedButtonNextPage() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | try { |
| | | if (m_nCurrentPage < m_nTotalPages) { |
| | | m_nCurrentPage++; |
| | | FillSystemLogManager(); |
| | | } |
| | | else { |
| | | AfxMessageBox(_T("å·²ç»æ¯æåä¸é¡µï¼")); |
| | | } |
| | | } |
| | | catch (const std::exception& ex) { |
| | | CString errorMsg; |
| | | errorMsg.Format(_T("忢å°ä¸ä¸é¡µå¤±è´¥ï¼%s"), CString(ex.what())); |
| | | AfxMessageBox(errorMsg, MB_ICONERROR); |
| | | } |
| | | } |
| | | |
| | | |
| | | void CSystemLogManagerDlg::OnSelchangeComboType() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | try { |
| | | m_nCurrentPage = 1; |
| | | FillSystemLogManager(); |
| | | } |
| | | catch (const std::exception& ex) { |
| | | CString errorMsg; |
| | | errorMsg.Format(_T("åæ¢ç±»å失败ï¼%s"), CString(ex.what())); |
| | | AfxMessageBox(errorMsg, MB_ICONERROR); |
| | | } |
| | | } |
| | | |
| | | |
| | | void CSystemLogManagerDlg::OnSelchangeComboUser() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | try { |
| | | m_nCurrentPage = 1; |
| | | FillSystemLogManager(); |
| | | } |
| | | catch (const std::exception& ex) { |
| | | CString errorMsg; |
| | | errorMsg.Format(_T("忢è§è²å¤±è´¥ï¼%s"), CString(ex.what())); |
| | | AfxMessageBox(errorMsg, MB_ICONERROR); |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include "afxdialogex.h" |
| | | #include "GridCtrl.h" |
| | | |
| | | // CSystemLogManagerDlg å¯¹è¯æ¡ |
| | | |
| | | class CSystemLogManagerDlg : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CSystemLogManagerDlg) |
| | | |
| | | public: |
| | | CSystemLogManagerDlg(CWnd* pParent = nullptr); // æ åæé 彿° |
| | | virtual ~CSystemLogManagerDlg(); |
| | | |
| | | // å¯¹è¯æ¡æ°æ® |
| | | #ifdef AFX_DESIGN_TIME |
| | | enum { IDD = IDD_DIALOG_SYSTEM_LOG_MANAGER }; |
| | | #endif |
| | | |
| | | private: |
| | | void InitSystemLogManager(); |
| | | void FillSystemLogManager(); |
| | | CFont* GetOrCreateFont(int nFontSize); |
| | | void UpdatePageInfo(); |
| | | void SetDefaultFont(); |
| | | void AdjustControls(float dScaleX, float dScaleY); |
| | | void AdjustControlFont(CWnd* pWnd, int nWidth, int nHeight); |
| | | void AdjustComboBoxStyle(CComboBox& comboBox); |
| | | void AdjustDateTimeCtrlStyle(CDateTimeCtrl& dateTimeCtrl); |
| | | |
| | | private: |
| | | int m_nInitialWidth; // åå§å®½åº¦ |
| | | int m_nInitialHeight; // åå§é«åº¦ |
| | | int m_nCurrentPage; // å½å页ç |
| | | int m_nTotalPages; // æ»é¡µæ° |
| | | std::map<int, CRect> m_mapCtrlLayouts; // å卿§ä»¶çåå§å¸å±ä¿¡æ¯ |
| | | std::map<int, CFont*> m_mapFonts; // 管çåä½ç容å¨ï¼é®ä¸ºåä½å¤§å° |
| | | |
| | | private: |
| | | CComboBox m_comboType; |
| | | CComboBox m_comboUser; |
| | | CDateTimeCtrl m_dateTimeStart; |
| | | CDateTimeCtrl m_dateTimeEnd; |
| | | CEdit m_editDescription; |
| | | CGridCtrl m_listLogs; |
| | | CStatic m_staticPageNum; |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV æ¯æ |
| | | |
| | | DECLARE_MESSAGE_MAP() |
| | | public: |
| | | virtual BOOL OnInitDialog(); |
| | | afx_msg void OnSize(UINT nType, int cx, int cy); |
| | | afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI); |
| | | afx_msg void OnBnClickedButtonSearch(); |
| | | afx_msg void OnBnClickedButtonPrevPage(); |
| | | afx_msg void OnBnClickedButtonNextPage(); |
| | | afx_msg void OnSelchangeComboType(); |
| | | afx_msg void OnSelchangeComboUser(); |
| | | }; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // UserManagerDlg.cpp: å®ç°æä»¶ |
| | | // |
| | | |
| | | #include "stdafx.h" |
| | | #include "BondEq.h" |
| | | #include "afxdialogex.h" |
| | | #include "UserManagerDlg.h" |
| | | #include "InputDialog.h" |
| | | #include "NewCellTypes/GridCellCombo.h" |
| | | #include "NewCellTypes/GridCellNumeric.h" |
| | | |
| | | #include <set> |
| | | |
| | | const COLORREF CURR_USER_BK_COLOR = RGB(0, 255, 0); |
| | | |
| | | // CUserManagerDlg å¯¹è¯æ¡ |
| | | |
| | | IMPLEMENT_DYNAMIC(CUserManagerDlg, CDialogEx) |
| | | |
| | | CUserManagerDlg::CUserManagerDlg(CWnd* pParent /*=nullptr*/) |
| | | : CDialogEx(IDD_DIALOG_USER_MANAGER, pParent) |
| | | { |
| | | m_nInitialWidth = 0; |
| | | m_nInitialHeight = 0; |
| | | } |
| | | |
| | | CUserManagerDlg::~CUserManagerDlg() |
| | | { |
| | | for (auto& pair : m_mapFonts) { |
| | | if (pair.second) { |
| | | pair.second->DeleteObject(); |
| | | delete pair.second; |
| | | } |
| | | } |
| | | m_mapFonts.clear(); |
| | | } |
| | | |
| | | void CUserManagerDlg::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | DDX_Control(pDX, IDC_CUSTOM_USER, m_gridUserManager); |
| | | CDialogEx::DoDataExchange(pDX); |
| | | } |
| | | |
| | | void CUserManagerDlg::InitUserManager() |
| | | { |
| | | if (m_gridUserManager.GetSafeHwnd() == NULL) |
| | | return; |
| | | |
| | | int nRows = 1; |
| | | int nCols = 8; |
| | | |
| | | int nFixRows = 1; |
| | | int nFixCols = 0; |
| | | int nRowIdx = 0; |
| | | int nColIdx = 0; |
| | | |
| | | m_gridUserManager.DeleteAllItems(); |
| | | m_gridUserManager.SetVirtualMode(FALSE); |
| | | m_gridUserManager.GetDefaultCell(TRUE, FALSE)->SetBackClr(g_nGridFixCellColor); // 设置åºå®è¡èæ¯è² |
| | | m_gridUserManager.GetDefaultCell(FALSE, TRUE)->SetBackClr(g_nGridFixCellColor); // 设置åºå®åèæ¯è² |
| | | m_gridUserManager.GetDefaultCell(FALSE, FALSE)->SetBackClr(g_nGridCellColor); // 设置åå
æ ¼èæ¯è² |
| | | m_gridUserManager.SetFixedTextColor(g_nGridFixFontColor); // 设置åºå®è¡ååä½é¢è² |
| | | |
| | | m_gridUserManager.SetRowCount(nRows); |
| | | m_gridUserManager.SetColumnCount(nCols); |
| | | m_gridUserManager.SetFixedRowCount(nFixRows); |
| | | m_gridUserManager.SetFixedColumnCount(nFixCols); |
| | | |
| | | // Col |
| | | m_gridUserManager.SetColumnWidth(nColIdx, 20); |
| | | m_gridUserManager.SetItemText(nRowIdx, nColIdx++, _T("No.")); |
| | | m_gridUserManager.SetColumnWidth(nColIdx, 70); |
| | | m_gridUserManager.SetItemText(nRowIdx, nColIdx++, _T("ç¨æ·å")); |
| | | m_gridUserManager.SetColumnWidth(nColIdx, 70); |
| | | m_gridUserManager.SetItemText(nRowIdx, nColIdx++, _T("å¯ç ")); |
| | | m_gridUserManager.SetColumnWidth(nColIdx, 70); |
| | | m_gridUserManager.SetItemText(nRowIdx, nColIdx++, _T("æé")); |
| | | m_gridUserManager.SetColumnWidth(nColIdx, 70); |
| | | m_gridUserManager.SetItemText(nRowIdx, nColIdx++, _T("ä¼è¯è¶
æ¶ï¼åéï¼")); |
| | | m_gridUserManager.SetColumnWidth(nColIdx, 70); |
| | | m_gridUserManager.SetItemText(nRowIdx, nColIdx++, _T("ä¼è¯è¿æï¼å°æ¶ï¼")); |
| | | m_gridUserManager.SetColumnWidth(nColIdx, 70); |
| | | m_gridUserManager.SetItemText(nRowIdx, nColIdx++, _T("æå䏿¬¡ç»å½æ¶é´")); |
| | | m_gridUserManager.SetColumnWidth(nColIdx, 100); |
| | | m_gridUserManager.SetItemText(nRowIdx, nColIdx++, _T("è§è²æè¿°")); |
| | | |
| | | m_gridUserManager.SetFixedRowSelection(FALSE); |
| | | m_gridUserManager.SetFixedColumnSelection(FALSE); |
| | | m_gridUserManager.SetEditable(TRUE); |
| | | m_gridUserManager.SetRowResize(FALSE); |
| | | m_gridUserManager.SetColumnResize(TRUE); |
| | | m_gridUserManager.ExpandColumnsToFit(TRUE); |
| | | m_gridUserManager.SetListMode(TRUE); // å¯ç¨åè¡¨æ¨¡å¼ |
| | | m_gridUserManager.EnableSelection(TRUE); // å¯ç¨éæ© |
| | | m_gridUserManager.SetSingleRowSelection(TRUE); // èªå¨æ´è¡é«äº®ï¼éå¶ä¸ºåè¡éæ©ï¼ |
| | | m_gridUserManager.ExpandLastColumn(); // æåä¸åå¡«å
ç½æ ¼ |
| | | |
| | | m_mapRoleDescriptions.clear(); |
| | | m_mapRoleDescriptions.emplace(_T("管çå"), _T("ç®¡çææç¨æ·ï¼åé
æé")); |
| | | m_mapRoleDescriptions.emplace(_T("å·¥ç¨å¸"), _T("ç»´æ¤ç³»ç»ï¼è§£å³ææ¯é®é¢")); |
| | | m_mapRoleDescriptions.emplace(_T("æä½å"), _T("æ§è¡æ¥å¸¸æä½ä»»å¡")); |
| | | |
| | | FillUserManager(); |
| | | } |
| | | |
| | | void CUserManagerDlg::FillUserManager() |
| | | { |
| | | UserManager& userManager = UserManager::getInstance(); |
| | | if (!userManager.isLoggedIn()) { |
| | | AfxMessageBox(_T("æªç»å½")); |
| | | return; |
| | | } |
| | | |
| | | if (userManager.getCurrentUserRole() != UserRole::SuperAdmin) { |
| | | AfxMessageBox(_T("é管çåç¨æ·")); |
| | | return; |
| | | } |
| | | |
| | | int nCurrNameRow = -1; |
| | | std::vector<std::vector<std::string>> usersData = userManager.getUsers(); |
| | | if (!usersData.empty()) { |
| | | m_gridUserManager.SetRowCount(usersData.size() + 1); |
| | | |
| | | for (int i = 0; i < usersData.size(); i++) { |
| | | int nRowIdx = i + 1; |
| | | int nColIdx = 0; |
| | | |
| | | m_gridUserManager.SetItemText(nRowIdx, nColIdx++, std::to_string(i + 1).c_str()); |
| | | for (int j = 0; j < usersData[i].size(); j++) { |
| | | if (usersData[i][1].empty()) { |
| | | continue; |
| | | } |
| | | m_gridUserManager.SetItemText(nRowIdx, nColIdx++, usersData[i][j].c_str()); |
| | | } |
| | | |
| | | // å½åç»å½ç¨æ·é«äº® |
| | | if (nCurrNameRow == -1 && usersData[i][0] == userManager.getCurrentUser()) { |
| | | nCurrNameRow = nRowIdx; |
| | | } |
| | | } |
| | | } |
| | | |
| | | CStringArray permissions; |
| | | permissions.Add(_T("管çå")); |
| | | permissions.Add(_T("å·¥ç¨å¸")); |
| | | permissions.Add(_T("æä½å")); |
| | | |
| | | int nCols = m_gridUserManager.GetColumnCount(); |
| | | for (int i = 1; i < m_gridUserManager.GetRowCount(); ++i) { |
| | | m_gridUserManager.SetItemState(i, 0, GVIS_READONLY); // 第ä¸ååªè¯» |
| | | m_gridUserManager.SetItemState(i, nCols - 2, GVIS_READONLY); // åæ°ç¬¬äºååªè¯» |
| | | m_gridUserManager.SetItemState(i, nCols - 1, GVIS_READONLY); // æåä¸ååªè¯» |
| | | |
| | | // 第åå设置æéåä¸ºä¸ææ¡ |
| | | if (m_gridUserManager.SetCellType(i, 3, RUNTIME_CLASS(CGridCellCombo))) { |
| | | CGridCellCombo* pCell = static_cast<CGridCellCombo*>(m_gridUserManager.GetCell(i, 3)); |
| | | pCell->SetOptions(permissions); |
| | | pCell->SetStyle(CBS_DROPDOWNLIST); |
| | | |
| | | CString cstrRole = m_gridUserManager.GetItemText(i, 3); |
| | | int nRole = _ttoi(cstrRole); |
| | | if (nRole < 0 || nRole > 2) { |
| | | CString cstrMessage; |
| | | cstrMessage.Format(_T("ç¨æ· [%s]ï¼æéå¼å¸¸ï¼å°è®¾ç½®ææä½åï¼"), m_gridUserManager.GetItemText(i, 1)); |
| | | AfxMessageBox(cstrMessage); |
| | | nRole = 2; |
| | | } |
| | | |
| | | m_gridUserManager.SetItemText(i, 3, permissions.GetAt(nRole)); |
| | | |
| | | auto it = m_mapRoleDescriptions.find(permissions.GetAt(nRole)); |
| | | if (it != m_mapRoleDescriptions.end()) { |
| | | m_gridUserManager.SetItemText(i, 7, it->second); |
| | | } |
| | | } |
| | | |
| | | // 第äºãå
åï¼ä¼è¯è¶
æ¶ï¼è®¾ç½®ä¸ºNumeric |
| | | //m_gridUserManager.SetCellType(i, 4, RUNTIME_CLASS(CGridCellNumeric)); |
| | | //m_gridUserManager.SetCellType(i, 5, RUNTIME_CLASS(CGridCellNumeric)); |
| | | m_gridUserManager.SetItemState(i, 4, GVIS_READONLY); // 第äºååªè¯» |
| | | m_gridUserManager.SetItemState(i, 5, GVIS_READONLY); // 第å
ååªè¯» |
| | | |
| | | m_gridUserManager.ExpandColumnsToFit(FALSE); |
| | | m_gridUserManager.ExpandLastColumn(); |
| | | } |
| | | |
| | | for (int i = 0; i < nCols; i++) { |
| | | m_gridUserManager.SetItemBkColour(nCurrNameRow, i, CURR_USER_BK_COLOR); |
| | | } |
| | | m_gridUserManager.SetItemState(nCurrNameRow, 3, GVIS_READONLY); |
| | | |
| | | m_gridUserManager.Invalidate(); |
| | | m_gridUserManager.UpdateWindow(); |
| | | } |
| | | |
| | | void CUserManagerDlg::AddRow(CGridCtrl* pGridCtrl) |
| | | { |
| | | if (!pGridCtrl) return; |
| | | |
| | | if (pGridCtrl->GetRowCount() <= 0 || pGridCtrl->GetColumnCount() <= 0) { |
| | | AfxMessageBox(_T("ç½æ ¼æ§ä»¶æªæ£ç¡®åå§åï¼è¯·æ£æ¥åå§åé»è¾ï¼")); |
| | | return; |
| | | } |
| | | |
| | | CInputDialog inputDialog(_T("æ·»å ç¨æ·"), _T("请è¾å
¥ç¨æ·åï¼")); |
| | | if (inputDialog.DoModal() != IDOK) { |
| | | return; |
| | | } |
| | | |
| | | CString inputText = inputDialog.GetInputText(); |
| | | if (inputText.IsEmpty()) { |
| | | AfxMessageBox(_T("ç¨æ·åä¸è½ä¸ºç©ºï¼")); |
| | | return; |
| | | } |
| | | |
| | | if (IsUsernameDuplicate(inputText)) { |
| | | AfxMessageBox(_T("ç¨æ·åéå¤ï¼")); |
| | | return; |
| | | } |
| | | |
| | | int nRowCount = pGridCtrl->GetRowCount(); |
| | | pGridCtrl->SetRowCount(nRowCount + 1); |
| | | int newRowIndex = nRowCount; |
| | | |
| | | CString strText; |
| | | strText.Format(_T("%d"), newRowIndex); |
| | | pGridCtrl->SetItemText(newRowIndex, 0, strText); |
| | | pGridCtrl->SetItemText(newRowIndex, 1, inputText); |
| | | pGridCtrl->SetItemText(newRowIndex, 2, _T("123456")); |
| | | pGridCtrl->SetItemText(newRowIndex, 3, _T("æä½å")); |
| | | pGridCtrl->SetItemText(newRowIndex, 4, _T("30")); |
| | | pGridCtrl->SetItemText(newRowIndex, 5, _T("72")); |
| | | pGridCtrl->SetItemText(newRowIndex, 6, _T("2024-01-01 00:00:00")); |
| | | |
| | | auto it = m_mapRoleDescriptions.find(_T("æä½å")); |
| | | if (it != m_mapRoleDescriptions.end()) { |
| | | pGridCtrl->SetItemText(newRowIndex, 7, it->second); |
| | | } |
| | | |
| | | int nCols = pGridCtrl->GetColumnCount(); |
| | | pGridCtrl->SetItemState(newRowIndex, 0, GVIS_READONLY); // 第ä¸ååªè¯» |
| | | pGridCtrl->SetItemState(newRowIndex, nCols - 2, GVIS_READONLY); // åæ°ç¬¬äºååªè¯» |
| | | pGridCtrl->SetItemState(newRowIndex, nCols - 1, GVIS_READONLY); // æåä¸ååªè¯» |
| | | |
| | | // 第ååè®¾ç½®ï¼æéåï¼ä¸ºä¸ææ¡ |
| | | CStringArray permissions; |
| | | permissions.Add(_T("管çå")); |
| | | permissions.Add(_T("å·¥ç¨å¸")); |
| | | permissions.Add(_T("æä½å")); |
| | | |
| | | if (pGridCtrl->SetCellType(newRowIndex, 3, RUNTIME_CLASS(CGridCellCombo))) { |
| | | CGridCellCombo* pCell = static_cast<CGridCellCombo*>(pGridCtrl->GetCell(newRowIndex, 3)); |
| | | pCell->SetOptions(permissions); |
| | | pCell->SetStyle(CBS_DROPDOWNLIST); |
| | | |
| | | pGridCtrl->SetItemText(newRowIndex, 3, permissions.GetAt(2)); |
| | | } |
| | | |
| | | // 第äºãå
åï¼ä¼è¯è¶
æ¶ï¼è®¾ç½®ä¸ºNumeric |
| | | //pGridCtrl->SetCellType(newRowIndex, 4, RUNTIME_CLASS(CGridCellNumeric)); |
| | | //pGridCtrl->SetCellType(newRowIndex, 5, RUNTIME_CLASS(CGridCellNumeric)); |
| | | pGridCtrl->SetItemState(newRowIndex, 4, GVIS_READONLY); // 第äºååªè¯» |
| | | pGridCtrl->SetItemState(newRowIndex, 5, GVIS_READONLY); // 第å
ååªè¯» |
| | | |
| | | pGridCtrl->ExpandColumnsToFit(FALSE); |
| | | pGridCtrl->ExpandLastColumn(); |
| | | pGridCtrl->Invalidate(); |
| | | pGridCtrl->UpdateWindow(); |
| | | |
| | | CString cstrMessage; |
| | | cstrMessage.Format(_T("颿·»å ç¨æ· [%s]ï¼"), inputText); |
| | | std::string strMessage = CT2A(cstrMessage); |
| | | SystemLogManager::getInstance().log(SystemLogManager::LogType::Operation, strMessage); |
| | | } |
| | | |
| | | void CUserManagerDlg::DeleteSelectedRow(CGridCtrl* pGridCtrl) |
| | | { |
| | | if (!pGridCtrl) return; |
| | | CCellRange selectedRange = pGridCtrl->GetSelectedCellRange(); |
| | | if (selectedRange.IsValid()) { |
| | | CString currentUser = UserManager::getInstance().getCurrentUser().c_str(); |
| | | std::vector<int> rowsToDelete; |
| | | |
| | | for (int row = selectedRange.GetMinRow(); row <= selectedRange.GetMaxRow(); ++row) { |
| | | BOOL isRowSelected = FALSE; |
| | | for (int col = selectedRange.GetMinCol(); col <= selectedRange.GetMaxCol(); ++col) { |
| | | if (pGridCtrl->IsCellSelected(row, col)) { |
| | | isRowSelected = TRUE; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (!isRowSelected) { |
| | | continue; |
| | | } |
| | | |
| | | CString selectedUser = pGridCtrl->GetItemText(row, 1); |
| | | if (selectedUser == currentUser) { |
| | | CString message; |
| | | message.Format(_T("ç¨æ· [%s] æ¯å½åç»å½ç¨æ·ï¼ä¸è½å é¤ï¼"), currentUser); |
| | | AfxMessageBox(message); |
| | | return; |
| | | } |
| | | |
| | | rowsToDelete.push_back(row); |
| | | } |
| | | |
| | | if (rowsToDelete.empty()) { |
| | | AfxMessageBox(_T("请å
éæ©è¦å é¤çè¡ï¼")); |
| | | return; |
| | | } |
| | | |
| | | CString message; |
| | | if (rowsToDelete.size() == 1) { |
| | | CString selectedUser = pGridCtrl->GetItemText(rowsToDelete[0], 1); |
| | | message.Format(_T("ç¡®å®è¦å é¤éä¸ç¨æ· [%s] åï¼"), selectedUser); |
| | | |
| | | CString cstrMessage; |
| | | cstrMessage.Format(_T("é¢å é¤ç¨æ· [%s]ï¼"), selectedUser); |
| | | std::string strMessage = CT2A(cstrMessage); |
| | | SystemLogManager::getInstance().log(SystemLogManager::LogType::Operation, strMessage); |
| | | } |
| | | else { |
| | | message.Format(_T("ç¡®å®è¦å é¤éä¸ç %d ä¸ªç¨æ·åï¼"), rowsToDelete.size()); |
| | | } |
| | | |
| | | if (AfxMessageBox(message, MB_YESNO | MB_ICONQUESTION) == IDYES) { |
| | | for (auto it = rowsToDelete.rbegin(); it != rowsToDelete.rend(); ++it) { |
| | | pGridCtrl->DeleteRow(*it); |
| | | } |
| | | |
| | | pGridCtrl->ExpandColumnsToFit(FALSE); |
| | | pGridCtrl->ExpandLastColumn(); |
| | | pGridCtrl->Invalidate(); |
| | | pGridCtrl->UpdateWindow(); |
| | | } |
| | | } |
| | | else { |
| | | AfxMessageBox(_T("请å
éæ©è¦å é¤çç¨æ·ï¼")); |
| | | } |
| | | } |
| | | |
| | | bool CUserManagerDlg::IsUsernameDuplicate(const CString& username) |
| | | { |
| | | for (int row = 1; row < m_gridUserManager.GetRowCount(); ++row) { |
| | | if (m_gridUserManager.GetItemText(row, 1) == username) { |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | CFont* CUserManagerDlg::GetOrCreateFont(int nFontSize) |
| | | { |
| | | auto it = m_mapFonts.find(nFontSize); |
| | | if (it != m_mapFonts.end()) { |
| | | return it->second; |
| | | } |
| | | |
| | | CFont* font = new CFont(); |
| | | LOGFONT logFont = { 0 }; |
| | | _tcscpy_s(logFont.lfFaceName, _T("Segoe UI")); |
| | | logFont.lfHeight = -nFontSize; |
| | | logFont.lfQuality = CLEARTYPE_QUALITY; |
| | | font->CreateFontIndirect(&logFont); |
| | | m_mapFonts[nFontSize] = font; |
| | | |
| | | return font; |
| | | } |
| | | |
| | | void CUserManagerDlg::SetDefaultFont() |
| | | { |
| | | CFont* defaultFont = GetOrCreateFont(12); |
| | | |
| | | // éåæææ§ä»¶ï¼åºç¨é»è®¤åä½ |
| | | CWnd* pWnd = GetWindow(GW_CHILD); |
| | | while (pWnd) { |
| | | // è·³è¿ç¹æ®æ§ä»¶ï¼å¦ MFCGridCtrlï¼ |
| | | TCHAR szClassName[256]; |
| | | GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName)); |
| | | if (_tcsicmp(szClassName, _T("MFCGridCtrl")) == 0) { |
| | | pWnd = pWnd->GetNextWindow(); |
| | | continue; |
| | | } |
| | | |
| | | pWnd->SetFont(defaultFont, TRUE); |
| | | pWnd = pWnd->GetNextWindow(); |
| | | } |
| | | } |
| | | |
| | | void CUserManagerDlg::AdjustControls(float dScaleX, float dScaleY) |
| | | { |
| | | CWnd* pWnd = GetWindow(GW_CHILD); |
| | | while (pWnd) { |
| | | int nCtrlID = pWnd->GetDlgCtrlID(); |
| | | if (nCtrlID != -1 && m_mapCtrlLayouts.find(nCtrlID) != m_mapCtrlLayouts.end()) |
| | | { |
| | | CRect originalRect = m_mapCtrlLayouts[nCtrlID]; |
| | | CRect newRect( |
| | | static_cast<int>(originalRect.left * dScaleX), |
| | | static_cast<int>(originalRect.top * dScaleY), |
| | | static_cast<int>(originalRect.right * dScaleX), |
| | | static_cast<int>(originalRect.bottom * dScaleY)); |
| | | |
| | | TCHAR szClassName[256]; |
| | | GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName)); |
| | | |
| | | if (_tcsicmp(szClassName, _T("ComboBox")) == 0) { |
| | | CComboBox* pComboBox = (CComboBox*)pWnd; |
| | | pComboBox->SetItemHeight(-1, newRect.Height()); // -1 表示ææé¡¹çé«åº¦ |
| | | } |
| | | |
| | | if (_tcsicmp(szClassName, _T("MFCGridCtrl")) == 0) { |
| | | CGridCtrl* pGridCtrl = (CGridCtrl*)pWnd; |
| | | pGridCtrl->SetDefCellHeight(newRect.Height() / 21); |
| | | pGridCtrl->ExpandColumnsToFit(TRUE); |
| | | pGridCtrl->ExpandLastColumn(); |
| | | pGridCtrl->Invalidate(); |
| | | pGridCtrl->UpdateWindow(); |
| | | } |
| | | |
| | | pWnd->MoveWindow(&newRect); |
| | | AdjustControlFont(pWnd, newRect.Width(), newRect.Height()); |
| | | } |
| | | pWnd = pWnd->GetNextWindow(); |
| | | } |
| | | } |
| | | |
| | | void CUserManagerDlg::AdjustControlFont(CWnd* pWnd, int nWidth, int nHeight) |
| | | { |
| | | TCHAR szClassName[256]; |
| | | GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName)); |
| | | |
| | | // è·³è¿ç¹æ®æ§ä»¶ï¼å¦ MFCGridCtrlï¼ |
| | | if (_tcsicmp(szClassName, _T("MFCGridCtrl")) == 0) { |
| | | return; |
| | | } |
| | | |
| | | // æ ¹æ®æ§ä»¶é«åº¦å¨æè°æ´åä½å¤§å° |
| | | int fontSize = nHeight / 2; |
| | | if (fontSize < 8) fontSize = 8; |
| | | |
| | | // è·åæå建åä½ |
| | | CFont* pFont = GetOrCreateFont(fontSize); |
| | | |
| | | pWnd->SetFont(pFont); |
| | | pWnd->Invalidate(); // å·æ°æ§ä»¶æ¾ç¤º |
| | | } |
| | | |
| | | BEGIN_MESSAGE_MAP(CUserManagerDlg, CDialogEx) |
| | | ON_WM_SIZE() |
| | | ON_NOTIFY(GVN_COMBOSELCHANGE, IDC_CUSTOM_USER, &CUserManagerDlg::OnGridComboSelChange) |
| | | ON_BN_CLICKED(IDC_BUTTON_ADD, &CUserManagerDlg::OnBnClickedButtonAdd) |
| | | ON_BN_CLICKED(IDC_BUTTON_DEL, &CUserManagerDlg::OnBnClickedButtonDel) |
| | | ON_BN_CLICKED(IDOK, &CUserManagerDlg::OnBnClickedOk) |
| | | ON_BN_CLICKED(IDC_BUTTON_INSERT, &CUserManagerDlg::OnBnClickedButtonInsert) |
| | | ON_WM_GETMINMAXINFO() |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | | // CUserManagerDlg æ¶æ¯å¤çç¨åº |
| | | |
| | | |
| | | BOOL CUserManagerDlg::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | |
| | | // TODO: 卿¤æ·»å é¢å¤çåå§å |
| | | CRect screenRect, dlgRect, clientRect; |
| | | SetWindowText(_T("ç¨æ·ç®¡ç")); |
| | | SystemParametersInfo(SPI_GETWORKAREA, 0, &screenRect, 0); |
| | | |
| | | GetClientRect(&clientRect); |
| | | m_nInitialWidth = clientRect.Width(); |
| | | m_nInitialHeight = clientRect.Height(); |
| | | |
| | | // åå§åé»è®¤åä½ |
| | | CFont* pDefaultFont = GetOrCreateFont(12); |
| | | |
| | | // éåææåæ§ä»¶ï¼è®°å½åå§ä½ç½®å¹¶è®¾ç½®é»è®¤åä½ |
| | | CWnd* pWnd = GetWindow(GW_CHILD); |
| | | while (pWnd) { |
| | | int nCtrlID = pWnd->GetDlgCtrlID(); |
| | | if (nCtrlID != -1) { |
| | | // è®°å½æ§ä»¶åå§å¸å± |
| | | CRect ctrlRect; |
| | | pWnd->GetWindowRect(&ctrlRect); |
| | | ScreenToClient(&ctrlRect); |
| | | m_mapCtrlLayouts[nCtrlID] = ctrlRect; |
| | | |
| | | // è·³è¿ç¹æ®æ§ä»¶ï¼å¦ MFCGridCtrlï¼ |
| | | TCHAR szClassName[256]; |
| | | GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName)); |
| | | if (_tcsicmp(szClassName, _T("MFCGridCtrl")) == 0) { |
| | | pWnd = pWnd->GetNextWindow(); |
| | | continue; |
| | | } |
| | | |
| | | // 设置é»è®¤åä½ |
| | | pWnd->SetFont(pDefaultFont); |
| | | } |
| | | pWnd = pWnd->GetNextWindow(); |
| | | } |
| | | |
| | | GetWindowRect(&dlgRect); |
| | | int dlgWidth = dlgRect.Width() * 3; |
| | | int dlgHeight = dlgRect.Height() * 3; |
| | | |
| | | if (dlgWidth > screenRect.Width()) { |
| | | dlgWidth = screenRect.Width(); |
| | | } |
| | | if (dlgHeight > screenRect.Height()) { |
| | | dlgHeight = screenRect.Height(); |
| | | } |
| | | |
| | | int centerX = screenRect.left + (screenRect.Width() - dlgWidth) / 2; |
| | | int centerY = screenRect.top + (screenRect.Height() - dlgHeight) / 2; |
| | | MoveWindow(centerX, centerY, dlgWidth, dlgHeight); |
| | | |
| | | // åå§åç¨æ·ç®¡çè¡¨æ ¼ |
| | | InitUserManager(); |
| | | |
| | | return TRUE; // return TRUE unless you set the focus to a control |
| | | // å¼å¸¸: OCX 屿§é¡µåºè¿å FALSE |
| | | } |
| | | |
| | | |
| | | void CUserManagerDlg::OnSize(UINT nType, int cx, int cy) |
| | | { |
| | | CDialogEx::OnSize(nType, cx, cy); |
| | | |
| | | // TODO: 卿¤å¤æ·»å æ¶æ¯å¤çç¨åºä»£ç |
| | | if (nType == SIZE_MINIMIZED || m_mapCtrlLayouts.empty()) { |
| | | return; |
| | | } |
| | | |
| | | float dScaleX = static_cast<float>(cx) / m_nInitialWidth; |
| | | float dScaleY = static_cast<float>(cy) / m_nInitialHeight; |
| | | |
| | | // éåå¯¹è¯æ¡ä¸çæææ§ä»¶ |
| | | AdjustControls(dScaleX, dScaleY); |
| | | } |
| | | |
| | | |
| | | void CUserManagerDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI) |
| | | { |
| | | // TODO: 卿¤æ·»å æ¶æ¯å¤çç¨åºä»£ç å/æè°ç¨é»è®¤å¼ |
| | | lpMMI->ptMinTrackSize.x = 400; // æå°å®½åº¦ |
| | | lpMMI->ptMinTrackSize.y = 300; // æå°é«åº¦ |
| | | |
| | | CDialogEx::OnGetMinMaxInfo(lpMMI); |
| | | } |
| | | |
| | | |
| | | void CUserManagerDlg::OnGridComboSelChange(NMHDR* pNMHDR, LRESULT* pResult) |
| | | { |
| | | NM_GRIDVIEW* pItem = (NM_GRIDVIEW*)pNMHDR; |
| | | |
| | | int nRow = pItem->iRow; |
| | | int nCol = pItem->iColumn; |
| | | |
| | | // 第4å为æéå, 第8å为è§è²æè¿°å, 仿 å°ä¸æ¥æ¾å¯¹åºæè¿° |
| | | if (nCol == 3) { |
| | | if (m_gridUserManager.GetItemBkColour(nRow, nCol) == CURR_USER_BK_COLOR) { |
| | | AfxMessageBox(_T("å½åç»å½ç¨æ·æéä¸è½ä¿®æ¹ï¼")); |
| | | } |
| | | else { |
| | | CString selectedRole = m_gridUserManager.GetItemText(nRow, nCol); |
| | | auto it = m_mapRoleDescriptions.find(selectedRole); |
| | | if (it != m_mapRoleDescriptions.end()) { |
| | | m_gridUserManager.SetItemText(nRow, 7, it->second); |
| | | m_gridUserManager.RedrawCell(nRow, 7); |
| | | } |
| | | else { |
| | | m_gridUserManager.SetItemText(nRow, 7, _T("")); |
| | | m_gridUserManager.RedrawCell(nRow, 7); |
| | | } |
| | | } |
| | | } |
| | | |
| | | *pResult = 0; |
| | | } |
| | | |
| | | |
| | | void CUserManagerDlg::OnBnClickedButtonAdd() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | AddRow(&m_gridUserManager); |
| | | } |
| | | |
| | | |
| | | void CUserManagerDlg::OnBnClickedButtonInsert() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | if (!m_gridUserManager.GetSafeHwnd()) return; |
| | | |
| | | CCellRange selectedRange = m_gridUserManager.GetSelectedCellRange(); |
| | | if (!selectedRange.IsValid()) { |
| | | AfxMessageBox(_T("请å
éæ©è¦æå
¥çä½ç½®ï¼")); |
| | | return; |
| | | } |
| | | |
| | | int minRow = selectedRange.GetMinRow(); |
| | | int maxRow = selectedRange.GetMaxRow(); |
| | | if (minRow < 1) { |
| | | AfxMessageBox(_T("è¯·éæ©ææçè¡ï¼")); |
| | | return; |
| | | } |
| | | |
| | | for (int row = maxRow; row >= minRow; --row) { |
| | | std::vector<CString> rowData; |
| | | for (int col = 0; col < m_gridUserManager.GetColumnCount(); ++col) { |
| | | rowData.push_back(m_gridUserManager.GetItemText(row, col)); |
| | | } |
| | | |
| | | m_gridUserManager.InsertRow(_T("æ°ç¨æ·"), row); |
| | | CString newUsername = rowData[1]; |
| | | int suffix = 1; |
| | | while (IsUsernameDuplicate(newUsername)) { |
| | | newUsername.Format(_T("%s_%d"), rowData[1], suffix++); |
| | | } |
| | | rowData[1] = newUsername; |
| | | |
| | | for (int col = 0; col < m_gridUserManager.GetColumnCount(); ++col) { |
| | | m_gridUserManager.SetItemText(row, col, rowData[col]); |
| | | } |
| | | |
| | | CStringArray permissions; |
| | | permissions.Add(_T("管çå")); |
| | | permissions.Add(_T("å·¥ç¨å¸")); |
| | | permissions.Add(_T("æä½å")); |
| | | |
| | | if (m_gridUserManager.SetCellType(row, 3, RUNTIME_CLASS(CGridCellCombo))) { |
| | | CGridCellCombo* pCell = static_cast<CGridCellCombo*>(m_gridUserManager.GetCell(row, 3)); |
| | | pCell->SetOptions(permissions); |
| | | pCell->SetStyle(CBS_DROPDOWNLIST); |
| | | |
| | | m_gridUserManager.SetItemText(row, 3, rowData[3]); |
| | | } |
| | | |
| | | m_gridUserManager.SetCellType(row, 4, RUNTIME_CLASS(CGridCellNumeric)); |
| | | m_gridUserManager.SetCellType(row, 5, RUNTIME_CLASS(CGridCellNumeric)); |
| | | } |
| | | |
| | | for (int row = 1; row < m_gridUserManager.GetRowCount(); ++row) { |
| | | CString strIndex; |
| | | strIndex.Format(_T("%d"), row); |
| | | m_gridUserManager.SetItemText(row, 0, strIndex); |
| | | } |
| | | |
| | | m_gridUserManager.Invalidate(); |
| | | m_gridUserManager.UpdateWindow(); |
| | | } |
| | | |
| | | |
| | | void CUserManagerDlg::OnBnClickedButtonDel() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | DeleteSelectedRow(&m_gridUserManager); |
| | | } |
| | | |
| | | |
| | | void CUserManagerDlg::OnBnClickedOk() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | std::vector<std::vector<std::string>> vecData; |
| | | std::set<std::string> usernameSet; // ç¨äºåå¨ç¨æ·åï¼æ£æ¥æ¯å¦éå¤ |
| | | |
| | | int nCurrUserRow = -1; |
| | | UserManager& userManager = UserManager::getInstance(); |
| | | for (int i = 1; i < m_gridUserManager.GetRowCount(); ++i) { |
| | | std::vector<std::string> rowData; |
| | | CString cellText = m_gridUserManager.GetItemText(i, 1); |
| | | std::string username = CT2A(cellText.GetString()); |
| | | |
| | | cellText = m_gridUserManager.GetItemText(i, 2); |
| | | std::string userpass = CT2A(cellText.GetString()); |
| | | |
| | | if (username.empty() || userpass.empty()) { |
| | | AfxMessageBox(_T("ç¨æ·ååå¯ç ä¸è½ä¸ºç©ºï¼")); |
| | | return; |
| | | } |
| | | |
| | | if (usernameSet.find(username) != usernameSet.end()) { |
| | | CString message; |
| | | message.Format(_T("ç¨æ·å [%s] éå¤ï¼è¯·ä¿®æ¹åä¿åï¼"), cellText); |
| | | AfxMessageBox(message, MB_ICONEXCLAMATION); |
| | | return; |
| | | } |
| | | usernameSet.insert(username); |
| | | |
| | | if (nCurrUserRow == -1 && m_gridUserManager.GetItemBkColour(i, 0) == CURR_USER_BK_COLOR){ |
| | | nCurrUserRow = i; |
| | | if (username.compare(userManager.getCurrentUser()) != 0) { |
| | | userManager.setCurrentUser(username); |
| | | } |
| | | |
| | | if (userpass.compare(userManager.getCurrentPass()) != 0) { |
| | | userManager.setCurrentPass(userpass); |
| | | } |
| | | |
| | | userManager.clearSession(); |
| | | userManager.saveSession(); |
| | | } |
| | | |
| | | for (int j = 1; j < m_gridUserManager.GetColumnCount() - 1; ++j) { |
| | | CString cellText = m_gridUserManager.GetItemText(i, j); |
| | | std::string cellString = CT2A(cellText.GetString()); |
| | | |
| | | // 第4忝æéï¼è½¬æ¢ä¸ºæ°åå符串 |
| | | if (j == 3) { |
| | | if (cellText == _T("管çå")) |
| | | cellString = "0"; |
| | | else if (cellText == _T("å·¥ç¨å¸")) |
| | | cellString = "1"; |
| | | else if (cellText == _T("æä½å")) |
| | | cellString = "2"; |
| | | else |
| | | cellString = "2"; |
| | | } |
| | | |
| | | rowData.push_back(cellString); |
| | | } |
| | | |
| | | vecData.push_back(rowData); |
| | | } |
| | | |
| | | userManager.setUsers(vecData); |
| | | CDialogEx::OnOK(); |
| | | } |
| ÎļþÃû´Ó SourceCode/Bond/BondEq/UserManagerDlg.h ÐÞ¸Ä |
| | |
| | | void AddRow(CGridCtrl* pGridCtrl); |
| | | void DeleteSelectedRow(CGridCtrl* pGridCtrl); |
| | | bool IsUsernameDuplicate(const CString& username); |
| | | void AdjustControls(int nWidth, int nHeight); |
| | | CFont* GetOrCreateFont(int nFontSize); |
| | | void SetDefaultFont(); |
| | | void AdjustControls(float dScaleX, float dScaleY); |
| | | void AdjustControlFont(CWnd* pWnd, int nWidth, int nHeight); |
| | | |
| | | private: |
| | | int m_nInitialWidth; |
| | | int m_nInitialHeight; |
| | | std::map<int, CRect> m_mapCtrlLayouts; |
| | | std::map<int, CFont*> m_mapFonts; |
| | | std::map<CString, CString> m_mapRoleDescriptions; |
| | | |
| | | private: |
| | | CGridCtrl m_gridUserManager; |
| | |
| | | public: |
| | | virtual BOOL OnInitDialog(); |
| | | afx_msg void OnSize(UINT nType, int cx, int cy); |
| | | afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI); |
| | | afx_msg void OnGridComboSelChange(NMHDR* pNMHDR, LRESULT* pResult); |
| | | afx_msg void OnBnClickedButtonAdd(); |
| | | afx_msg void OnBnClickedButtonInsert(); |
| | | afx_msg void OnBnClickedButtonDel(); |
| | |
| | | #include "..\DatabaseSDK\include\MySQLDatabase.h" |
| | | #include "..\DatabaseSDK\include\SQLiteDatabase.h" |
| | | |
| | | // å便¨¡å¼çæ°æ®åºç®¡çç±» |
| | | #include "UserManager.h" |
| | | #include "RecipeManager.h" |
| | | #include "SystemLogManager.h" |
| | | |
| | | // æ§ä»¶æ ·å¼ |
| | | static UINT g_nGridFixCellColor = RGB(144, 200, 246); |
| | | static UINT g_nGridFixFontColor = RGB(0, 0, 0); |