| | |
| | | SourceCode/Bond/x64/Debug/HsmsPassive.cache |
| | | SourceCode/Bond/x64/Debug/MasterState.dat |
| | | SourceCode/Bond/x64/Debug/Recipe/EQ10_Unit0.recipelist |
| | | SourceCode/Bond/UserX/ |
| | | Document/~$Panel Bonderå
«é¶èå SecsTest CheckList_v3.0.xlsx |
| | |
| | | #if !defined(AFX_BLLABEL_H__A4EABEC5_2E8C_11D1_B79F_00805F9ECE10__INCLUDED_) |
| | | #if !defined(AFX_BLLABEL_H__A4EABEC5_2E8C_11D1_B79F_00805F9ECE10__INCLUDED_) |
| | | #define AFX_BLLABEL_H__A4EABEC5_2E8C_11D1_B79F_00805F9ECE10__INCLUDED_ |
| | | |
| | | #if _MSC_VER >= 1000 |
| | |
| | | #include "Servo.h" |
| | | #include "CHMPropertyDlg.h" |
| | | #include "afxdialogex.h" |
| | | #include "HmTab.h" |
| | | #include <algorithm> |
| | | |
| | | |
| | | // CEquipmentDlg å¯¹è¯æ¡ |
| | |
| | | m_hbrBkgnd = nullptr; |
| | | m_nWndWidth = 0; |
| | | m_nWndHeight = 0; |
| | | m_pTab = nullptr; |
| | | } |
| | | |
| | | CHMPropertyDlg::CHMPropertyDlg(const char* pszTitle, int width, int height) |
| | |
| | | m_nWndWidth = width; |
| | | m_nWndHeight = height; |
| | | m_strTitle = pszTitle; |
| | | m_pTab = nullptr; |
| | | } |
| | | |
| | | CHMPropertyDlg::~CHMPropertyDlg() |
| | |
| | | |
| | | // Tab |
| | | CString strTitle; |
| | | CHmTab* m_pTab = CHmTab::Hook(GetDlgItem(IDC_TAB1)->m_hWnd); |
| | | m_pTab = CHmTab::Hook(GetDlgItem(IDC_TAB1)->m_hWnd); |
| | | m_pTab->SetPaddingLeft(20); |
| | | m_pTab->SetItemMarginLeft(18); |
| | | for (int i = 0; i < m_pages.size(); i++) { |
| | | m_pages[i]->SetParent(this); |
| | | m_pages[i]->GetWindowText(strTitle); |
| | | m_pages[i]->OnCreateBtns(); |
| | | m_pTab->AddItem(strTitle, i == m_pages.size() - 1); |
| | | } |
| | | m_pTab->SetCurSel(0); |
| | |
| | | void CHMPropertyDlg::OnSize(UINT nType, int cx, int cy) |
| | | { |
| | | CDialogEx::OnSize(nType, cx, cy); |
| | | if (GetDlgItem(IDC_TAB1) == nullptr) return; |
| | | if (m_pTab == nullptr) return; |
| | | Resize(); |
| | | } |
| | | |
| | |
| | | pItem->GetWindowRect(&rcItem); |
| | | pItem->MoveWindow(x2 - rcItem.Width(), y2 - rcItem.Height(), |
| | | rcItem.Width(), rcItem.Height()); |
| | | y2 -= rcItem.Height(); |
| | | y2 -= 12; |
| | | |
| | | // å½åå页æé®ï¼å¦ææï¼ |
| | | int btnY = y2 - rcItem.Height(); |
| | | int btnX = 12; |
| | | y2 -= rcItem.Height() + 12; |
| | | int curIndex = (m_pTab != nullptr) ? m_pTab->GetCurSel() : 0; |
| | | if (curIndex >= 0 && curIndex < (int)m_pages.size()) { |
| | | auto& btnMap = m_pages[curIndex]->getBtns(); |
| | | // æ BTN_ORDER æåº |
| | | std::vector<std::pair<int, CButton*>> ordered; |
| | | for (auto& kv : btnMap) { |
| | | CButton* btn = kv.second; |
| | | if (btn == nullptr || !::IsWindow(btn->GetSafeHwnd())) continue; |
| | | int order = (int)(INT_PTR)::GetProp(btn->GetSafeHwnd(), _T("BTN_ORDER")); |
| | | ordered.emplace_back(order, btn); |
| | | } |
| | | std::sort(ordered.begin(), ordered.end(), [](const auto& a, const auto& b) { |
| | | return a.first < b.first; |
| | | }); |
| | | for (auto& item : ordered) { |
| | | CButton* btn = item.second; |
| | | CRect rcBtn; |
| | | btn->GetWindowRect(&rcBtn); |
| | | if (rcBtn.Width() <= 0 || rcBtn.Height() <= 0) { |
| | | rcBtn.SetRect(0, 0, 80, 28); |
| | | } |
| | | btn->MoveWindow(btnX, btnY, rcBtn.Width(), rcBtn.Height()); |
| | | btnX += rcBtn.Width() + 8; |
| | | } |
| | | } |
| | | |
| | | // åé线 |
| | | pItem = GetDlgItem(IDC_LINE1); |
| | |
| | | for (int i = 0; i < m_pages.size(); i++) { |
| | | m_pages[i]->ShowWindow(i == index ? SW_SHOW : SW_HIDE); |
| | | } |
| | | |
| | | // éèææé¡µé¢çæé® |
| | | for (auto page : m_pages) { |
| | | for (auto& kv : page->getBtns()) { |
| | | CButton* btn = kv.second; |
| | | if (btn != nullptr && ::IsWindow(btn->GetSafeHwnd())) { |
| | | btn->ShowWindow(SW_HIDE); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // å建并æ¾ç¤ºå½å页é¢çæé® |
| | | auto& btns = m_pages[index]->getBtns(); |
| | | if (!btns.empty()) { |
| | | CRect rcClient; |
| | | GetClientRect(&rcClient); |
| | | const int margin = 12; |
| | | const int spacing = 8; |
| | | int x = margin; |
| | | int y = rcClient.bottom - 40; // é¢çåºé¨åºå |
| | | |
| | | // æ BTN_ORDER æåº |
| | | std::vector<std::pair<int, CButton*>> ordered; |
| | | for (auto& kv : btns) { |
| | | CButton* btn = kv.second; |
| | | if (btn == nullptr || !::IsWindow(btn->GetSafeHwnd())) continue; |
| | | int order = (int)(INT_PTR)::GetProp(btn->GetSafeHwnd(), _T("BTN_ORDER")); |
| | | ordered.emplace_back(order, btn); |
| | | } |
| | | std::sort(ordered.begin(), ordered.end(), [](const auto& a, const auto& b) { |
| | | return a.first < b.first; |
| | | }); |
| | | for (auto& item : ordered) { |
| | | CButton* btn = item.second; |
| | | CRect rc; |
| | | btn->GetWindowRect(&rc); |
| | | if (rc.Width() <= 0 || rc.Height() <= 0) { |
| | | rc.SetRect(0, 0, 80, 28); |
| | | } |
| | | btn->MoveWindow(x, y, rc.Width(), rc.Height()); |
| | | btn->ShowWindow(SW_SHOW); |
| | | x += rc.Width() + spacing; |
| | | } |
| | | } |
| | | } |
| | | |
| | | void CHMPropertyDlg::SetWindowSize(int width, int height) |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | BOOL CHMPropertyDlg::OnCommand(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | UINT code = HIWORD(wParam); |
| | | HWND hCtrl = (HWND)lParam; |
| | | |
| | | if (code == BN_CLICKED && hCtrl != nullptr) { |
| | | for (auto page : m_pages) { |
| | | for (auto& kv : page->getBtns()) { |
| | | if (kv.second != nullptr && kv.second->GetSafeHwnd() == hCtrl) { |
| | | page->HandleBtnClick(hCtrl); |
| | | return TRUE; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | return CDialogEx::OnCommand(wParam, lParam); |
| | | } |
| | |
| | | #pragma once |
| | | #include <vector> |
| | | #include "CHMPropertyPage.h" |
| | | #include "HmTab.h" |
| | | |
| | | |
| | | // CEquipmentDlg å¯¹è¯æ¡ |
| | |
| | | std::vector<CHMPropertyPage*> m_pages; |
| | | int m_nWndWidth; |
| | | int m_nWndHeight; |
| | | CHmTab* m_pTab; |
| | | |
| | | |
| | | // å¯¹è¯æ¡æ°æ® |
| | |
| | | afx_msg void OnTabSelChanged(NMHDR* nmhdr, LRESULT* result); |
| | | afx_msg void OnBnClickedOk(); |
| | | afx_msg void OnBnClickedButtonApply(); |
| | | virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam); |
| | | }; |
| | |
| | | { |
| | | |
| | | } |
| | | |
| | | void CHMPropertyPage::OnCreateBtns() |
| | | { |
| | | |
| | | } |
| | | |
| | | CButton* CHMPropertyPage::CreateBtn(const char* name, int w, int h, const UINT id) |
| | | { |
| | | std::string key = std::string(name); |
| | | auto it = m_btns.find(key); |
| | | if (it != m_btns.end()) { |
| | | return it->second; |
| | | } |
| | | |
| | | CButton* pBtn = new CButton(); |
| | | pBtn->Create(name, WS_CHILD, CRect(0, 0, w, h), GetParent(), id); |
| | | // 使ç¨é»è®¤GUIåä½ |
| | | HFONT hFont = (HFONT)::GetStockObject(DEFAULT_GUI_FONT); |
| | | if (hFont != nullptr) { |
| | | pBtn->SetFont(CFont::FromHandle(hFont), FALSE); |
| | | } |
| | | ::SetProp(pBtn->GetSafeHwnd(), _T("BTN_ORDER"), (HANDLE)(INT_PTR)m_btnOrderSeq++); |
| | | m_btns[key] = pBtn; |
| | | return pBtn; |
| | | } |
| | | |
| | | CButton* CHMPropertyPage::GetBtnByName(const char* name) |
| | | { |
| | | auto it = m_btns.find(std::string(name)); |
| | | if (it != m_btns.end()) { |
| | | return it->second; |
| | | } |
| | | return nullptr; |
| | | } |
| | | |
| | | std::map<std::string, CButton*>& CHMPropertyPage::getBtns() |
| | | { |
| | | return m_btns; |
| | | } |
| | | |
| | | void CHMPropertyPage::HandleBtnClick(HWND hBtn) |
| | | { |
| | | for (auto& kv : m_btns) { |
| | | if (kv.second != nullptr && kv.second->GetSafeHwnd() == hBtn) { |
| | | OnClickedBtn(kv.first.c_str()); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | BEGIN_MESSAGE_MAP(CHMPropertyPage, CDialogEx) |
| | | ON_WM_DESTROY() |
| | | END_MESSAGE_MAP() |
| | | |
| | | void CHMPropertyPage::OnDestroy() |
| | | { |
| | | CDialogEx::OnDestroy(); |
| | | |
| | | for (auto& kv : m_btns) { |
| | | CButton* btn = kv.second; |
| | | if (btn != nullptr) { |
| | | if (::IsWindow(btn->GetSafeHwnd())) { |
| | | ::RemoveProp(btn->GetSafeHwnd(), _T("BTN_ORDER")); |
| | | } |
| | | if (::IsWindow(btn->GetSafeHwnd())) { |
| | | btn->DestroyWindow(); |
| | | } |
| | | delete btn; |
| | | } |
| | | } |
| | | m_btns.clear(); |
| | | } |
| | |
| | | #pragma once |
| | | #pragma once |
| | | #include <map> |
| | | #include <string> |
| | | |
| | | class CHMPropertyPage : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CHMPropertyPage) |
| | | |
| | | public: |
| | | CHMPropertyPage(UINT nID, CWnd* pPage); // æ åæé 彿° |
| | | virtual ~CHMPropertyPage(); // ææå½æ° |
| | | CHMPropertyPage(UINT nID, CWnd* pPage); // æ åæé 彿° |
| | | virtual ~CHMPropertyPage(); // ææå½æ° |
| | | virtual void OnApply(); |
| | | virtual void OnCreateBtns(); |
| | | afx_msg void OnDestroy(); |
| | | std::map<std::string, CButton*>& getBtns(); |
| | | CButton* GetBtnByName(const char* name); |
| | | void HandleBtnClick(HWND hBtn); |
| | | |
| | | protected: |
| | | // åç±»å¯éåï¼æ°å¢/å é¤/ç¼è¾æé®ç¹å»å¤ç |
| | | virtual void OnClickedBtn(const char* btnName) {}; |
| | | |
| | | protected: |
| | | CButton* CreateBtn(const char* name, int w, int h, const UINT id); |
| | | std::map<std::string, CButton*> m_btns; |
| | | int m_btnOrderSeq{ 0 }; |
| | | |
| | | DECLARE_MESSAGE_MAP() |
| | | }; |
| | | |
| | |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | InitRxWindows(); |
| | | SetTimer(TIMER_ID_DEVICE_STATUS, 3000, nullptr); |
| | | SetTimer(TIMER_ID_DEVICE_STATUS, 800, nullptr); |
| | | SetTimer(TIMER_ID_ROBOT_STATUS, 1000, nullptr); // æ¯ 1000ms æ´æ°ä¸æ¬¡ç¶æ |
| | | |
| | | // å¾ç¤º |
| | |
| | | ON_WM_CTLCOLOR() |
| | | ON_WM_DESTROY() |
| | | ON_WM_SIZE() |
| | | ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, &CPageVarialbles::OnLvnItemchangedList1) |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | |
| | | m_listCtrl.SetItemText(index, 4, item->getRemark().c_str()); |
| | | } |
| | | } |
| | | |
| | | void CPageVarialbles::OnCreateBtns() |
| | | { |
| | | const int BTN_W = 80; |
| | | const int BTN_H = 28; |
| | | CreateBtn(_T("æ°å¢"), BTN_W, BTN_H, 1001); |
| | | CreateBtn(_T("å é¤"), BTN_W, BTN_H, 1002)->EnableWindow(FALSE); |
| | | CreateBtn(_T("ç¼è¾"), BTN_W, BTN_H, 1003)->EnableWindow(FALSE); |
| | | } |
| | | |
| | | void CPageVarialbles::OnLvnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult) |
| | | { |
| | | LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR); |
| | | int nSelCount = m_listCtrl.GetSelectedCount(); |
| | | |
| | | // æ ¹æ®éä¸ç¶æå¯ç¨/ç¦ç¨æé® |
| | | if (CButton* pDel = GetBtnByName("å é¤")) { |
| | | pDel->EnableWindow(nSelCount > 0); |
| | | } |
| | | if (CButton* pEdit = GetBtnByName("ç¼è¾")) { |
| | | pEdit->EnableWindow(nSelCount > 0); |
| | | } |
| | | |
| | | *pResult = 0; |
| | | } |
| | | |
| | | void CPageVarialbles::OnClickedBtn(const char* btnName) |
| | | { |
| | | ASSERT(btnName); |
| | | if (_strcmpi(btnName, "æ°å¢") == 0) { |
| | | // TODO: æ°å¢é»è¾ |
| | | } |
| | | else if (_strcmpi(btnName, "å é¤") == 0) { |
| | | POSITION pos = m_listCtrl.GetFirstSelectedItemPosition(); |
| | | if (pos == nullptr) return; |
| | | int nItem = m_listCtrl.GetNextSelectedItem(pos); |
| | | auto pVar = reinterpret_cast<SERVO::CVariable*>(m_listCtrl.GetItemData(nItem)); |
| | | if (pVar == nullptr) return; |
| | | |
| | | int ret = theApp.m_model.m_hsmsPassive.deleteVariable(pVar->getVarialbleId()); |
| | | if (ret == 0) { |
| | | m_listCtrl.DeleteAllItems(); |
| | | loadVariables(); |
| | | if (CButton* pDel = GetBtnByName("å é¤")) pDel->EnableWindow(FALSE); |
| | | if (CButton* pEdit = GetBtnByName("ç¼è¾")) pEdit->EnableWindow(FALSE); |
| | | } |
| | | } |
| | | else if (_strcmpi(btnName, "ç¼è¾") == 0) { |
| | | // TODO: ç¼è¾é»è¾ |
| | | } |
| | | } |
| | |
| | | virtual ~CPageVarialbles(); |
| | | virtual void OnApply(); |
| | | void loadVariables(); |
| | | virtual void OnCreateBtns(); |
| | | |
| | | private: |
| | | CListCtrlEx m_listCtrl; |
| | | |
| | | protected: |
| | | virtual void OnClickedBtn(const char* btnName) override; |
| | | |
| | | |
| | | // å¯¹è¯æ¡æ°æ® |
| | |
| | | afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); |
| | | afx_msg void OnDestroy(); |
| | | afx_msg void OnSize(UINT nType, int cx, int cy); |
| | | afx_msg void OnLvnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult); |
| | | }; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include "CUserEdit2Dlg.h" |
| | | #include "CUserManager2.h" |
| | | #include "resource.h" |
| | | |
| | | IMPLEMENT_DYNAMIC(CUserEdit2Dlg, CDialogEx) |
| | | |
| | | CUserEdit2Dlg::CUserEdit2Dlg(bool editMode, CWnd* pParent /*=nullptr*/) |
| | | : CDialogEx(IDD_DIALOG_USER_EDIT2, pParent) |
| | | { |
| | | m_bEditMode = editMode; |
| | | } |
| | | |
| | | CUserEdit2Dlg::~CUserEdit2Dlg() |
| | | { |
| | | } |
| | | |
| | | void CUserEdit2Dlg::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | DDX_Text(pDX, IDC_EDIT_USER_ACCOUNT, m_strUsername); |
| | | DDX_Text(pDX, IDC_EDIT_USER_DISPLAY, m_strDisplayName); |
| | | DDX_Text(pDX, IDC_EDIT_USER_PASSWORD, m_strPassword); |
| | | DDX_CBString(pDX, IDC_COMBO_USER_ROLE, m_strRole); |
| | | DDX_Check(pDX, IDC_CHECK_USER_ENABLED, m_bEnabled); |
| | | } |
| | | |
| | | BEGIN_MESSAGE_MAP(CUserEdit2Dlg, CDialogEx) |
| | | END_MESSAGE_MAP() |
| | | |
| | | BOOL CUserEdit2Dlg::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | |
| | | if (m_bEditMode) { |
| | | if (auto pEdit = GetDlgItem(IDC_EDIT_USER_ACCOUNT)) { |
| | | pEdit->EnableWindow(FALSE); |
| | | } |
| | | } |
| | | |
| | | UpdateData(FALSE); |
| | | |
| | | auto roles = CUserManager2::getInstance().getRoles(); |
| | | CComboBox* pCombo = (CComboBox*)GetDlgItem(IDC_COMBO_USER_ROLE); |
| | | if (pCombo) { |
| | | int selected = -1; |
| | | for (const auto& role : roles) { |
| | | CString text(role.name.c_str()); |
| | | int idx = pCombo->AddString(text); |
| | | if (selected == -1 && m_strRole.CompareNoCase(text) == 0) { |
| | | selected = idx; |
| | | } |
| | | } |
| | | |
| | | if (selected >= 0) { |
| | | pCombo->SetCurSel(selected); |
| | | } |
| | | else if (pCombo->GetCount() > 0) { |
| | | pCombo->SetCurSel(0); |
| | | CString text; |
| | | pCombo->GetLBText(0, text); |
| | | if (m_strRole.IsEmpty()) { |
| | | m_strRole = text; |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (auto pPwd = GetDlgItem(IDC_EDIT_USER_PASSWORD)) { |
| | | pPwd->EnableWindow(!m_bEditMode); |
| | | if (m_bEditMode) { |
| | | pPwd->SetWindowText(_T("")); |
| | | } |
| | | } |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | void CUserEdit2Dlg::OnOK() |
| | | { |
| | | UpdateData(TRUE); |
| | | |
| | | CString user = m_strUsername; |
| | | user.Trim(); |
| | | CString role = m_strRole; |
| | | role.Trim(); |
| | | |
| | | CString password = m_strPassword; |
| | | password.Trim(); |
| | | |
| | | if (m_bEditMode) { |
| | | password.Empty(); |
| | | } |
| | | |
| | | if (!m_bEditMode) { |
| | | if (user.IsEmpty()) { |
| | | AfxMessageBox(_T("请è¾å
¥è´¦å·")); |
| | | return; |
| | | } |
| | | |
| | | if (password.IsEmpty()) { |
| | | AfxMessageBox(_T("请è¾å
¥å¯ç ")); |
| | | return; |
| | | } |
| | | } |
| | | |
| | | if (role.IsEmpty()) { |
| | | AfxMessageBox(_T("è¯·éæ©è§è²")); |
| | | return; |
| | | } |
| | | |
| | | if (auto pCombo = (CComboBox*)GetDlgItem(IDC_COMBO_USER_ROLE)) { |
| | | int sel = pCombo->GetCurSel(); |
| | | if (sel != CB_ERR) { |
| | | CString text; |
| | | pCombo->GetLBText(sel, text); |
| | | if (!text.IsEmpty()) { |
| | | m_strRole = text; |
| | | } |
| | | } |
| | | } |
| | | |
| | | m_strUsername = user; |
| | | m_strPassword = password; |
| | | CDialogEx::OnOK(); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | |
| | | class CUserEdit2Dlg : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CUserEdit2Dlg) |
| | | |
| | | public: |
| | | CUserEdit2Dlg(bool editMode = false, CWnd* pParent = nullptr); |
| | | virtual ~CUserEdit2Dlg(); |
| | | |
| | | CString m_strUsername; |
| | | CString m_strDisplayName; |
| | | CString m_strPassword; |
| | | CString m_strRole; |
| | | BOOL m_bEnabled = TRUE; |
| | | bool m_bEditMode = false; |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); |
| | | virtual BOOL OnInitDialog(); |
| | | afx_msg void OnOK(); |
| | | DECLARE_MESSAGE_MAP() |
| | | }; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include "CUserManager2.h" |
| | | #include "ToolUnits.h" |
| | | #include <vector> |
| | | #include <map> |
| | | #include <utility> |
| | | #include <algorithm> |
| | | #include <sstream> |
| | | #include <cwchar> |
| | | |
| | | std::vector<std::wstring> SplitLines(const std::wstring& text) |
| | | { |
| | | std::wstringstream ss(text); std::vector<std::wstring> v; std::wstring line; while (std::getline(ss, line)) v.push_back(line); return v; |
| | | } |
| | | |
| | | std::vector<std::wstring> SplitByDelimiter(const std::wstring& text, wchar_t delimiter) |
| | | { |
| | | std::vector<std::wstring> parts; |
| | | size_t start = 0; |
| | | while (start <= text.length()) { |
| | | size_t pos = text.find(delimiter, start); |
| | | if (pos == std::wstring::npos) { |
| | | parts.push_back(text.substr(start)); |
| | | break; |
| | | } |
| | | |
| | | parts.push_back(text.substr(start, pos - start)); |
| | | start = pos + 1; |
| | | } |
| | | |
| | | return parts; |
| | | } |
| | | |
| | | template<typename Fn> |
| | | std::wstring ReadBufferVia(Fn fn) |
| | | { |
| | | int need = fn(nullptr, 0); if (need <= 0) return L""; |
| | | std::wstring buf; buf.resize((size_t)need); |
| | | int rc = fn(buf.data(), need); |
| | | if (rc == 0) { if (!buf.empty() && buf.back() == L'\0') buf.pop_back(); return buf; } |
| | | return L""; |
| | | } |
| | | |
| | | // è·ååä¾å®ä¾ |
| | | CUserManager2& CUserManager2::getInstance() { |
| | | static CUserManager2 instance; |
| | | return instance; |
| | | } |
| | | |
| | | CUserManager2::CUserManager2() |
| | | { |
| | | |
| | | } |
| | | |
| | | CUserManager2::~CUserManager2() |
| | | { |
| | | |
| | | } |
| | | |
| | | void CUserManager2::init(const char* pszDir) |
| | | { |
| | | std::wstring dir = CToolUnits::AnsiToWString(std::string(pszDir)); |
| | | UX_Init(dir.c_str()); |
| | | |
| | | wchar_t buffer[1024]; |
| | | UX_GetUsers(buffer, 1024); |
| | | bool hasAny = false; |
| | | for (auto& ln : SplitLines(buffer)) { if (!ln.empty()) { hasAny = true; break; } } |
| | | if (!hasAny) { |
| | | const wchar_t* roles = L"Admin:100\nEE:80\nPE:50\nOperator:10\n"; |
| | | (void)UX_SetRoleDefinitions(roles); |
| | | (void)UX_AddUser(L"admin", L"Administrator", L"admin123", L"Admin"); |
| | | |
| | | UX_DefineAction(L"start", L"å¯å¨æºå°", L"Operator"); |
| | | UX_DefineAction(L"stop", L"åæº", L"Operator"); |
| | | UX_DefineAction(L"recipe", L"ç¼è¾é
æ¹", L"Engineer"); |
| | | } |
| | | } |
| | | |
| | | bool CUserManager2::login(const char* pszAccount, const char* pszPwd) |
| | | { |
| | | std::wstring strUser, strPwd; |
| | | strUser = CToolUnits::AnsiToWString(std::string(pszAccount)); |
| | | strPwd = CToolUnits::AnsiToWString(std::string(pszPwd)); |
| | | int rc = UX_Login(strUser.c_str(), strPwd.c_str()); |
| | | return rc == UX_OK; |
| | | } |
| | | |
| | | bool CUserManager2::isLoggedIn() |
| | | { |
| | | return UX_IsLoggedIn(); |
| | | } |
| | | |
| | | std::string CUserManager2::getCurrentUserName() |
| | | { |
| | | std::string strName; |
| | | |
| | | int need = UX_GetCurrentUser(nullptr, 0); |
| | | std::wstring buf; buf.resize((size_t)need); |
| | | if (UX_GetCurrentUser(buf.data(), need) == UX_OK) { |
| | | if (!buf.empty() && buf.back() == L'\0') |
| | | buf.pop_back(); |
| | | |
| | | strName = CToolUnits::WStringToAnsi(buf); |
| | | } |
| | | |
| | | return strName; |
| | | } |
| | | |
| | | bool CUserManager2::IsAdminCurrent() |
| | | { |
| | | if (UX_IsLoggedIn() != 1) return false; |
| | | int need = UX_GetCurrentUser(nullptr, 0); if (need <= 0) return false; |
| | | std::wstring user; user.resize((size_t)need); |
| | | if (UX_GetCurrentUser(user.data(), need) != 0) return false; |
| | | if (!user.empty() && user.back() == L'\0') user.pop_back(); |
| | | int maxLvl = 0; auto rolesTxt = ReadBufferVia([](wchar_t* b, int n) { return UX_GetRoles(b, n); }); |
| | | for (auto& ln : SplitLines(rolesTxt)) { size_t p = ln.find(L':'); if (p != std::wstring::npos) { int lvl = _wtoi(ln.substr(p + 1).c_str()); if (lvl > maxLvl) maxLvl = lvl; } } |
| | | int myLvl = 0; auto usersTxt = ReadBufferVia([](wchar_t* b, int n) { return UX_GetUsers(b, n); }); |
| | | for (auto& ln : SplitLines(usersTxt)) { |
| | | if (ln.empty()) continue; size_t p1 = ln.find(L','), p2 = ln.find(L',', p1 == std::wstring::npos ? 0 : p1 + 1), p3 = ln.find(L',', p2 == std::wstring::npos ? 0 : p2 + 1); |
| | | std::wstring name = (p1 == std::wstring::npos ? ln : ln.substr(0, p1)); if (name == user) { if (p2 != std::wstring::npos) { std::wstring lvlS = ln.substr(p2 + 1, (p3 == std::wstring::npos ? ln.size() : p3) - (p2 + 1)); myLvl = _wtoi(lvlS.c_str()); } break; } |
| | | } |
| | | |
| | | return (maxLvl > 0) && (myLvl >= maxLvl); |
| | | } |
| | | |
| | | std::vector<CUserManager2::RoleInfo> CUserManager2::getRoles() |
| | | { |
| | | std::vector<RoleInfo> roles; |
| | | auto txt = ReadBufferVia([](wchar_t* b, int n) { return UX_GetRoles(b, n); }); |
| | | if (txt.empty()) { |
| | | return roles; |
| | | } |
| | | |
| | | for (auto& line : SplitLines(txt)) { |
| | | if (line.empty()) continue; |
| | | size_t pos = line.find(L':'); |
| | | RoleInfo info; |
| | | info.name = (pos == std::wstring::npos) ? line : line.substr(0, pos); |
| | | if (pos != std::wstring::npos) { |
| | | info.level = _wtoi(line.substr(pos + 1).c_str()); |
| | | } |
| | | |
| | | if (!info.name.empty()) { |
| | | roles.push_back(std::move(info)); |
| | | } |
| | | } |
| | | |
| | | std::sort(roles.begin(), roles.end(), [](const RoleInfo& a, const RoleInfo& b) { |
| | | if (a.level == b.level) { |
| | | return a.name < b.name; |
| | | } |
| | | return a.level > b.level; |
| | | }); |
| | | |
| | | return roles; |
| | | } |
| | | std::vector<CUserManager2::UserInfo> CUserManager2::getUsers() |
| | | { |
| | | std::vector<UserInfo> users; |
| | | auto txt = ReadBufferVia([](wchar_t* b, int n) { return UX_GetUsers(b, n); }); |
| | | if (txt.empty()) { |
| | | return users; |
| | | } |
| | | |
| | | std::map<int, std::wstring> roleMap; |
| | | for (auto& role : getRoles()) { |
| | | roleMap[role.level] = role.name; |
| | | } |
| | | |
| | | for (auto& line : SplitLines(txt)) { |
| | | if (line.empty()) continue; |
| | | auto parts = SplitByDelimiter(line, L','); |
| | | UserInfo info; |
| | | if (!parts.empty()) info.userName = parts[0]; |
| | | if (parts.size() > 1) info.displayName = parts[1]; |
| | | if (parts.size() > 2) info.roleLevel = _wtoi(parts[2].c_str()); |
| | | if (parts.size() > 3) info.enabled = (_wtoi(parts[3].c_str()) != 0); |
| | | auto it = roleMap.find(info.roleLevel); |
| | | if (it != roleMap.end()) { |
| | | info.roleName = it->second; |
| | | } |
| | | users.push_back(std::move(info)); |
| | | } |
| | | |
| | | return users; |
| | | } |
| | | |
| | | int CUserManager2::addUser(const std::wstring& userName, const std::wstring& displayName, |
| | | const std::wstring& password, const std::wstring& roleName, bool enabled) |
| | | { |
| | | int rc = UX_AddUser(userName.c_str(), displayName.c_str(), password.c_str(), roleName.c_str()); |
| | | if (rc == UX_OK && !enabled) { |
| | | UX_EnableUser(userName.c_str(), 0); |
| | | } |
| | | |
| | | return rc; |
| | | } |
| | | |
| | | int CUserManager2::updateUser(const std::wstring& userName, const std::wstring& displayName, |
| | | const std::wstring& password, const std::wstring& roleName, bool enabled) |
| | | { |
| | | const wchar_t* disp = displayName.empty() ? nullptr : displayName.c_str(); |
| | | const wchar_t* pwd = password.empty() ? nullptr : password.c_str(); |
| | | const wchar_t* role = roleName.empty() ? nullptr : roleName.c_str(); |
| | | return UX_UpdateUser(userName.c_str(), disp, pwd, role, enabled ? 1 : 0); |
| | | } |
| | | |
| | | int CUserManager2::deleteUser(const std::wstring& userName) |
| | | { |
| | | return UX_DeleteUser(userName.c_str()); |
| | | } |
| | | |
| | | int CUserManager2::setUserEnabled(const std::wstring& userName, bool enabled) |
| | | { |
| | | return UX_EnableUser(userName.c_str(), enabled ? 1 : 0); |
| | | } |
| | | |
| | | int CUserManager2::resetPassword(const std::wstring& userName, const std::wstring& password) |
| | | { |
| | | return UX_ResetPassword(userName.c_str(), password.c_str()); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | |
| | | #include <string> |
| | | #include <vector> |
| | | |
| | | class CUserManager2 |
| | | { |
| | | public: |
| | | static CUserManager2& getInstance(); |
| | | CUserManager2(const CUserManager2&) = delete; |
| | | CUserManager2& operator=(const CUserManager2&) = delete; |
| | | |
| | | struct RoleInfo |
| | | { |
| | | std::wstring name; |
| | | int level = 0; |
| | | }; |
| | | |
| | | struct UserInfo |
| | | { |
| | | std::wstring userName; |
| | | std::wstring displayName; |
| | | std::wstring roleName; |
| | | int roleLevel = 0; |
| | | bool enabled = false; |
| | | }; |
| | | |
| | | public: |
| | | void init(const char* pszDir); |
| | | bool login(const char* pszAccount, const char* pszPwd); |
| | | bool isLoggedIn(); |
| | | std::string getCurrentUserName(); |
| | | bool IsAdminCurrent(); |
| | | std::vector<RoleInfo> getRoles(); |
| | | std::vector<UserInfo> getUsers(); |
| | | int addUser(const std::wstring& userName, const std::wstring& displayName, |
| | | const std::wstring& password, const std::wstring& roleName, bool enabled); |
| | | int updateUser(const std::wstring& userName, const std::wstring& displayName, |
| | | const std::wstring& password, const std::wstring& roleName, bool enabled); |
| | | int deleteUser(const std::wstring& userName); |
| | | int setUserEnabled(const std::wstring& userName, bool enabled); |
| | | int resetPassword(const std::wstring& userName, const std::wstring& password); |
| | | |
| | | private: |
| | | CUserManager2(); |
| | | ~CUserManager2(); |
| | | }; |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // CUserManager2Dlg.cpp |
| | | // |
| | | |
| | | #include "stdafx.h" |
| | | #include "Servo.h" |
| | | #include "CUserManager2Dlg.h" |
| | | #include "afxdialogex.h" |
| | | #include "CUserEdit2Dlg.h" |
| | | #include "InputDialog.h" |
| | | #include "resource.h" |
| | | #include "ToolUnits.h" |
| | | |
| | | IMPLEMENT_DYNAMIC(CUserManager2Dlg, CDialogEx) |
| | | |
| | | CUserManager2Dlg::CUserManager2Dlg(CWnd* pParent) |
| | | : CDialogEx(IDD_DIALOG_USER_MANAGER2, pParent) |
| | | { |
| | | } |
| | | |
| | | CUserManager2Dlg::~CUserManager2Dlg() |
| | | { |
| | | } |
| | | |
| | | void CUserManager2Dlg::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | DDX_Control(pDX, IDC_LIST1, m_listUsers); |
| | | } |
| | | |
| | | BEGIN_MESSAGE_MAP(CUserManager2Dlg, CDialogEx) |
| | | ON_WM_SIZE() |
| | | ON_BN_CLICKED(IDC_BUTTON_ADD, &CUserManager2Dlg::OnBnClickedButtonAdd) |
| | | ON_BN_CLICKED(IDC_BUTTON_EDIT, &CUserManager2Dlg::OnBnClickedButtonEdit) |
| | | ON_BN_CLICKED(IDC_BUTTON_DEL, &CUserManager2Dlg::OnBnClickedButtonDel) |
| | | ON_BN_CLICKED(IDC_BUTTON_RESET_PWD, &CUserManager2Dlg::OnBnClickedButtonResetPwd) |
| | | ON_BN_CLICKED(IDC_BUTTON_ENABLE, &CUserManager2Dlg::OnBnClickedButtonEnable) |
| | | ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, &CUserManager2Dlg::OnLvnItemchangedUsers) |
| | | END_MESSAGE_MAP() |
| | | |
| | | BOOL CUserManager2Dlg::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | |
| | | InitList(); |
| | | RefreshUserList(); |
| | | UpdateButtonState(); |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | void CUserManager2Dlg::OnSize(UINT nType, int cx, int cy) |
| | | { |
| | | CDialogEx::OnSize(nType, cx, cy); |
| | | } |
| | | |
| | | void CUserManager2Dlg::InitList() |
| | | { |
| | | DWORD dwStyle = m_listUsers.GetExtendedStyle(); |
| | | m_listUsers.SetExtendedStyle(dwStyle | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES); |
| | | m_listUsers.InsertColumn(0, _T("è´¦å·"), LVCFMT_LEFT, 90); |
| | | m_listUsers.InsertColumn(1, _T("æ¾ç¤ºå"), LVCFMT_LEFT, 100); |
| | | m_listUsers.InsertColumn(2, _T("è§è²"), LVCFMT_LEFT, 80); |
| | | m_listUsers.InsertColumn(3, _T("级å«"), LVCFMT_LEFT, 60); |
| | | m_listUsers.InsertColumn(4, _T("ç¶æ"), LVCFMT_LEFT, 70); |
| | | } |
| | | |
| | | void CUserManager2Dlg::RefreshUserList() |
| | | { |
| | | CString selectedName; |
| | | int currentIndex = GetSelectedIndex(); |
| | | if (currentIndex >= 0 && currentIndex < static_cast<int>(m_users.size())) { |
| | | selectedName = m_users[currentIndex].userName.c_str(); |
| | | } |
| | | |
| | | m_users = CUserManager2::getInstance().getUsers(); |
| | | m_listUsers.DeleteAllItems(); |
| | | |
| | | for (size_t i = 0; i < m_users.size(); ++i) { |
| | | const auto& user = m_users[i]; |
| | | CString account(user.userName.c_str()); |
| | | CString display(user.displayName.c_str()); |
| | | CString role(user.roleName.empty() ? L"-" : user.roleName.c_str()); |
| | | CString level; |
| | | level.Format(_T("%d"), user.roleLevel); |
| | | CString state = user.enabled ? _T("å¯ç¨") : _T("ç¦ç¨"); |
| | | |
| | | int row = m_listUsers.InsertItem(static_cast<int>(i), account); |
| | | m_listUsers.SetItemText(row, 1, display); |
| | | m_listUsers.SetItemText(row, 2, role); |
| | | m_listUsers.SetItemText(row, 3, level); |
| | | m_listUsers.SetItemText(row, 4, state); |
| | | } |
| | | |
| | | if (!selectedName.IsEmpty()) { |
| | | for (int i = 0; i < m_listUsers.GetItemCount(); ++i) { |
| | | if (selectedName.CompareNoCase(m_listUsers.GetItemText(i, 0)) == 0) { |
| | | m_listUsers.SetItemState(i, LVIS_SELECTED, LVIS_SELECTED); |
| | | m_listUsers.EnsureVisible(i, FALSE); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | UpdateButtonState(); |
| | | } |
| | | |
| | | void CUserManager2Dlg::UpdateButtonState() |
| | | { |
| | | int index = GetSelectedIndex(); |
| | | BOOL hasSelection = (index >= 0); |
| | | |
| | | auto enable = [&](int id, BOOL enableFlag) { |
| | | if (CWnd* p = GetDlgItem(id)) { |
| | | p->EnableWindow(enableFlag); |
| | | } |
| | | }; |
| | | |
| | | enable(IDC_BUTTON_EDIT, hasSelection); |
| | | enable(IDC_BUTTON_DEL, hasSelection); |
| | | enable(IDC_BUTTON_RESET_PWD, hasSelection); |
| | | enable(IDC_BUTTON_ENABLE, hasSelection); |
| | | |
| | | CString toggleText = _T("ç¦ç¨/å¯ç¨"); |
| | | if (const auto* user = GetSelectedUser()) { |
| | | toggleText = user->enabled ? _T("ç¦ç¨") : _T("å¯ç¨"); |
| | | if (IsCurrentUser(*user)) { |
| | | enable(IDC_BUTTON_DEL, FALSE); |
| | | enable(IDC_BUTTON_ENABLE, FALSE); |
| | | } |
| | | } |
| | | |
| | | SetDlgItemText(IDC_BUTTON_ENABLE, toggleText); |
| | | } |
| | | |
| | | int CUserManager2Dlg::GetSelectedIndex() const |
| | | { |
| | | if (!::IsWindow(m_listUsers.GetSafeHwnd())) { |
| | | return -1; |
| | | } |
| | | return m_listUsers.GetNextItem(-1, LVNI_SELECTED); |
| | | } |
| | | |
| | | const CUserManager2::UserInfo* CUserManager2Dlg::GetSelectedUser() const |
| | | { |
| | | int index = GetSelectedIndex(); |
| | | if (index < 0 || index >= static_cast<int>(m_users.size())) { |
| | | return nullptr; |
| | | } |
| | | return &m_users[index]; |
| | | } |
| | | |
| | | std::wstring CUserManager2Dlg::ToWString(const CString& text) const |
| | | { |
| | | CString trimmed(text); |
| | | trimmed.Trim(); |
| | | |
| | | std::string str((LPTSTR)(LPCTSTR)trimmed); |
| | | return CToolUnits::AnsiToWString(str); |
| | | } |
| | | |
| | | void CUserManager2Dlg::ShowErrorMessage(const CString& action, int code) |
| | | { |
| | | const wchar_t* detail = UX_ErrorMessage(code); |
| | | CString msg; |
| | | msg.Format(_T("%s: %s"), action.GetString(), detail ? detail : L"Unknown"); |
| | | AfxMessageBox(msg, MB_ICONERROR); |
| | | } |
| | | |
| | | bool CUserManager2Dlg::IsCurrentUser(const CUserManager2::UserInfo& info) const |
| | | { |
| | | CString current(CUserManager2::getInstance().getCurrentUserName().c_str()); |
| | | CString account(info.userName.c_str()); |
| | | current.Trim(); |
| | | account.Trim(); |
| | | return !current.IsEmpty() && current.CompareNoCase(account) == 0; |
| | | } |
| | | |
| | | void CUserManager2Dlg::OnBnClickedButtonAdd() |
| | | { |
| | | CUserEdit2Dlg dlg(false, this); |
| | | if (dlg.DoModal() != IDOK) { |
| | | return; |
| | | } |
| | | |
| | | CString account = dlg.m_strUsername; |
| | | account.Trim(); |
| | | CString display = dlg.m_strDisplayName; |
| | | display.Trim(); |
| | | if (display.IsEmpty()) { |
| | | display = account; |
| | | } |
| | | CString role = dlg.m_strRole; |
| | | role.Trim(); |
| | | CString password = dlg.m_strPassword; |
| | | password.Trim(); |
| | | |
| | | int rc = CUserManager2::getInstance().addUser(ToWString(account), ToWString(display), ToWString(password), ToWString(role), dlg.m_bEnabled == TRUE); |
| | | if (rc == UX_OK) { |
| | | RefreshUserList(); |
| | | AfxMessageBox(_T("æ°å¢ç¨æ·æå")); |
| | | } |
| | | else { |
| | | ShowErrorMessage(_T("æ°å¢ç¨æ·å¤±è´¥"), rc); |
| | | } |
| | | } |
| | | |
| | | void CUserManager2Dlg::OnBnClickedButtonEdit() |
| | | { |
| | | const auto* user = GetSelectedUser(); |
| | | if (!user) { |
| | | AfxMessageBox(_T("è¯·éæ©ç¨æ·")); |
| | | return; |
| | | } |
| | | |
| | | CUserEdit2Dlg dlg(true, this); |
| | | dlg.m_strUsername = user->userName.c_str(); |
| | | dlg.m_strDisplayName = user->displayName.c_str(); |
| | | dlg.m_strRole = user->roleName.c_str(); |
| | | dlg.m_bEnabled = user->enabled ? TRUE : FALSE; |
| | | if (dlg.DoModal() != IDOK) { |
| | | return; |
| | | } |
| | | |
| | | CString display = dlg.m_strDisplayName; |
| | | display.Trim(); |
| | | CString password = dlg.m_strPassword; |
| | | password.Trim(); |
| | | CString role = dlg.m_strRole; |
| | | role.Trim(); |
| | | |
| | | int rc = CUserManager2::getInstance().updateUser(user->userName, ToWString(display), ToWString(password), ToWString(role), dlg.m_bEnabled == TRUE); |
| | | if (rc == UX_OK) { |
| | | RefreshUserList(); |
| | | AfxMessageBox(_T("ä¿åæå")); |
| | | } |
| | | else { |
| | | ShowErrorMessage(_T("ä¿å失败"), rc); |
| | | } |
| | | } |
| | | |
| | | void CUserManager2Dlg::OnBnClickedButtonDel() |
| | | { |
| | | const auto* user = GetSelectedUser(); |
| | | if (!user) { |
| | | AfxMessageBox(_T("è¯·éæ©ç¨æ·")); |
| | | return; |
| | | } |
| | | |
| | | if (IsCurrentUser(*user)) { |
| | | AfxMessageBox(_T("ä¸è½å é¤å½åç»å½ç¨æ·")); |
| | | return; |
| | | } |
| | | |
| | | CString prompt; |
| | | prompt.Format(_T("ç¡®å®å é¤ç¨æ· %s ?"), CString(user->userName.c_str())); |
| | | if (AfxMessageBox(prompt, MB_ICONQUESTION | MB_YESNO) != IDYES) { |
| | | return; |
| | | } |
| | | |
| | | int rc = CUserManager2::getInstance().deleteUser(user->userName); |
| | | if (rc == UX_OK) { |
| | | RefreshUserList(); |
| | | AfxMessageBox(_T("å 餿å")); |
| | | } |
| | | else { |
| | | ShowErrorMessage(_T("å é¤å¤±è´¥"), rc); |
| | | } |
| | | } |
| | | |
| | | void CUserManager2Dlg::OnBnClickedButtonResetPwd() |
| | | { |
| | | const auto* user = GetSelectedUser(); |
| | | if (!user) { |
| | | AfxMessageBox(_T("è¯·éæ©ç¨æ·")); |
| | | return; |
| | | } |
| | | |
| | | CInputDialog dlg(_T("éç½®å¯ç "), _T("请è¾å
¥æ°å¯ç :"), this); |
| | | if (dlg.DoModal() != IDOK) { |
| | | return; |
| | | } |
| | | |
| | | CString password = dlg.GetInputText(); |
| | | password.Trim(); |
| | | if (password.IsEmpty()) { |
| | | AfxMessageBox(_T("å¯ç ä¸è½ä¸ºç©º")); |
| | | return; |
| | | } |
| | | |
| | | int rc = CUserManager2::getInstance().resetPassword(user->userName, ToWString(password)); |
| | | if (rc == UX_OK) { |
| | | AfxMessageBox(_T("å¯ç å·²éç½®")); |
| | | } |
| | | else { |
| | | ShowErrorMessage(_T("é置失败"), rc); |
| | | } |
| | | } |
| | | |
| | | void CUserManager2Dlg::OnBnClickedButtonEnable() |
| | | { |
| | | const auto* user = GetSelectedUser(); |
| | | if (!user) { |
| | | AfxMessageBox(_T("è¯·éæ©ç¨æ·")); |
| | | return; |
| | | } |
| | | |
| | | bool enable = !user->enabled; |
| | | int rc = CUserManager2::getInstance().setUserEnabled(user->userName, enable); |
| | | if (rc == UX_OK) { |
| | | RefreshUserList(); |
| | | CString msg = enable ? _T("ç¨æ·å·²å¯ç¨") : _T("ç¨æ·å·²ç¦ç¨"); |
| | | AfxMessageBox(msg); |
| | | } |
| | | else { |
| | | ShowErrorMessage(_T("æä½å¤±è´¥"), rc); |
| | | } |
| | | } |
| | | |
| | | void CUserManager2Dlg::OnLvnItemchangedUsers(NMHDR* /*pNMHDR*/, LRESULT* pResult) |
| | | { |
| | | UpdateButtonState(); |
| | | *pResult = 0; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | |
| | | #include "CUserManager2.h" |
| | | #include <string> |
| | | #include <vector> |
| | | |
| | | class CUserManager2Dlg : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CUserManager2Dlg) |
| | | |
| | | public: |
| | | CUserManager2Dlg(CWnd* pParent = nullptr); |
| | | virtual ~CUserManager2Dlg(); |
| | | |
| | | #ifdef AFX_DESIGN_TIME |
| | | enum { IDD = IDD_DIALOG_USER_MANAGER2 }; |
| | | #endif |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); |
| | | |
| | | DECLARE_MESSAGE_MAP() |
| | | public: |
| | | virtual BOOL OnInitDialog(); |
| | | afx_msg void OnSize(UINT nType, int cx, int cy); |
| | | afx_msg void OnBnClickedButtonAdd(); |
| | | afx_msg void OnBnClickedButtonEdit(); |
| | | afx_msg void OnBnClickedButtonDel(); |
| | | afx_msg void OnBnClickedButtonResetPwd(); |
| | | afx_msg void OnBnClickedButtonEnable(); |
| | | afx_msg void OnLvnItemchangedUsers(NMHDR* pNMHDR, LRESULT* pResult); |
| | | |
| | | private: |
| | | CListCtrl m_listUsers; |
| | | std::vector<CUserManager2::UserInfo> m_users; |
| | | |
| | | void InitList(); |
| | | void RefreshUserList(); |
| | | void UpdateButtonState(); |
| | | int GetSelectedIndex() const; |
| | | const CUserManager2::UserInfo* GetSelectedUser() const; |
| | | std::wstring ToWString(const CString& text) const; |
| | | void ShowErrorMessage(const CString& action, int code); |
| | | bool IsCurrentUser(const CUserManager2::UserInfo& info) const; |
| | | }; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include "Servo.h" |
| | | #include "CUserXLogDlg.h" |
| | | #include "afxdialogex.h" |
| | | #include <functional> |
| | | #include <vector> |
| | | #include <sstream> |
| | | |
| | | namespace |
| | | { |
| | | std::wstring ReadBufferVia(const std::function<int(wchar_t*, int)>& fn) |
| | | { |
| | | int need = fn(nullptr, 0); |
| | | if (need <= 0) { |
| | | return L""; |
| | | } |
| | | |
| | | std::wstring buffer; |
| | | buffer.resize(static_cast<size_t>(need)); |
| | | if (fn(buffer.data(), need) == UX_OK) { |
| | | if (!buffer.empty() && buffer.back() == L'\0') { |
| | | buffer.pop_back(); |
| | | } |
| | | return buffer; |
| | | } |
| | | |
| | | return L""; |
| | | } |
| | | |
| | | std::vector<std::wstring> SplitLines(const std::wstring& text) |
| | | { |
| | | std::vector<std::wstring> lines; |
| | | std::wstringstream ss(text); |
| | | std::wstring line; |
| | | while (std::getline(ss, line)) { |
| | | lines.push_back(line); |
| | | } |
| | | return lines; |
| | | } |
| | | } |
| | | |
| | | IMPLEMENT_DYNAMIC(CUserXLogDlg, CDialogEx) |
| | | |
| | | CUserXLogDlg::CUserXLogDlg(CWnd* pParent) |
| | | : CDialogEx(IDD_DIALOG_USERX_LOG, pParent) |
| | | { |
| | | } |
| | | |
| | | CUserXLogDlg::~CUserXLogDlg() |
| | | { |
| | | } |
| | | |
| | | void CUserXLogDlg::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | DDX_Control(pDX, IDC_LIST1, m_listLogs); |
| | | } |
| | | |
| | | BEGIN_MESSAGE_MAP(CUserXLogDlg, CDialogEx) |
| | | ON_WM_SIZE() |
| | | ON_WM_DESTROY() |
| | | END_MESSAGE_MAP() |
| | | |
| | | BOOL CUserXLogDlg::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | |
| | | InitListCtrl(); |
| | | RefreshLogs(); |
| | | AdjustLayout(); |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | void CUserXLogDlg::InitListCtrl() |
| | | { |
| | | DWORD dwStyle = m_listLogs.GetExtendedStyle(); |
| | | m_listLogs.SetExtendedStyle(dwStyle | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES); |
| | | m_listLogs.InsertColumn(0, _T("æ¶é´"), LVCFMT_LEFT, 180); |
| | | m_listLogs.InsertColumn(1, _T("ç¨æ·"), LVCFMT_LEFT, 120); |
| | | m_listLogs.InsertColumn(2, _T("å¨ä½"), LVCFMT_LEFT, 120); |
| | | m_listLogs.InsertColumn(3, _T("æè¿°"), LVCFMT_LEFT, 200); |
| | | } |
| | | |
| | | void CUserXLogDlg::RefreshLogs() |
| | | { |
| | | m_logs.clear(); |
| | | m_listLogs.DeleteAllItems(); |
| | | |
| | | auto allLogs = ReadBufferVia([](wchar_t* buffer, int size) { |
| | | return UX_QueryLogs(200, buffer, size); |
| | | }); |
| | | |
| | | for (auto& rawLine : SplitLines(allLogs)) { |
| | | if (rawLine.empty()) continue; |
| | | |
| | | auto trim = [](std::wstring value) { |
| | | size_t first = value.find_first_not_of(L" \t\r\n"); |
| | | size_t last = value.find_last_not_of(L" \t\r\n"); |
| | | if (first == std::wstring::npos || last == std::wstring::npos) { |
| | | return std::wstring(); |
| | | } |
| | | return value.substr(first, last - first + 1); |
| | | }; |
| | | |
| | | auto takeField = [&](size_t& cursor) { |
| | | if (cursor == std::wstring::npos || cursor >= rawLine.length()) { |
| | | return std::wstring(); |
| | | } |
| | | size_t pos = rawLine.find(L',', cursor); |
| | | std::wstring part = (pos == std::wstring::npos) ? rawLine.substr(cursor) : rawLine.substr(cursor, pos - cursor); |
| | | cursor = (pos == std::wstring::npos) ? std::wstring::npos : pos + 1; |
| | | return trim(part); |
| | | }; |
| | | |
| | | size_t cursor = 0; |
| | | LogItem item; |
| | | item.time = takeField(cursor).c_str(); |
| | | item.user = takeField(cursor).c_str(); |
| | | item.action = takeField(cursor).c_str(); |
| | | if (cursor != std::wstring::npos && cursor < rawLine.length()) { |
| | | item.detail = trim(rawLine.substr(cursor)).c_str(); |
| | | } |
| | | |
| | | m_logs.push_back(item); |
| | | } |
| | | |
| | | for (size_t i = 0; i < m_logs.size(); ++i) { |
| | | const auto& log = m_logs[i]; |
| | | int row = m_listLogs.InsertItem(static_cast<int>(i), log.time); |
| | | m_listLogs.SetItemText(row, 1, log.user); |
| | | m_listLogs.SetItemText(row, 2, log.action); |
| | | m_listLogs.SetItemText(row, 3, log.detail); |
| | | } |
| | | } |
| | | |
| | | void CUserXLogDlg::AdjustLayout() |
| | | { |
| | | if (!::IsWindow(m_listLogs.GetSafeHwnd())) { |
| | | return; |
| | | } |
| | | |
| | | CRect rcClient; |
| | | GetClientRect(&rcClient); |
| | | const int margin = 7; |
| | | |
| | | CRect rcList(margin, margin, rcClient.right - margin, rcClient.bottom - 40); |
| | | m_listLogs.MoveWindow(rcList); |
| | | |
| | | auto moveButton = [&](int id, int order) { |
| | | if (CWnd* pBtn = GetDlgItem(id)) { |
| | | CRect rc; |
| | | pBtn->GetWindowRect(&rc); |
| | | ScreenToClient(&rc); |
| | | int width = rc.Width(); |
| | | int height = rc.Height(); |
| | | rc.left = rcClient.right - margin - width - order * (width + margin); |
| | | rc.right = rc.left + width; |
| | | rc.top = rcClient.bottom - margin - height; |
| | | rc.bottom = rc.top + height; |
| | | pBtn->MoveWindow(rc); |
| | | } |
| | | }; |
| | | |
| | | moveButton(IDOK, 1); |
| | | moveButton(IDCANCEL, 0); |
| | | } |
| | | |
| | | void CUserXLogDlg::OnSize(UINT nType, int cx, int cy) |
| | | { |
| | | CDialogEx::OnSize(nType, cx, cy); |
| | | AdjustLayout(); |
| | | } |
| | | |
| | | void CUserXLogDlg::OnDestroy() |
| | | { |
| | | CDialogEx::OnDestroy(); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | |
| | | #include <vector> |
| | | #include <string> |
| | | |
| | | class CUserXLogDlg : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CUserXLogDlg) |
| | | |
| | | public: |
| | | CUserXLogDlg(CWnd* pParent = nullptr); |
| | | virtual ~CUserXLogDlg(); |
| | | |
| | | #ifdef AFX_DESIGN_TIME |
| | | enum { IDD = IDD_DIALOG_USERX_LOG }; |
| | | #endif |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); |
| | | |
| | | DECLARE_MESSAGE_MAP() |
| | | public: |
| | | virtual BOOL OnInitDialog(); |
| | | afx_msg void OnSize(UINT nType, int cx, int cy); |
| | | afx_msg void OnDestroy(); |
| | | |
| | | private: |
| | | struct LogItem |
| | | { |
| | | CString time; |
| | | CString user; |
| | | CString action; |
| | | CString detail; |
| | | }; |
| | | |
| | | CListCtrl m_listLogs; |
| | | std::vector<LogItem> m_logs; |
| | | |
| | | void InitListCtrl(); |
| | | void RefreshLogs(); |
| | | void AdjustLayout(); |
| | | }; |
| | |
| | | |
| | | int CHsmsPassive::loadVarialbles(const char* pszFilepath) |
| | | { |
| | | CStdioFile file; |
| | | if (!file.Open(pszFilepath, CFile::modeRead)) { |
| | | m_strVariableFilepath = pszFilepath; |
| | | m_bVariableUtf8 = false; |
| | | m_bVariableUtf8Bom = false; |
| | | // å
读åå§åèï¼åç»åæ UTF-8/BOM ææ¬å°ç¼ç è½¬æ¢ |
| | | CFile file; |
| | | if (!file.Open(pszFilepath, CFile::modeRead | CFile::shareDenyNone)) { |
| | | return -1; |
| | | } |
| | | |
| | | std::regex pattern("^\\d+,.*"); // å¹é
以æ°å+éå·å¼å¤´çå符串 |
| | | const ULONGLONG nLen = file.GetLength(); |
| | | if (nLen == 0) { |
| | | return -1; |
| | | } |
| | | |
| | | std::string buffer; |
| | | buffer.resize(static_cast<size_t>(nLen)); |
| | | file.Read(buffer.data(), static_cast<UINT>(nLen)); |
| | | file.Close(); |
| | | |
| | | const unsigned char* bytes = reinterpret_cast<const unsigned char*>(buffer.data()); |
| | | size_t offset = 0; |
| | | CStringW content; |
| | | |
| | | // UTF-8 BOM |
| | | if (nLen >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) { |
| | | offset = 3; |
| | | m_bVariableUtf8 = true; |
| | | m_bVariableUtf8Bom = true; |
| | | } |
| | | |
| | | // UTF-16 LE BOM |
| | | if (nLen >= 2 && bytes[0] == 0xFF && bytes[1] == 0xFE) { |
| | | const wchar_t* wdata = reinterpret_cast<const wchar_t*>(buffer.data() + 2); |
| | | const size_t wlen = (nLen - 2) / sizeof(wchar_t); |
| | | content.SetString(wdata, static_cast<int>(wlen)); |
| | | } |
| | | // UTF-16 BE BOM |
| | | else if (nLen >= 2 && bytes[0] == 0xFE && bytes[1] == 0xFF) { |
| | | const size_t wlen = (nLen - 2) / sizeof(wchar_t); |
| | | std::wstring temp; |
| | | temp.reserve(wlen); |
| | | for (size_t i = 0; i < wlen; ++i) { |
| | | wchar_t ch = static_cast<wchar_t>(bytes[2 + i * 2] << 8 | bytes[2 + i * 2 + 1]); |
| | | temp.push_back(ch); |
| | | } |
| | | content = temp.c_str(); |
| | | } |
| | | // å°è¯ UTF-8ï¼å«æ BOMï¼ |
| | | else { |
| | | auto tryUtf8 = [&](size_t off) -> bool { |
| | | int need = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, buffer.data() + off, |
| | | static_cast<int>(buffer.size() - off), nullptr, 0); |
| | | if (need <= 0) return false; |
| | | std::wstring temp; |
| | | temp.resize(need); |
| | | MultiByteToWideChar(CP_UTF8, 0, buffer.data() + off, |
| | | static_cast<int>(buffer.size() - off), temp.data(), need); |
| | | content = temp.c_str(); |
| | | m_bVariableUtf8 = true; |
| | | return true; |
| | | }; |
| | | |
| | | if (!tryUtf8(offset)) { |
| | | // åéå°æ¬å°ä»£ç 页 |
| | | int need = MultiByteToWideChar(CP_ACP, 0, buffer.data(), static_cast<int>(buffer.size()), nullptr, 0); |
| | | if (need > 0) { |
| | | std::wstring temp; |
| | | temp.resize(need); |
| | | MultiByteToWideChar(CP_ACP, 0, buffer.data(), static_cast<int>(buffer.size()), temp.data(), need); |
| | | content = temp.c_str(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (content.IsEmpty()) { |
| | | return -1; |
| | | } |
| | | |
| | | std::wregex pattern(L"^\\d+,.+"); // å¹é
以æ°å+éå·å¼å¤´çå符串 |
| | | std::vector<SERVO::CVariable*> variables; |
| | | int index, last; |
| | | CString strLine; |
| | | CString strId, strName, strFormat, strRemark; |
| | | while (file.ReadString(strLine)) { |
| | | if (!std::regex_match((LPTSTR)(LPCTSTR)strLine, pattern)) { |
| | | CStringW strLine; |
| | | CStringW strId, strName, strFormat, strRemark; |
| | | std::wstringstream ss(content.GetString()); |
| | | auto narrowFromW = [](const CStringW& s) -> std::string { |
| | | int need = WideCharToMultiByte(CP_ACP, 0, s, -1, nullptr, 0, nullptr, nullptr); |
| | | if (need <= 0) return {}; |
| | | std::string out(static_cast<size_t>(need - 1), '\0'); |
| | | WideCharToMultiByte(CP_ACP, 0, s, -1, out.data(), need, nullptr, nullptr); |
| | | return out; |
| | | }; |
| | | std::wstring line; |
| | | while (std::getline(ss, line, L'\n')) { |
| | | strLine = line.c_str(); |
| | | strLine.Trim(); |
| | | if (strLine.IsEmpty()) continue; |
| | | if (!std::regex_match(static_cast<LPCWSTR>(strLine), pattern)) { |
| | | continue; |
| | | } |
| | | |
| | | last = 0; |
| | | index = strLine.Find(",", last); |
| | | index = strLine.Find(L",", last); |
| | | if (index < 0) continue; |
| | | strId = strLine.Left(index); |
| | | last = index + 1; |
| | | |
| | | index = strLine.Find(",", last); |
| | | index = strLine.Find(L",", last); |
| | | if (index < 0) continue; |
| | | strName = strLine.Mid(last, index - last); |
| | | last = index + 1; |
| | | |
| | | index = strLine.Find(",", last); |
| | | index = strLine.Find(L",", last); |
| | | if (index < 0) continue; |
| | | strFormat = strLine.Mid(last, index - last); |
| | | strRemark = strLine.Right(strLine.GetLength() - index - 1); |
| | | strRemark.Replace(_T("\\r\\n"), _T("\r\n")); |
| | | strRemark.Replace(L"\\r\\n", L"\r\n"); |
| | | |
| | | std::string sId = narrowFromW(strId); |
| | | std::string sName = narrowFromW(strName); |
| | | std::string sFormat = narrowFromW(strFormat); |
| | | std::string sRemark = narrowFromW(strRemark); |
| | | |
| | | SERVO::CVariable* pVarialble = new SERVO::CVariable( |
| | | (LPTSTR)(LPCTSTR)strId, (LPTSTR)(LPCTSTR)strName, (LPTSTR)(LPCTSTR)strFormat, (LPTSTR)(LPCTSTR)strRemark); |
| | | sId.c_str(), |
| | | sName.c_str(), |
| | | sFormat.c_str(), |
| | | sRemark.c_str()); |
| | | variables.push_back(pVarialble); |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | file.Close(); |
| | | return 0; |
| | | } |
| | | |
| | |
| | | m_variabels.clear(); |
| | | } |
| | | |
| | | CStringA WideToUtf8(const CStringW& ws) |
| | | { |
| | | int need = WideCharToMultiByte(CP_UTF8, 0, ws, -1, nullptr, 0, nullptr, nullptr); |
| | | if (need <= 0) return ""; |
| | | CStringA out; |
| | | LPSTR buf = out.GetBufferSetLength(need - 1); |
| | | WideCharToMultiByte(CP_UTF8, 0, ws, -1, buf, need, nullptr, nullptr); |
| | | out.ReleaseBuffer(); |
| | | return out; |
| | | } |
| | | |
| | | CStringA WideToAnsi(const CStringW& ws) |
| | | { |
| | | int need = WideCharToMultiByte(CP_ACP, 0, ws, -1, nullptr, 0, nullptr, nullptr); |
| | | if (need <= 0) return ""; |
| | | CStringA out; |
| | | LPSTR buf = out.GetBufferSetLength(need - 1); |
| | | WideCharToMultiByte(CP_ACP, 0, ws, -1, buf, need, nullptr, nullptr); |
| | | out.ReleaseBuffer(); |
| | | return out; |
| | | } |
| | | |
| | | static CStringA AnsiToUtf8(const std::string& s) |
| | | { |
| | | int wlen = MultiByteToWideChar(CP_ACP, 0, s.c_str(), -1, nullptr, 0); |
| | | if (wlen <= 0) return ""; |
| | | CStringW ws; |
| | | LPWSTR wbuf = ws.GetBufferSetLength(wlen - 1); |
| | | MultiByteToWideChar(CP_ACP, 0, s.c_str(), -1, wbuf, wlen); |
| | | ws.ReleaseBuffer(); |
| | | return WideToUtf8(ws); |
| | | } |
| | | |
| | | int CHsmsPassive::deleteVariable(int variableId) |
| | | { |
| | | Lock(); |
| | | auto it = std::find_if(m_variabels.begin(), m_variabels.end(), [=](SERVO::CVariable* v) { |
| | | return v != nullptr && v->getVarialbleId() == variableId; |
| | | }); |
| | | if (it == m_variabels.end()) { |
| | | Unlock(); |
| | | return -1; |
| | | } |
| | | delete *it; |
| | | m_variabels.erase(it); |
| | | auto filepath = m_strVariableFilepath; |
| | | Unlock(); |
| | | |
| | | if (filepath.empty()) return -2; |
| | | |
| | | // ååæä»¶ï¼ä¿æåç¼ç ï¼UTF-8 ææ¬å°ç¼ç ï¼ |
| | | CFile file; |
| | | if (!file.Open(filepath.c_str(), CFile::modeCreate | CFile::modeWrite | CFile::shareDenyNone)) { |
| | | return -3; |
| | | } |
| | | |
| | | // header |
| | | const std::string headerAnsi = "SVID,SV Name,SV Format,SV Remark\r\n"; |
| | | if (m_bVariableUtf8) { |
| | | if (m_bVariableUtf8Bom) { |
| | | const BYTE bom[3] = { 0xEF, 0xBB, 0xBF }; |
| | | file.Write(bom, 3); |
| | | } |
| | | CStringA header = AnsiToUtf8(headerAnsi); |
| | | file.Write(header.GetString(), header.GetLength()); |
| | | } |
| | | else { |
| | | file.Write(headerAnsi.data(), (UINT)headerAnsi.size()); |
| | | } |
| | | |
| | | for (auto v : m_variabels) { |
| | | if (v == nullptr) continue; |
| | | std::string lineAnsi; |
| | | lineAnsi.reserve(256); |
| | | lineAnsi += std::to_string(v->getVarialbleId()); |
| | | lineAnsi.push_back(','); |
| | | lineAnsi += v->getName(); |
| | | lineAnsi.push_back(','); |
| | | lineAnsi += SERVO::CVariable::formatToString(v->getFormat()); |
| | | lineAnsi.push_back(','); |
| | | lineAnsi += v->getRemark(); |
| | | lineAnsi.append("\r\n"); |
| | | |
| | | if (m_bVariableUtf8) { |
| | | CStringA outLine = AnsiToUtf8(lineAnsi); |
| | | file.Write(outLine.GetString(), outLine.GetLength()); |
| | | } |
| | | else { |
| | | file.Write(lineAnsi.data(), (UINT)lineAnsi.size()); |
| | | } |
| | | } |
| | | file.Close(); |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | void CHsmsPassive::setVariableValue(const char* pszName, __int64 value) |
| | | { |
| | | auto v = getVariable(pszName); |
| | |
| | | |
| | | int CHsmsPassive::loadReports(const char* pszFilepath) |
| | | { |
| | | CStdioFile file; |
| | | if (!file.Open(pszFilepath, CFile::modeRead)) { |
| | | // å
¼å®¹ UTF-8/BOM 䏿¬å°ç¼ç 读å |
| | | CFile file; |
| | | if (!file.Open(pszFilepath, CFile::modeRead | CFile::shareDenyNone)) { |
| | | return -1; |
| | | } |
| | | |
| | | std::regex pattern("^\\d+,\\(\\d+(,\\d+)*\\).*"); // å¹é
以æ°å+éå·å¼å¤´çå符串 |
| | | const ULONGLONG nLen = file.GetLength(); |
| | | if (nLen == 0) { |
| | | return -1; |
| | | } |
| | | |
| | | std::string buffer; |
| | | buffer.resize(static_cast<size_t>(nLen)); |
| | | file.Read(buffer.data(), static_cast<UINT>(nLen)); |
| | | file.Close(); |
| | | |
| | | const unsigned char* bytes = reinterpret_cast<const unsigned char*>(buffer.data()); |
| | | size_t offset = 0; |
| | | CStringW content; |
| | | |
| | | // UTF-8 BOM |
| | | if (nLen >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) { |
| | | offset = 3; |
| | | } |
| | | |
| | | // UTF-16 LE BOM |
| | | if (nLen >= 2 && bytes[0] == 0xFF && bytes[1] == 0xFE) { |
| | | const wchar_t* wdata = reinterpret_cast<const wchar_t*>(buffer.data() + 2); |
| | | const size_t wlen = (nLen - 2) / sizeof(wchar_t); |
| | | content.SetString(wdata, static_cast<int>(wlen)); |
| | | } |
| | | // UTF-16 BE BOM |
| | | else if (nLen >= 2 && bytes[0] == 0xFE && bytes[1] == 0xFF) { |
| | | const size_t wlen = (nLen - 2) / sizeof(wchar_t); |
| | | std::wstring temp; |
| | | temp.reserve(wlen); |
| | | for (size_t i = 0; i < wlen; ++i) { |
| | | wchar_t ch = static_cast<wchar_t>(bytes[2 + i * 2] << 8 | bytes[2 + i * 2 + 1]); |
| | | temp.push_back(ch); |
| | | } |
| | | content = temp.c_str(); |
| | | } |
| | | else { |
| | | auto tryUtf8 = [&](size_t off) -> bool { |
| | | int need = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, buffer.data() + off, |
| | | static_cast<int>(buffer.size() - off), nullptr, 0); |
| | | if (need <= 0) return false; |
| | | std::wstring temp; |
| | | temp.resize(need); |
| | | MultiByteToWideChar(CP_UTF8, 0, buffer.data() + off, |
| | | static_cast<int>(buffer.size() - off), temp.data(), need); |
| | | content = temp.c_str(); |
| | | return true; |
| | | }; |
| | | |
| | | if (!tryUtf8(offset)) { |
| | | int need = MultiByteToWideChar(CP_ACP, 0, buffer.data(), static_cast<int>(buffer.size()), nullptr, 0); |
| | | if (need > 0) { |
| | | std::wstring temp; |
| | | temp.resize(need); |
| | | MultiByteToWideChar(CP_ACP, 0, buffer.data(), static_cast<int>(buffer.size()), temp.data(), need); |
| | | content = temp.c_str(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (content.IsEmpty()) { |
| | | return -1; |
| | | } |
| | | |
| | | std::wregex pattern(L"^\\d+,\\(\\d+(,\\d+)*\\).*"); // å¹é
以æ°å+éå·å¼å¤´çå符串 |
| | | std::vector<SERVO::CReport*> reports; |
| | | int index; |
| | | CString strLine, strVariable; |
| | | CString strId; |
| | | while (file.ReadString(strLine)) { |
| | | if (!std::regex_match((LPTSTR)(LPCTSTR)strLine, pattern)) { |
| | | CStringW strLine, strVariable; |
| | | CStringW strId; |
| | | std::wstringstream ss(content.GetString()); |
| | | auto narrowFromW = [](const CStringW& s) -> std::string { |
| | | int need = WideCharToMultiByte(CP_ACP, 0, s, -1, nullptr, 0, nullptr, nullptr); |
| | | if (need <= 0) return {}; |
| | | std::string out(static_cast<size_t>(need - 1), '\0'); |
| | | WideCharToMultiByte(CP_ACP, 0, s, -1, out.data(), need, nullptr, nullptr); |
| | | return out; |
| | | }; |
| | | std::wstring line; |
| | | while (std::getline(ss, line, L'\n')) { |
| | | strLine = line.c_str(); |
| | | strLine.Trim(); |
| | | if (strLine.IsEmpty()) continue; |
| | | if (!std::regex_match(static_cast<LPCWSTR>(strLine), pattern)) { |
| | | continue; |
| | | } |
| | | |
| | | index = strLine.Find(",", 0); |
| | | index = strLine.Find(L",", 0); |
| | | if (index < 0) continue; |
| | | strId = strLine.Left(index); |
| | | strVariable = strLine.Right(strLine.GetLength() - index - 1); |
| | | strVariable.Delete(0); |
| | | strVariable.Delete(strVariable.GetLength() - 1); |
| | | auto vids = parseVidList(strVariable); |
| | | CString strVariableA(narrowFromW(strVariable).c_str()); |
| | | auto vids = parseVidList(strVariableA); |
| | | |
| | | SERVO::CReport* pReport = new SERVO::CReport(atoi((LPTSTR)(LPCTSTR)strId), vids); |
| | | SERVO::CReport* pReport = new SERVO::CReport(_wtoi(strId), vids); |
| | | for (auto vid : vids) { |
| | | SERVO::CVariable* pVariable = getVariable(vid); |
| | | if (pVariable != nullptr) { |
| | |
| | | } |
| | | |
| | | |
| | | file.Close(); |
| | | return 0; |
| | | } |
| | | |
| | |
| | | |
| | | int CHsmsPassive::loadCollectionEvents(const char* pszFilepath) |
| | | { |
| | | CStdioFile file; |
| | | if (!file.Open(pszFilepath, CFile::modeRead)) { |
| | | CFile file; |
| | | if (!file.Open(pszFilepath, CFile::modeRead | CFile::shareDenyNone)) { |
| | | return -1; |
| | | } |
| | | |
| | | std::regex pattern("^\\d+,[^,]*,[^,]*,\\(\\d+(,\\d+)*\\).*"); // å¹é
以æ°å+éå·å¼å¤´çå符串 |
| | | const ULONGLONG nLen = file.GetLength(); |
| | | if (nLen == 0) { |
| | | return -1; |
| | | } |
| | | |
| | | std::string buffer; |
| | | buffer.resize(static_cast<size_t>(nLen)); |
| | | file.Read(buffer.data(), static_cast<UINT>(nLen)); |
| | | file.Close(); |
| | | |
| | | const unsigned char* bytes = reinterpret_cast<const unsigned char*>(buffer.data()); |
| | | size_t offset = 0; |
| | | CStringW content; |
| | | |
| | | // UTF-8 BOM |
| | | if (nLen >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) { |
| | | offset = 3; |
| | | } |
| | | |
| | | // UTF-16 LE BOM |
| | | if (nLen >= 2 && bytes[0] == 0xFF && bytes[1] == 0xFE) { |
| | | const wchar_t* wdata = reinterpret_cast<const wchar_t*>(buffer.data() + 2); |
| | | const size_t wlen = (nLen - 2) / sizeof(wchar_t); |
| | | content.SetString(wdata, static_cast<int>(wlen)); |
| | | } |
| | | // UTF-16 BE BOM |
| | | else if (nLen >= 2 && bytes[0] == 0xFE && bytes[1] == 0xFF) { |
| | | const size_t wlen = (nLen - 2) / sizeof(wchar_t); |
| | | std::wstring temp; |
| | | temp.reserve(wlen); |
| | | for (size_t i = 0; i < wlen; ++i) { |
| | | wchar_t ch = static_cast<wchar_t>(bytes[2 + i * 2] << 8 | bytes[2 + i * 2 + 1]); |
| | | temp.push_back(ch); |
| | | } |
| | | content = temp.c_str(); |
| | | } |
| | | else { |
| | | auto tryUtf8 = [&](size_t off) -> bool { |
| | | int need = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, buffer.data() + off, |
| | | static_cast<int>(buffer.size() - off), nullptr, 0); |
| | | if (need <= 0) return false; |
| | | std::wstring temp; |
| | | temp.resize(need); |
| | | MultiByteToWideChar(CP_UTF8, 0, buffer.data() + off, |
| | | static_cast<int>(buffer.size() - off), temp.data(), need); |
| | | content = temp.c_str(); |
| | | return true; |
| | | }; |
| | | |
| | | if (!tryUtf8(offset)) { |
| | | int need = MultiByteToWideChar(CP_ACP, 0, buffer.data(), static_cast<int>(buffer.size()), nullptr, 0); |
| | | if (need > 0) { |
| | | std::wstring temp; |
| | | temp.resize(need); |
| | | MultiByteToWideChar(CP_ACP, 0, buffer.data(), static_cast<int>(buffer.size()), temp.data(), need); |
| | | content = temp.c_str(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (content.IsEmpty()) { |
| | | return -1; |
| | | } |
| | | |
| | | std::wregex pattern(L"^\\d+,[^,]*,[^,]*,\\(\\d+(,\\d+)*\\).*"); // å¹é
以æ°å+éå·å¼å¤´çå符串 |
| | | std::vector<SERVO::CCollectionEvent*> events; |
| | | int index, last; |
| | | CString strLine, strRPTIDs; |
| | | CString strId, strName, strDescription; |
| | | while (file.ReadString(strLine)) { |
| | | if (!std::regex_match((LPTSTR)(LPCTSTR)strLine, pattern)) { |
| | | CStringW strLine, strRPTIDs; |
| | | CStringW strId, strName, strDescription; |
| | | std::wstringstream ss(content.GetString()); |
| | | auto narrowFromW = [](const CStringW& s) -> std::string { |
| | | int need = WideCharToMultiByte(CP_ACP, 0, s, -1, nullptr, 0, nullptr, nullptr); |
| | | if (need <= 0) return {}; |
| | | std::string out(static_cast<size_t>(need - 1), '\0'); |
| | | WideCharToMultiByte(CP_ACP, 0, s, -1, out.data(), need, nullptr, nullptr); |
| | | return out; |
| | | }; |
| | | std::wstring line; |
| | | while (std::getline(ss, line, L'\n')) { |
| | | strLine = line.c_str(); |
| | | strLine.Trim(); |
| | | if (strLine.IsEmpty()) continue; |
| | | if (!std::regex_match(static_cast<LPCWSTR>(strLine), pattern)) { |
| | | continue; |
| | | } |
| | | |
| | | last = 0; |
| | | index = strLine.Find(",", last); |
| | | index = strLine.Find(L",", last); |
| | | if (index < 0) continue; |
| | | strId = strLine.Left(index); |
| | | last = index + 1; |
| | | |
| | | index = strLine.Find(",", last); |
| | | index = strLine.Find(L",", last); |
| | | if (index < 0) continue; |
| | | strName = strLine.Mid(last, index - last); |
| | | last = index + 1; |
| | | |
| | | index = strLine.Find(",", last); |
| | | index = strLine.Find(L",", last); |
| | | if (index < 0) continue; |
| | | strDescription = strLine.Mid(last, index - last); |
| | | strRPTIDs = strLine.Right(strLine.GetLength() - index - 1); |
| | | strRPTIDs.Delete(0); |
| | | strRPTIDs.Delete(strRPTIDs.GetLength() - 1); |
| | | auto prtids = parseVidList(strRPTIDs); |
| | | CString strRPTIDsA(narrowFromW(strRPTIDs).c_str()); |
| | | auto prtids = parseVidList(strRPTIDsA); |
| | | |
| | | std::string sName = narrowFromW(strName); |
| | | std::string sDesc = narrowFromW(strDescription); |
| | | |
| | | SERVO::CCollectionEvent* pEvent = new SERVO::CCollectionEvent( |
| | | atoi(strId), (LPTSTR)(LPCTSTR)strName, (LPTSTR)(LPCTSTR)strDescription, prtids); |
| | | _wtoi(strId), sName.c_str(), sDesc.c_str(), prtids); |
| | | for (auto rptid : prtids) { |
| | | SERVO::CReport* pReport = getReport(rptid); |
| | | if (pReport != nullptr) { |
| | |
| | | m_collectionEvents.push_back(item); |
| | | } |
| | | } |
| | | |
| | | |
| | | file.Close(); |
| | | return 0; |
| | | } |
| | | |
| | |
| | | return requestEventReportSend("Panel_End"); |
| | | } |
| | | |
| | | int CHsmsPassive::requestEventReportSend_OCR_PanelID_Read_OK() |
| | | { |
| | | return requestEventReportSend("OCR_PanelID_Read_OK"); |
| | | } |
| | | |
| | | |
| | | |
| | |
| | | #pragma once |
| | | #pragma once |
| | | #include <string> |
| | | #include <list> |
| | | #include "HsmsAction.h" |
| | |
| | | #define CAACK_6 6 /* command performed with errors */ |
| | | |
| | | /* |
| | | * 叏鿰æ®ç»æ |
| | | * 叏鿰æ®ç»æ |
| | | */ |
| | | typedef struct _EQConstant |
| | | { |
| | |
| | | } EQConstant; |
| | | |
| | | /* |
| | | * Command æ°æ®ç»æ |
| | | * Command æ°æ®ç»æ |
| | | */ |
| | | typedef struct _CommandParameter |
| | | { |
| | |
| | | } CommandParameter; |
| | | |
| | | /* |
| | | * Report æ°æ®ç»æ |
| | | * Report æ°æ®ç»æ |
| | | */ |
| | | typedef struct _REPORT |
| | | { |
| | |
| | | } REPORT; |
| | | |
| | | /* |
| | | * Value æ°æ®ç»æ |
| | | * Value æ°æ®ç»æ |
| | | */ |
| | | typedef struct _VALUE |
| | | { |
| | |
| | | ~CHsmsPassive(); |
| | | |
| | | public: |
| | | /* 设置æºå¨åå· æå¤§é¿åº¦ 20 bytes */ |
| | | /* 设置æºå¨åå· æå¤§é¿åº¦ 20 bytes */ |
| | | void setEquipmentModelType(const char* pszMode); |
| | | |
| | | /* è®¾ç½®è½¯ä»¶çæ¬å· æå¤§é¿åº¦ 20 bytes */ |
| | | /* è®¾ç½®è½¯ä»¶çæ¬å· æå¤§é¿åº¦ 20 bytes */ |
| | | void setSoftRev(const char* pszRev); |
| | | |
| | | /* æ·»å åéå¼å°ISECS2Item */ |
| | | /* æ·»å åéå¼å°ISECS2Item */ |
| | | void addVariableValueToItem(ISECS2Item* pParent, SERVO::CVariable* pVariable); |
| | | |
| | | // è¿æ¥Report |
| | | // è¿æ¥Report |
| | | void linkEventReport(unsigned int CEID, unsigned int RPTID); |
| | | |
| | | // åæ¶è¿æ¥report |
| | | // åæ¶è¿æ¥report |
| | | void unlinkEventReport(unsigned int CEID); |
| | | |
| | | // define Report |
| | | SERVO::CReport* defineReport(unsigned int RPTID, std::vector<unsigned int>& vids); |
| | | |
| | | // åæ¶ define report |
| | | // åæ¶ define report |
| | | bool removeReport(int rptid); |
| | | void clearAllReport(); |
| | | |
| | | // 仿件ä¸å è½½CVariableå表 |
| | | // 仿件ä¸å è½½CVariableå表 |
| | | int loadVarialbles(const char* pszFilepath); |
| | | |
| | | // åå¾CVariableå表 |
| | | // åå¾CVariableå表 |
| | | std::vector<SERVO::CVariable*>& getVariables(); |
| | | |
| | | // å徿å®Variable |
| | | // å徿å®Variable |
| | | SERVO::CVariable* getVariable(int variableId); |
| | | SERVO::CVariable* getVariable(const char* pszName); |
| | | int deleteVariable(int variableId); |
| | | |
| | | // 设置åéå¼ |
| | | // 设置åéå¼ |
| | | void setVariableValue(const char* pszName, __int64 value); |
| | | void setVariableValue(const char* pszName, const char* value); |
| | | void setVariableValue(const char* pszName, std::vector<SERVO::CVariable>& vars); |
| | | |
| | | // 仿件ä¸å è½½CReportå表 |
| | | // 仿件ä¸å è½½CReportå表 |
| | | int loadReports(const char* pszFilepath); |
| | | |
| | | // åå¾Reportå表 |
| | | // åå¾Reportå表 |
| | | std::vector<SERVO::CReport*>& getReports(); |
| | | |
| | | // 仿件ä¸å è½½CCollectionEventå表 |
| | | // 仿件ä¸å è½½CCollectionEventå表 |
| | | int loadCollectionEvents(const char* pszFilepath); |
| | | |
| | | // åå¾CCollectionEventå表 |
| | | // åå¾CCollectionEventå表 |
| | | std::vector<SERVO::CCollectionEvent*>& getCollectionEvents(); |
| | | |
| | | // åæ¶/å 餿æCollectionEvent |
| | | // åæ¶/å 餿æCollectionEvent |
| | | void clearAllCollectionEvent(); |
| | | |
| | | // åå¾CCollectionEvent |
| | | // åå¾CCollectionEvent |
| | | SERVO::CCollectionEvent* getEvent(unsigned short CEID); |
| | | |
| | | // åå¾Report |
| | | // åå¾Report |
| | | SERVO::CReport* getReport(int rptid); |
| | | |
| | | void setListener(SECSListener listener); |
| | |
| | | int unserialize(const char* pszBuffer, int nBufferSize); |
| | | |
| | | public: |
| | | /* requestå¼å¤´ç彿°ä¸ºä¸»å¨åéæ°æ®ç彿° */ |
| | | /* requestå¼å¤´ç彿°ä¸ºä¸»å¨åéæ°æ®ç彿° */ |
| | | int requestAreYouThere(); |
| | | int requestAlarmReport(int ALCD, int ALID, const char* ALTX); |
| | | int requestEventReportSend(unsigned int CEID); |
| | |
| | | int requestEventReportSend_CJ_End(); |
| | | int requestEventReportSend_Panel_Start(); |
| | | int requestEventReportSend_Panel_End(); |
| | | int requestEventReportSend_OCR_PanelID_Read_OK(); |
| | | |
| | | private: |
| | | void replyAck(int s, int f, unsigned int systemBytes, BYTE ack, const char* pszAckName); |
| | | |
| | | /* replyå¼å¤´ç彿°ä¸ºåå¤å½æ° */ |
| | | /* replyå¼å¤´ç彿°ä¸ºåå¤å½æ° */ |
| | | int replyAreYouThere(IMessage* pRecv); |
| | | int replyEstablishCommunications(IMessage* pRecv); |
| | | int replySelectedEquipmentStatusData(IMessage* pRecv); |
| | |
| | | |
| | | private: |
| | | SECSListener m_listener; |
| | | std::string m_strVariableFilepath; |
| | | bool m_bVariableUtf8{ false }; |
| | | bool m_bVariableUtf8Bom{ false }; |
| | | BOOL m_bCimWorking; |
| | | HANDLE m_hCimWorkEvent; |
| | | HANDLE m_hCimWorkThreadHandle; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // LoginDlg.cpp: å®ç°æä»¶ |
| | | // |
| | | |
| | | #include "stdafx.h" |
| | | #include "Servo.h" |
| | | #include "afxdialogex.h" |
| | | #include "LoginDlg2.h" |
| | | |
| | | |
| | | // CLoginDlg å¯¹è¯æ¡ |
| | | |
| | | IMPLEMENT_DYNAMIC(CLoginDlg2, CDialogEx) |
| | | |
| | | CLoginDlg2::CLoginDlg2(CWnd* pParent /*=nullptr*/) |
| | | : CDialogEx(IDD_DIALOG_LOGIN, pParent) |
| | | { |
| | | } |
| | | |
| | | CLoginDlg2::~CLoginDlg2() |
| | | { |
| | | } |
| | | |
| | | void CLoginDlg2::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | } |
| | | |
| | | |
| | | BEGIN_MESSAGE_MAP(CLoginDlg2, CDialogEx) |
| | | ON_BN_CLICKED(IDC_BUTTON_LOGIN, &CLoginDlg2::OnBnClickedLogin) |
| | | ON_STN_CLICKED(IDC_STATIC_CHANGE_PASSWORD, &CLoginDlg2::OnBnClickedChangePassword) |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | | // CLoginDlg æ¶æ¯å¤çç¨åº |
| | | |
| | | |
| | | BOOL CLoginDlg2::OnInitDialog() |
| | | { |
| | | CDialog::OnInitDialog(); |
| | | |
| | | // 设置çªå£æ é¢ååå§å¼ |
| | | SetWindowText(_T("ç»å½")); |
| | | |
| | | |
| | | CStatic* pStaticImage = (CStatic*)GetDlgItem(IDC_STATIC_IMAGE); |
| | | ASSERT(pStaticImage); |
| | | |
| | | 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 æ§ä»¶ä¸ºå¾æ æ ·å¼ |
| | | pStaticImage->ModifyStyle(0xF, SS_ICON); |
| | | pStaticImage->SetIcon(hIcon); |
| | | } |
| | | |
| | | // æ·»å SS_NOTIFYæ ·å¼ |
| | | CStatic* pStatic = (CStatic*)GetDlgItem(IDC_STATIC_CHANGE_PASSWORD); |
| | | if (pStatic != nullptr) { |
| | | pStatic->ModifyStyle(0, SS_NOTIFY); |
| | | } |
| | | |
| | | GetDlgItem(IDC_CHECK_REMEMBER_PASSWORD)->ShowWindow(SW_HIDE); |
| | | |
| | | |
| | | // test |
| | | SetDlgItemText(IDC_EDIT_USERNAME, _T("admin")); |
| | | SetDlgItemText(IDC_EDIT_PASSWORD, _T("admin123")); |
| | | |
| | | return TRUE; |
| | | } |
| | | |
| | | void CLoginDlg2::OnBnClickedLogin() |
| | | { |
| | | GetDlgItemText(IDC_EDIT_USERNAME, m_strUsername); |
| | | GetDlgItemText(IDC_EDIT_PASSWORD, m_strPassword); |
| | | |
| | | if (m_strUsername.IsEmpty()) { |
| | | AfxMessageBox(_T("请è¾å
¥ç¨æ·å")); |
| | | GetDlgItem(IDC_EDIT_USERNAME)->SetFocus(); |
| | | return; |
| | | } |
| | | if (m_strPassword.IsEmpty()) { |
| | | AfxMessageBox(_T("请è¾å
¥å¯ç ")); |
| | | GetDlgItem(IDC_EDIT_PASSWORD)->SetFocus(); |
| | | return; |
| | | } |
| | | |
| | | |
| | | EndDialog(IDOK); |
| | | } |
| | | |
| | | void CLoginDlg2::OnBnClickedChangePassword() |
| | | { |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include "afxdialogex.h" |
| | | |
| | | |
| | | // CLoginDlg å¯¹è¯æ¡ |
| | | |
| | | class CLoginDlg2 : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CLoginDlg2) |
| | | |
| | | public: |
| | | CLoginDlg2(CWnd* pParent = nullptr); // æ åæé 彿° |
| | | virtual ~CLoginDlg2(); |
| | | |
| | | // å¯¹è¯æ¡æ°æ® |
| | | #ifdef AFX_DESIGN_TIME |
| | | enum { IDD = IDD_DIALOG_LOGIN }; |
| | | #endif |
| | | |
| | | public: |
| | | CString m_strUsername; |
| | | CString m_strPassword; |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV æ¯æ |
| | | virtual BOOL OnInitDialog(); |
| | | afx_msg void OnBnClickedLogin(); |
| | | afx_msg void OnBnClickedChangePassword(); |
| | | DECLARE_MESSAGE_MAP() |
| | | }; |
| | |
| | | #include "stdafx.h" |
| | | #include "stdafx.h" |
| | | #include "Model.h" |
| | | #include "Log.h" |
| | | #include "Common.h" |
| | |
| | | { |
| | | if (m_pObservable == nullptr) { |
| | | m_pObservable = RX_AllocaObservable([&](IObservableEmitter* e) -> void { |
| | | m_pObservableEmitter = e; // ä¿ååå°å¨ |
| | | m_pObservableEmitter = e; // ä¿ååå°å¨ |
| | | }); |
| | | } |
| | | |
| | |
| | | m_configuration.setFilepath((LPTSTR)(LPCTSTR)strIniFile); |
| | | m_configuration.getUnitId(strUnitId); |
| | | |
| | | // æºå¨åå·åè½¯ä»¶çæ¬å·åºä»é
ç½®ä¸è¯»åï¼å½åå
åºå®å¼ |
| | | // æºå¨åå·åè½¯ä»¶çæ¬å·åºä»é
ç½®ä¸è¯»åï¼å½åå
åºå®å¼ |
| | | CString strModeType = _T("Master"); |
| | | CString strSoftRev = _T("1.0.2"); |
| | | |
| | |
| | | |
| | | SECSListener listener; |
| | | listener.onEQOffLine = [&](void* pFrom) -> void { |
| | | LOGI("è¿ç¨è¯·æ±OffLine"); |
| | | LOGI("è¿ç¨è¯·æ±OffLine"); |
| | | }; |
| | | listener.onEQOnLine = [&](void* pFrom) -> void { |
| | | LOGI("è¿ç¨è¯·æ±OnLine"); |
| | | LOGI("è¿ç¨è¯·æ±OnLine"); |
| | | }; |
| | | listener.onCommand = [&](void* pFrom, const char* pszName, std::vector<CommandParameter>& params) -> void { |
| | | LOGI("onCommand:%s", pszName); |
| | |
| | | } |
| | | }; |
| | | listener.onEQConstantRequest = [&](void* pFrom, std::vector<EQConstant>& eqcs) -> void { |
| | | // 卿¤å¡«å
常éå¼ï¼ç®åä»
æ¯å 1åè¿å |
| | | // 卿¤å¡«å
常éå¼ï¼ç®åä»
æ¯å 1åè¿å |
| | | for (auto& item : eqcs) { |
| | | sprintf_s(item.szValue, 256, "Test%d", item.id + 1); |
| | | } |
| | | }; |
| | | listener.onEQConstantSend = [&](void* pFrom, std::vector<EQConstant>& eqcs) -> void { |
| | | // 卿¤ä¿åå设置æºå¨å¸¸éå¼ |
| | | // 卿¤ä¿åå设置æºå¨å¸¸éå¼ |
| | | for (auto& item : eqcs) { |
| | | LOGI("onEQConstantRequest: %d, %s", item.id, item.szValue); |
| | | } |
| | |
| | | }; |
| | | masterListener.onEqVcrEventReport = [&](void* pMaster, SERVO::CEquipment* pEquipment, SERVO::CVcrEventReport* pReport) { |
| | | LOGE("<CModel>onEqVcrEventReport."); |
| | | if (pReport != nullptr) { |
| | | m_hsmsPassive.setVariableValue("PanelStartID", pReport->getGlassId().c_str()); |
| | | int nRet = m_hsmsPassive.requestEventReportSend_OCR_PanelID_Read_OK(); |
| | | if (nRet != ER_NOERROR) { |
| | | LOGE("<CModel>requestEventReportSend_OCR_PanelID_Read_OK failed, ret=%d", nRet); |
| | | } |
| | | } |
| | | }; |
| | | masterListener.onEqDataChanged = [&](void* pMaster, SERVO::CEquipment* pEquipment, int code) { |
| | | LOGE("<CModel>onEqDataChanged."); |
| | |
| | | }; |
| | | masterListener.onRobotTaskEvent = [&](void* pMaster, SERVO::CRobotTask* pTask, int code) { |
| | | if (pTask == nullptr) { |
| | | LOGE("<CModel>onRobotTaskEvent: ç©ºä»»å¡æéï¼å¿½ç¥äºä»¶ code=%d", code); |
| | | LOGE("<CModel>onRobotTaskEvent: ç©ºä»»å¡æéï¼å¿½ç¥äºä»¶ code=%d", code); |
| | | return; |
| | | } |
| | | |
| | | // ä»»å¡æè¿°ä¸ ID ç¨äºæ¥å¿ |
| | | // ä»»å¡æè¿°ä¸ ID ç¨äºæ¥å¿ |
| | | SERVO::CGlass* pGlass = (SERVO::CGlass*)pTask->getContext(); |
| | | const std::string& strDesc = pTask->getDescription(); |
| | | std::string strClassID; |
| | |
| | | } |
| | | } |
| | | |
| | | // æ¥å¿è¾åºä¸ç¶æå¤ç |
| | | // æ¥å¿è¾åºä¸ç¶æå¤ç |
| | | switch (code) { |
| | | case ROBOT_EVENT_CREATE: |
| | | LOGI("<CModel>onRobotTaskEvent: æ°ä»»å¡å建(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str()); |
| | | LOGI("<CModel>onRobotTaskEvent: æ°ä»»å¡å建(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str()); |
| | | break; |
| | | case ROBOT_EVENT_FINISH: |
| | | LOGI("<CModel>onRobotTaskEvent: ä»»å¡å®æ(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str()); |
| | | LOGI("<CModel>onRobotTaskEvent: ä»»å¡å®æ(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str()); |
| | | break; |
| | | case ROBOT_EVENT_ERROR: |
| | | LOGE("<CModel>onRobotTaskEvent: ä»»å¡é误(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str()); |
| | | LOGE("<CModel>onRobotTaskEvent: ä»»å¡é误(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str()); |
| | | break; |
| | | case ROBOT_EVENT_ABORT: |
| | | LOGE("<CModel>onRobotTaskEvent: ä»»å¡åæ¢(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str()); |
| | | LOGE("<CModel>onRobotTaskEvent: ä»»å¡åæ¢(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str()); |
| | | break; |
| | | case ROBOT_EVENT_RESTORE: |
| | | LOGE("<CModel>onRobotTaskEvent: ä»»å¡åæ¤(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str()); |
| | | LOGE("<CModel>onRobotTaskEvent: ä»»å¡åæ¤(%s, ClassID=%s).", strDesc.c_str(), strClassID.c_str()); |
| | | break; |
| | | default: |
| | | LOGE("<CModel>onRobotTaskEvent: æªç¥äºä»¶ code=%d, ä»»å¡=%s", code, strDesc.c_str()); |
| | | LOGE("<CModel>onRobotTaskEvent: æªç¥äºä»¶ code=%d, ä»»å¡=%s", code, strDesc.c_str()); |
| | | break; |
| | | } |
| | | |
| | | // å®å
¨æ ¼å¼åæ¶é´ |
| | | // å®å
¨æ ¼å¼åæ¶é´ |
| | | auto format_time = [](time_t t) -> std::string { |
| | | if (t <= 0 || t == _I64_MIN || t == _I64_MAX) { |
| | | return ""; |
| | | } |
| | | |
| | | // ä½¿ç¨ localtime_s ç¡®ä¿çº¿ç¨å®å
¨ |
| | | // ä½¿ç¨ localtime_s ç¡®ä¿çº¿ç¨å®å
¨ |
| | | tm tmBuf{}; |
| | | errno_t err = localtime_s(&tmBuf, &t); |
| | | if (err != 0 || tmBuf.tm_mon < 0 || tmBuf.tm_mon > 11) { |
| | | return ""; |
| | | } |
| | | |
| | | // æ ¼å¼åæ¶é´å符串 |
| | | // æ ¼å¼åæ¶é´å符串 |
| | | char buf[64] = {}; |
| | | strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tmBuf); |
| | | return std::string(buf); |
| | | }; |
| | | |
| | | // æé TransferData æ°æ®ç»æ |
| | | // æé TransferData æ°æ®ç»æ |
| | | TransferData data; |
| | | data.strClassID = strClassID; |
| | | data.strCreateTime = format_time(pTask->getCreateTime()); |
| | |
| | | data.strEndTime = format_time(pTask->getFinishTime()); |
| | | data.strDescription = pTask->getSimpleDescription(); |
| | | |
| | | // ç¶ææ å° |
| | | // ç¶ææ å° |
| | | static const char* STATUS_STR[] = { |
| | | "Ready", "Running", "Picking", "Picked", "Placing", "Restoring", "Error", "Abort", "Restored", "Completed" |
| | | }; |
| | |
| | | data.strStatus = "Unknown"; |
| | | } |
| | | |
| | | // åå
¥æ°æ®åº |
| | | // åå
¥æ°æ®åº |
| | | if (code == ROBOT_EVENT_FINISH || code == ROBOT_EVENT_ERROR |
| | | || code == ROBOT_EVENT_ABORT || code == ROBOT_EVENT_RESTORE) { |
| | | int nRecordId = 0; |
| | | TransferManager::getInstance().addTransferRecord(data, nRecordId); |
| | | LOGI("<CModel>onRobotTaskEvent: ä»»å¡è®°å½å·²ä¿åï¼RecordID=%d", nRecordId); |
| | | LOGI("<CModel>onRobotTaskEvent: ä»»å¡è®°å½å·²ä¿åï¼RecordID=%d", nRecordId); |
| | | } |
| | | notifyPtrAndInt(RX_CODE_EQ_ROBOT_TASK, pTask, nullptr, code); |
| | | |
| | |
| | | m_hsmsPassive.setVariableValue("CJEndID", ((SERVO::CControlJob*)pj)->id().c_str()); |
| | | m_hsmsPassive.requestEventReportSend_CJ_End(); |
| | | |
| | | // ç»æ¹ï¼ä¿åControlJob |
| | | // ç»æ¹ï¼ä¿åControlJob |
| | | // |
| | | }; |
| | | masterListener.onPjStart = [&](void* pMaster, void* pj) { |
| | |
| | | m_master.setContinuousTransferCount(m_configuration.getContinuousTransferCount()); |
| | | |
| | | |
| | | // master 设置ç¼åæä»¶ |
| | | // master 设置ç¼åæä»¶ |
| | | CString strMasterDataFile; |
| | | strMasterDataFile.Format(_T("%s\\Master.dat"), (LPTSTR)(LPCTSTR)m_strWorkDir); |
| | | m_master.setCacheFilepath((LPTSTR)(LPCTSTR)strMasterDataFile); |
| | | m_master.setCompareMapsBeforeProceeding(m_configuration.isCompareMapsBeforeProceeding()); |
| | | m_master.setJobMode(m_configuration.isJobMode()); |
| | | |
| | | // å æªJob |
| | | // å æªJob |
| | | strMasterDataFile.Format(_T("%s\\MasterState.dat"), (LPTSTR)(LPCTSTR)m_strWorkDir); |
| | | std::string strPath = std::string((LPTSTR)(LPCTSTR)strMasterDataFile); |
| | | m_master.setStateFile(strPath); |
| | | |
| | | |
| | | |
| | | // å è½½è¦åä¿¡æ¯ |
| | | // å è½½è¦åä¿¡æ¯ |
| | | AlarmManager& alarmManager = AlarmManager::getInstance(); |
| | | char szBuffer[MAX_PATH]; |
| | | sprintf_s(szBuffer, MAX_PATH, "%s\\AlarmList.csv", (LPTSTR)(LPCTSTR)m_strWorkDir); |
| | | alarmManager.readAlarmFile(szBuffer); |
| | | |
| | | |
| | | // Glassæ°æ®åº |
| | | // Glassæ°æ®åº |
| | | strLogDir.Format(_T("%s\\db\\process.db"), (LPTSTR)(LPCTSTR)m_strWorkDir); |
| | | std::string path((LPTSTR)(LPCTSTR)strLogDir); |
| | | GlassLogDb::Init(path); |
| | |
| | | |
| | | void CPageRecipe::OnBnClickedButtonNew() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | //CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_EQUIPMENT); |
| | | //int nSel = pComboBox->GetCurSel(); |
| | | //SERVO::CEquipment* pEq = (SERVO::CEquipment*)pComboBox->GetItemDataPtr(nSel); |
| | | //if (pEq == nullptr) { |
| | | // return; |
| | | //} |
| | | int rc = UX_CanExecute(L"recipe"); |
| | | if (rc != 1) { |
| | | AfxMessageBox("æä½æéä¸è¶³ï¼è¯·è系管ç人åï¼"); |
| | | return; |
| | | } |
| | | UX_RecordAction(L"recipe"); |
| | | |
| | | CRecipeDeviceBindDlg dlg(this); |
| | | if (dlg.DoModal() == IDOK) { |
| | |
| | | |
| | | void CPageRecipe::OnBnClickedButtonModify() |
| | | { |
| | | int rc = UX_CanExecute(L"recipe"); |
| | | if (rc != 1) { |
| | | AfxMessageBox("æä½æéä¸è¶³ï¼è¯·è系管ç人åï¼"); |
| | | return; |
| | | } |
| | | UX_RecordAction(L"recipe"); |
| | | |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_EQUIPMENT); |
| | | if (pComboBox == nullptr || !::IsWindow(pComboBox->m_hWnd)) { |
| | |
| | | |
| | | void CPageRecipe::OnBnClickedButtonDelete() |
| | | { |
| | | int rc = UX_CanExecute(L"recipe"); |
| | | if (rc != 1) { |
| | | AfxMessageBox("æä½æéä¸è¶³ï¼è¯·è系管ç人åï¼"); |
| | | return; |
| | | } |
| | | UX_RecordAction(L"recipe"); |
| | | |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | POSITION pos = m_listPPID.GetFirstSelectedItemPosition(); |
| | | if (!pos) { |
| | |
| | | |
| | | void CPageRecipe::OnBnClickedButtonDeleteAll() |
| | | { |
| | | int rc = UX_CanExecute(L"recipe"); |
| | | if (rc != 1) { |
| | | AfxMessageBox("æä½æéä¸è¶³ï¼è¯·è系管ç人åï¼"); |
| | | return; |
| | | } |
| | | UX_RecordAction(L"recipe"); |
| | | |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | if (IDYES != AfxMessageBox(_T("ç¡®å®è¦å é¤å
¨é¨é
æ¹è®°å½åï¼"), MB_YESNO | MB_ICONWARNING)) { |
| | | return; |
| | |
| | | #include "MapPosWnd.h" |
| | | #include "HmTab.h" |
| | | #include "CControlJobManagerDlg.h" |
| | | #include "ToolUnits.h" |
| | | #include "CUserManager2.h" |
| | | |
| | | |
| | | // 声æå
¨å±åéï¼ç¨äºç®¡ç GDI+ åå§å |
| | |
| | | m_strAppDir = CString(sDrive) + CString(sDir); |
| | | m_strAppFile = CString(sFilename); |
| | | m_model.setWorkDir((LPTSTR)(LPCTSTR)m_strAppDir); |
| | | |
| | | |
| | | // ç¨æ·æ°æ®åºç®¡ç |
| | | CString strDir = m_strAppDir + _T("\\DB"); |
| | | CUserManager2::getInstance().init((LPTSTR)(LPCTSTR)strDir); |
| | | |
| | | |
| | | // æ³¨åæ§ä»¶ |
| | |
| | | m_model.term(); |
| | | HSMS_Term(); |
| | | RX_Term(); |
| | | UX_Shutdown(); |
| | | |
| | | // æ¸
ç GDI+ |
| | | TermGDIPlus(); |
| | |
| | | <ClInclude Include="CRobotTaskDlg.h" /> |
| | | <ClInclude Include="CSVData.h" /> |
| | | <ClInclude Include="CServoUtilsTool.h" /> |
| | | <ClInclude Include="CUserManager2.h" /> |
| | | <ClInclude Include="CUserManager2Dlg.h" /> |
| | | <ClInclude Include="CUserEdit2Dlg.h" /> |
| | | <ClInclude Include="CUserXLogDlg.h" /> |
| | | <ClInclude Include="CVariable.h" /> |
| | | <ClInclude Include="DeviceRecipeParamDlg.h" /> |
| | | <ClInclude Include="GlassJson.h" /> |
| | |
| | | <ClInclude Include="InputDialog.h" /> |
| | | <ClInclude Include="JobSlotGrid.h" /> |
| | | <ClInclude Include="LoginDlg.h" /> |
| | | <ClInclude Include="LoginDlg2.h" /> |
| | | <ClInclude Include="MsgDlg.h" /> |
| | | <ClInclude Include="PageRecipe.h" /> |
| | | <ClInclude Include="CDoubleGlass.h" /> |
| | |
| | | <ClCompile Include="CRobotTaskDlg.cpp" /> |
| | | <ClCompile Include="CSVData.cpp" /> |
| | | <ClCompile Include="CServoUtilsTool.cpp" /> |
| | | <ClCompile Include="CUserManager2.cpp" /> |
| | | <ClCompile Include="CUserManager2Dlg.cpp" /> |
| | | <ClCompile Include="CUserEdit2Dlg.cpp" /> |
| | | <ClCompile Include="CUserXLogDlg.cpp" /> |
| | | <ClCompile Include="CVariable.cpp" /> |
| | | <ClCompile Include="DeviceRecipeParamDlg.cpp" /> |
| | | <ClCompile Include="GlassJson.cpp" /> |
| | |
| | | <ClCompile Include="InputDialog.cpp" /> |
| | | <ClCompile Include="JobSlotGrid.cpp" /> |
| | | <ClCompile Include="LoginDlg.cpp" /> |
| | | <ClCompile Include="LoginDlg2.cpp" /> |
| | | <ClCompile Include="MsgDlg.cpp" /> |
| | | <ClCompile Include="PageRecipe.cpp" /> |
| | | <ClCompile Include="CDoubleGlass.cpp" /> |
| | |
| | | <ClCompile Include="..\DAQBridge\proto\ProtocolCodec.cpp"> |
| | | <Filter>DAQBridge</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="ClientListDlg.cpp" /> |
| | | <ClCompile Include="LoginDlg2.cpp" /> |
| | | <ClCompile Include="CUserManager2.cpp" /> |
| | | <ClCompile Include="CUserManager2Dlg.cpp" /> |
| | | <ClCompile Include="CUserEdit2Dlg.cpp" /> |
| | | <ClCompile Include="CUserXLogDlg.cpp" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ClInclude Include="AlarmManager.h" /> |
| | |
| | | <ClInclude Include="..\DAQBridge\DAQConfig.h"> |
| | | <Filter>DAQBridge</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="ClientListDlg.h" /> |
| | | <ClInclude Include="LoginDlg2.h" /> |
| | | <ClInclude Include="CUserManager2.h" /> |
| | | <ClInclude Include="CUserManager2Dlg.h" /> |
| | | <ClInclude Include="CUserEdit2Dlg.h" /> |
| | | <ClInclude Include="CUserXLogDlg.h" /> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ResourceCompile Include="Servo.rc" /> |
| | |
| | | #include "CRobotCmdContainerDlg.h" |
| | | #include "CRobotCmdTestDlg.h" |
| | | #include "LoginDlg.h" |
| | | #include "LoginDlg2.h" |
| | | #include "ChangePasswordDlg.h" |
| | | #include "UserManagerDlg.h" |
| | | #include "SystemLogManagerDlg.h" |
| | |
| | | #include "InputDialog.h" |
| | | #include "ClientListDlg.h" |
| | | #include "CControlJobManagerDlg.h" |
| | | #include "CUserManager2.h" |
| | | #include "CUserManager2Dlg.h" |
| | | #include "CUserXLogDlg.h" |
| | | |
| | | |
| | | #ifdef _DEBUG |
| | |
| | | #define TIMER_ID_UPDATE_RUMTIME 2 |
| | | |
| | | /* Test */ |
| | | #define TIMER_ID_TEST 3 |
| | | #define TIMER_ID_LOGIN 3 |
| | | |
| | | |
| | | // ç¨äºåºç¨ç¨åºâå
³äºâèå项ç CAboutDlg å¯¹è¯æ¡ |
| | |
| | | else if (RX_CODE_MASTER_STATE_CHANGED == code) { |
| | | SERVO::MASTERSTATE state = theApp.m_model.getMaster().getState(); |
| | | if (state == SERVO::MASTERSTATE::READY) { |
| | | m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(TRUE); |
| | | m_pTopToolbar ->GetBtn(IDC_BUTTON_RUN)->EnableWindow(TRUE); |
| | | m_pTopToolbar->GetBtn(IDC_BUTTON_RUN_BATCH)->EnableWindow(TRUE); |
| | | m_pTopToolbar->GetBtn(IDC_BUTTON_RUN_CT)->EnableWindow(TRUE); |
| | | m_pTopToolbar->GetBtn(IDC_BUTTON_STOP)->EnableWindow(FALSE); |
| | |
| | | |
| | | // model init |
| | | theApp.m_model.init(); |
| | | SetTimer(TIMER_ID_TEST, 1000, nullptr); |
| | | SetTimer(TIMER_ID_LOGIN, 1500, nullptr); |
| | | |
| | | // èå |
| | | CMenu menu; |
| | |
| | | m_pMyStatusbar->setRunTimeText((LPTSTR)(LPCTSTR)strText); |
| | | } |
| | | |
| | | else if(TIMER_ID_TEST == nIDEvent){ |
| | | static __int64 tttt = 0; |
| | | tttt++; |
| | | theApp.m_model.m_hsmsPassive.setVariableValue("CJobSpace", tttt % 10); |
| | | theApp.m_model.m_hsmsPassive.setVariableValue("PJobSpace", tttt % 5); |
| | | else if(TIMER_ID_LOGIN == nIDEvent){ |
| | | KillTimer(TIMER_ID_LOGIN); |
| | | if (!CUserManager2::getInstance().isLoggedIn()) { |
| | | CLoginDlg2 dlg; |
| | | if (dlg.DoModal() != IDOK) { |
| | | PostMessage(WM_CLOSE); |
| | | } |
| | | else { |
| | | bool bRet = CUserManager2::getInstance().login((LPTSTR)(LPCTSTR)dlg.m_strUsername, |
| | | (LPTSTR)(LPCTSTR)dlg.m_strPassword); |
| | | if (!bRet) { |
| | | AfxMessageBox("ç»å½å¤±è´¥ï¼è¯·æ£æ¥ç¨æ·åæå¯ç æ¯å¦æ£ç¡®ï¼"); |
| | | PostMessage(WM_CLOSE); |
| | | } |
| | | UpdateLoginStatus(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | void CServoDlg::UpdateLoginStatus() |
| | | { |
| | | 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); |
| | | CUserManager2& userManager = CUserManager2::getInstance(); |
| | | if (userManager.isLoggedIn()) { |
| | | ::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) { |
| | | if (userManager.IsAdminCurrent()) { |
| | | ::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()); |
| | | m_pTopToolbar->SetOperatorBtnText(userManager.getCurrentUserName().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("æªç»å½")); |
| | | } |
| | | } |
| | |
| | | LRESULT CServoDlg::OnToolbarBtnClicked(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | int id = (int)lParam; |
| | | if (id == IDC_BUTTON_RUN || id == IDC_BUTTON_STOP) { |
| | | UserRole emRole = UserManager::getInstance().getCurrentUserRole(); |
| | | if (emRole != UserRole::SuperAdmin) { |
| | | AfxMessageBox(_T("å½åç¨æ·å¹¶é管çåï¼ï¼ï¼")); |
| | | return 1; |
| | | } |
| | | } |
| | | |
| | | if (id == IDC_BUTTON_RUN) { |
| | | int rc = UX_CanExecute(L"start"); |
| | | if (rc != 1) { |
| | | AfxMessageBox("æä½æéä¸è¶³ï¼è¯·è系管ç人åï¼"); |
| | | return 0; |
| | | } |
| | | UX_RecordAction(L"start"); |
| | | |
| | | if (theApp.m_model.getMaster().getState() == SERVO::MASTERSTATE::MSERROR) { |
| | | AfxMessageBox("å½åææºå°åçé误ï¼ä¸è½å¯å¨ï¼è¯·ç¡®è®¤è§£å³é®é¢ååå°è¯éæ°å¯å¨ï¼"); |
| | | } |
| | |
| | | } |
| | | } |
| | | else if (id == IDC_BUTTON_STOP) { |
| | | int rc = UX_CanExecute(L"stop"); |
| | | if (rc != 1) { |
| | | AfxMessageBox("æä½æéä¸è¶³ï¼è¯·è系管ç人åï¼"); |
| | | return 0; |
| | | } |
| | | UX_RecordAction(L"stop"); |
| | | |
| | | if (theApp.m_model.getMaster().stop() == 0) { |
| | | m_pTopToolbar->GetBtn(IDC_BUTTON_STOP)->EnableWindow(FALSE); |
| | | } |
| | |
| | | } |
| | | else if (id == IDC_BUTTON_OPERATOR) { |
| | | int menuId = (int)wParam; |
| | | if (menuId == 0) { |
| | | CUserManager2Dlg dlg; |
| | | dlg.DoModal(); |
| | | } |
| | | else if (menuId == 1) { |
| | | CUserXLogDlg dlg; |
| | | dlg.DoModal(); |
| | | } |
| | | else if (menuId == 2) { |
| | | CLoginDlg2 dlg; |
| | | if (dlg.DoModal() == IDOK) { |
| | | bool bRet = CUserManager2::getInstance().login((LPTSTR)(LPCTSTR)dlg.m_strUsername, |
| | | (LPTSTR)(LPCTSTR)dlg.m_strPassword); |
| | | if (!bRet) { |
| | | AfxMessageBox("ç»å½å¤±è´¥ï¼è¯·æ£æ¥ç¨æ·åæå¯ç æ¯å¦æ£ç¡®ï¼"); |
| | | } |
| | | UpdateLoginStatus(); |
| | | } |
| | | } |
| | | |
| | | /* |
| | | SystemLogManager& logManager = SystemLogManager::getInstance(); |
| | | UserManager& userManager = UserManager::getInstance(); |
| | | if (menuId == 0) { |
| | |
| | | } |
| | | |
| | | UpdateLoginStatus(); |
| | | */ |
| | | } |
| | | |
| | | return 0; |
| | |
| | | std::ostringstream oss; |
| | | oss << std::put_time(&tm, "%Y%m%d%H%M%S"); // ä¾ï¼2025-09-15 08:23:07 |
| | | return oss.str(); |
| | | } |
| | | |
| | | std::wstring CToolUnits::AnsiToWString(const std::string& str) |
| | | { |
| | | if (str.empty()) return std::wstring(); |
| | | |
| | | int len = ::MultiByteToWideChar(CP_ACP, 0, |
| | | str.c_str(), -1, |
| | | nullptr, 0); |
| | | if (len <= 0) return std::wstring(); |
| | | |
| | | std::wstring ws; |
| | | ws.resize(len - 1); |
| | | |
| | | ::MultiByteToWideChar(CP_ACP, 0, |
| | | str.c_str(), -1, |
| | | &ws[0], len); |
| | | |
| | | return ws; |
| | | } |
| | | |
| | | std::string CToolUnits::WStringToAnsi(const std::wstring& wstr) |
| | | { |
| | | if (wstr.empty()) return std::string(); |
| | | |
| | | int len = ::WideCharToMultiByte(CP_ACP, 0, |
| | | wstr.c_str(), -1, |
| | | nullptr, 0, |
| | | nullptr, nullptr); |
| | | if (len <= 0) return std::string(); |
| | | |
| | | std::string str; |
| | | str.resize(len - 1); |
| | | |
| | | ::WideCharToMultiByte(CP_ACP, 0, |
| | | wstr.c_str(), -1, |
| | | &str[0], len, |
| | | nullptr, nullptr); |
| | | |
| | | return str; |
| | | } |
| | |
| | | const char* fmt = "%Y-%m-%d %H:%M:%S"); |
| | | static std::string TimePointToLocalStringMs(const std::optional<TP>& tp); |
| | | static std::string NowStrSec(); |
| | | static std::wstring AnsiToWString(const std::string& str); |
| | | static std::string WStringToAnsi(const std::wstring& wstr); |
| | | }; |
| | | |
| | |
| | | |
| | | #include "..\RxWindows1.0\include\RxWindowsLib.h" |
| | | #include "..\HSMSSDK\Include\HSMSSDK.h" |
| | | |
| | | #include "..\UserXLibrary\UserXAPI.h" |
| | | |
| | | |
| | | #ifdef _UNICODE |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // UserX ç¨æ·ç®¡çåºï¼C æ¥å£ï¼/ UserX user management library (C API) |
| | | // è¦çåè½ / Features: users, roles, actions, auth, logsï¼åºå® SQLite3 æä¹
å / SQLite3 persistenceï¼ |
| | | |
| | | #pragma once |
| | | |
| | | #if defined(_WIN32) |
| | | # ifdef USERXLIBRARY_EXPORTS |
| | | # define UX_API extern "C" __declspec(dllexport) |
| | | # else |
| | | # define UX_API extern "C" __declspec(dllimport) |
| | | # endif |
| | | #else |
| | | # define UX_API extern "C" |
| | | #endif |
| | | |
| | | #include <wchar.h> |
| | | |
| | | |
| | | #ifdef _COMPILE_AS_LIB |
| | | #warning "compiling as lib!" |
| | | #else |
| | | #ifdef _DEBUG |
| | | #ifndef _WIN64 |
| | | #pragma comment(lib, "../USERXLibrary/lib/Win32/Debug/UserXLibrary.lib") |
| | | #else |
| | | #pragma comment(lib, "../USERXLibrary/lib/x64/Debug/UserXLibrary.lib") |
| | | #endif |
| | | #else |
| | | #ifndef _WIN64 |
| | | #pragma comment(lib, "../USERXLibrary/lib/Win32/Release/UserXLibrary.lib") |
| | | #else |
| | | #pragma comment(lib, "../USERXLibrary/lib/x64/Release/UserXLibrary.lib") |
| | | #endif |
| | | #endif |
| | | #endif // !BUILD_AS_LIB |
| | | |
| | | |
| | | // é¢å¤é误ç / Extra error code |
| | | #ifndef UX_ERR_BAD_PASSWORD |
| | | #define UX_ERR_BAD_PASSWORD -10 // å¯ç é误 / bad password |
| | | #endif |
| | | |
| | | // é误ç å®å®ä¹ / Error code macros |
| | | #define UX_OK 0 // æå / success |
| | | #define UX_ERR_INVALID_ARGS -1 // åæ°é误 / invalid arguments |
| | | #define UX_ERR_NOT_FOUND -2 // æªæ¾å° / not found |
| | | #define UX_ERR_EXISTS -3 // å·²åå¨ / already exists |
| | | #define UX_ERR_PERMISSION -4 // æéä¸è¶³ / permission denied |
| | | #define UX_ERR_NOT_LOGGED_IN -5 // æªç»å½ / not logged in |
| | | #define UX_ERR_BUFFER_TOO_SMALL -6 // ç¼å²åºä¸è¶³ / buffer too small |
| | | #define UX_ERR_DB -7 // I/O ææ°æ®åºé误 / I/O or database error |
| | | #define UX_ERR_NOT_DEFINED -8 // æªå®ä¹ï¼å¦å¨ä½ä¸åå¨ï¼/ not defined |
| | | #define UX_ERR_DB_NOT_EMPTY -9 // æ°æ®åºé空ï¼å·²åå§åï¼/ database not empty |
| | | |
| | | // è¿åç / Return codesï¼è¯¦è§ä¸æ¹å®ï¼ |
| | | // UX_OK, UX_ERR_INVALID_ARGS, UX_ERR_NOT_FOUND, UX_ERR_EXISTS, |
| | | // UX_ERR_PERMISSION, UX_ERR_NOT_LOGGED_IN, UX_ERR_BUFFER_TOO_SMALL, |
| | | // UX_ERR_DB, UX_ERR_NOT_DEFINED, UX_ERR_DB_NOT_EMPTY |
| | | |
| | | // åå§åï¼æå®æ°æ®ç®å½ï¼å
é¨å°æå¼/å建 SQLite æ°æ®åºæä»¶ UserX.db |
| | | // Init: provide data directory; opens/creates SQLite DB file UserX.db |
| | | UX_API int UX_Init(const wchar_t* storage_dir); |
| | | |
| | | // å¯éï¼è¦çæ°æ®åºè·¯å¾ï¼ä»
使ç¨ç¬¬ä¸ä¸ªåæ°ä½ä¸º .db æä»¶è·¯å¾ï¼å
¶ä»å¿½ç¥ï¼ |
| | | // Optional: override DB path (use first arg as .db path; others ignored) |
| | | UX_API int UX_SetStorage(const wchar_t* users_db_path, |
| | | const wchar_t* /*unused_logs*/, |
| | | const wchar_t* /*unused_roles*/, |
| | | const wchar_t* /*unused_actions*/); |
| | | |
| | | // é
ç½®è§è²ï¼name:level æè¡ï¼/ Configure roles from lines "name:level" |
| | | // ä»
å
许å¨âç©ºæ°æ®åºâï¼roles/users/actions/logs åè¡¨åæ æ°æ®ï¼æ¶è°ç¨ï¼å¦åè¿å -9ã |
| | | // Only allowed when DB is empty (roles/users/actions/logs all zero rows); otherwise returns -9. |
| | | // e.g. L"Admin:100\nEngineer:50\nOperator:10\n" |
| | | UX_API int UX_SetRoleDefinitions(const wchar_t* roles_text); |
| | | |
| | | // è·åè§è²å表ï¼name:level æè¡ï¼ï¼buffer 为空æä¸è¶³æ¶è¿åæéå¤§å° |
| | | // Get roles list as lines; returns required size if buffer is null/too small |
| | | UX_API int UX_GetRoles(wchar_t* buffer, int buffer_chars); |
| | | |
| | | // ç¨æ·ç®¡ç / User management |
| | | UX_API int UX_AddUser(const wchar_t* username, |
| | | const wchar_t* display_name, |
| | | const wchar_t* password, |
| | | const wchar_t* role_name); |
| | | |
| | | UX_API int UX_DeleteUser(const wchar_t* username); |
| | | |
| | | // æ´æ°ä»»æå段ï¼ä¼ nullptr è¡¨ç¤ºä¿æä¸åï¼/ Update subset; nullptr keeps field |
| | | UX_API int UX_UpdateUser(const wchar_t* username, |
| | | const wchar_t* new_display_name, |
| | | const wchar_t* new_password, |
| | | const wchar_t* new_role_name, |
| | | int enabled /* -1 keep, 0 disable, 1 enable */); |
| | | |
| | | UX_API int UX_EnableUser(const wchar_t* username, int enabled /*0/1*/); |
| | | UX_API int UX_ResetPassword(const wchar_t* username, const wchar_t* new_password); |
| | | UX_API int UX_RenameUser(const wchar_t* username, const wchar_t* new_display_name); |
| | | |
| | | // 管çåæéï¼å 餿æç¨æ· / Admin-only |
| | | UX_API int UX_DeleteAllUsers(); |
| | | |
| | | // è·åç¨æ·åè¡¨ï¼æ¯è¡ï¼username,display,level,enabledï¼/ Query users |
| | | UX_API int UX_GetUsers(wchar_t* buffer, int buffer_chars); |
| | | |
| | | // è®¤è¯ / Authentication |
| | | UX_API int UX_Login(const wchar_t* username, const wchar_t* password); |
| | | UX_API void UX_Logout(); |
| | | UX_API int UX_IsLoggedIn(); |
| | | UX_API void UX_Shutdown(); // éæ¾èµæº / shutdown and free resources |
| | | UX_API int UX_GetCurrentUser(wchar_t* buffer, int buffer_chars); |
| | | |
| | | // å¨ä½ä¸æé / Actions & permissions |
| | | // å®ä¹/è¦çå¨ä½ï¼åç§°ãæè¿°ãæä½è§è²ï¼/ Define/overwrite action |
| | | UX_API int UX_DefineAction(const wchar_t* action_name, |
| | | const wchar_t* description, |
| | | const wchar_t* min_role_name); |
| | | |
| | | // 坿§è¡è¿å1ï¼ä¸å¯æ§è¡è¿å0ï¼è´æ°ä¸ºé误 / 1 allowed, 0 denied |
| | | UX_API int UX_CanExecute(const wchar_t* action_name); |
| | | |
| | | // è®°å½å¨ä½å°æ¥å¿ï¼æ¶é´ãç¨æ·ãå¨ä½ãæè¿°ï¼/ Record action to logs |
| | | UX_API int UX_RecordAction(const wchar_t* action_name); |
| | | |
| | | // è·åå¨ä½åè¡¨ï¼æ¯è¡ï¼name,desc,minlevelï¼/ Get actions list |
| | | UX_API int UX_GetActions(wchar_t* buffer, int buffer_chars); |
| | | |
| | | // è®°å½å°è¯ï¼å
许/æç»ï¼/ record an attempt with allowed flag (1 allowed, 0 denied) |
| | | UX_API int UX_RecordAttempt(const wchar_t* action_name, int allowed /*1/0*/); |
| | | |
| | | // æ¥è¯¢æè¿ N æ¡æ¥å¿ï¼æ¯è¡ï¼ISO8601æ¶é´,ç¨æ·å,å¨ä½,æè¿°ï¼/ Query logs |
| | | UX_API int UX_QueryLogs(int last_n, wchar_t* buffer, int buffer_chars); |
| | | |
| | | // æ ¹æ®é误ç è¿åæåæè¿°ï¼ä¸æ/Englishï¼ |
| | | // Return a human-readable message for an error code |
| | | UX_API const wchar_t* UX_ErrorMessage(int code); |