| | |
| | | <Optimization>Disabled</Optimization> |
| | | <PreprocessorDefinitions>_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
| | | <SDLCheck>true</SDLCheck> |
| | | <AdditionalIncludeDirectories>.;.\DBManager;..\DatabaseSDK\include</AdditionalIncludeDirectories> |
| | | <AdditionalIncludeDirectories>.;.\DBManager;.\FileManager;..\DatabaseSDK\include;..\BLControlsSDK\include;..\BLControlsSDK\GridControl</AdditionalIncludeDirectories> |
| | | </ClCompile> |
| | | <Link> |
| | | <SubSystem>Windows</SubSystem> |
| | |
| | | <IntrinsicFunctions>true</IntrinsicFunctions> |
| | | <PreprocessorDefinitions>_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
| | | <SDLCheck>true</SDLCheck> |
| | | <AdditionalIncludeDirectories>.;.\DBManager;..\DatabaseSDK\include</AdditionalIncludeDirectories> |
| | | <AdditionalIncludeDirectories>.;.\DBManager;.\FileManager;..\DatabaseSDK\include;..\BLControlsSDK\include;..\BLControlsSDK\GridControl</AdditionalIncludeDirectories> |
| | | </ClCompile> |
| | | <Link> |
| | | <SubSystem>Windows</SubSystem> |
| | |
| | | <ClInclude Include="DBManager\AxisManager.h" /> |
| | | <ClInclude Include="DBManager\SystemLogManager.h" /> |
| | | <ClInclude Include="DBManager\UserManager.h" /> |
| | | <ClInclude Include="FileManager\IOManager.h" /> |
| | | <ClInclude Include="FileManager\pugiconfig.hpp" /> |
| | | <ClInclude Include="FileManager\pugixml.hpp" /> |
| | | <ClInclude Include="FileManager\RecipeManager.h" /> |
| | | <ClInclude Include="InputDialog.h" /> |
| | | <ClInclude Include="Intent.h" /> |
| | | <ClInclude Include="IOMonitoringDlg.h" /> |
| | | <ClInclude Include="Log.h" /> |
| | | <ClInclude Include="LogEdit.h" /> |
| | | <ClInclude Include="McBool.h" /> |
| | |
| | | <ClCompile Include="DBManager\AxisManager.cpp" /> |
| | | <ClCompile Include="DBManager\SystemLogManager.cpp" /> |
| | | <ClCompile Include="DBManager\UserManager.cpp" /> |
| | | <ClCompile Include="FileManager\IOManager.cpp" /> |
| | | <ClCompile Include="FileManager\pugixml.cpp"> |
| | | <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader> |
| | | <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader> |
| | | </ClCompile> |
| | | <ClCompile Include="FileManager\RecipeManager.cpp" /> |
| | | <ClCompile Include="InputDialog.cpp" /> |
| | | <ClCompile Include="Intent.cpp" /> |
| | | <ClCompile Include="IOMonitoringDlg.cpp" /> |
| | | <ClCompile Include="Log.cpp" /> |
| | | <ClCompile Include="LogEdit.cpp" /> |
| | | <ClCompile Include="McBool.cpp" /> |
| | |
| | | <Filter Include="DBManager"> |
| | | <UniqueIdentifier>{c5603403-bc3a-451f-b300-c56d9fe09307}</UniqueIdentifier> |
| | | </Filter> |
| | | <Filter Include="FileManager"> |
| | | <UniqueIdentifier>{d7763e1c-46cf-48f9-b0da-001138287bcd}</UniqueIdentifier> |
| | | </Filter> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <Text Include="ReadMe.txt" /> |
| | |
| | | <ClInclude Include="LogEdit.h"> |
| | | <Filter>头æä»¶</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="FileManager\IOManager.h"> |
| | | <Filter>FileManager</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="FileManager\pugiconfig.hpp"> |
| | | <Filter>FileManager</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="FileManager\pugixml.hpp"> |
| | | <Filter>FileManager</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="FileManager\RecipeManager.h"> |
| | | <Filter>FileManager</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="InputDialog.h"> |
| | | <Filter>头æä»¶</Filter> |
| | | </ClInclude> |
| | | <ClInclude Include="IOMonitoringDlg.h"> |
| | | <Filter>头æä»¶</Filter> |
| | | </ClInclude> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ClCompile Include="BoounionPLC.cpp"> |
| | |
| | | <ClCompile Include="LogEdit.cpp"> |
| | | <Filter>æºæä»¶</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="FileManager\IOManager.cpp"> |
| | | <Filter>FileManager</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="FileManager\pugixml.cpp"> |
| | | <Filter>FileManager</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="FileManager\RecipeManager.cpp"> |
| | | <Filter>FileManager</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="InputDialog.cpp"> |
| | | <Filter>æºæä»¶</Filter> |
| | | </ClCompile> |
| | | <ClCompile Include="IOMonitoringDlg.cpp"> |
| | | <Filter>æºæä»¶</Filter> |
| | | </ClCompile> |
| | | </ItemGroup> |
| | | <ItemGroup> |
| | | <ResourceCompile Include="BoounionPLC.rc"> |
| | |
| | | #include "afxdialogex.h" |
| | | #include "Common.h" |
| | | #include "PlcView.h" |
| | | #include "AlarmMonitor.h" |
| | | #include "Log.h" |
| | | #include "InputDialog.h" |
| | | #include "IOManager.h" |
| | | |
| | | // æµè¯ |
| | | #include "IOMonitoringDlg.h" |
| | | |
| | | |
| | | #ifdef _DEBUG |
| | |
| | | { |
| | | int id = (int)lParam; |
| | | if (id == IDC_BUTTON_ADD) { |
| | | static int i = 0; |
| | | char szName[256]; |
| | | sprintf_s(szName, 256, "PLC%d", ++i); |
| | | theApp.m_model.addPlc(szName, "192.168.1.188", 1001); |
| | | CInputDialog inputDialog(_T("æ°å»ºè®¾å¤"), _T("请è¾å
¥è®¾å¤åç§°ï¼")); |
| | | if (inputDialog.DoModal() != IDOK) { |
| | | AfxMessageBox(_T("åæ¶éªè¯ï¼")); |
| | | return 0; |
| | | } |
| | | |
| | | CString strName; |
| | | strName = inputDialog.GetInputText(); |
| | | if (!strName.IsEmpty()) { |
| | | theApp.m_model.addPlc((LPTSTR)(LPCTSTR)strName, "192.168.1.188", 1001); |
| | | |
| | | // æ°å»ºIOæä»¶ |
| | | IOManager io; |
| | | io.DefaultMachineData(); |
| | | io.SaveToFile((LPTSTR)(LPCTSTR)strName); |
| | | } |
| | | } |
| | | else if (id == IDC_BUTTON_DELETE) { |
| | | CPLC* pPlc = theApp.m_model.getCurrentPlc(); |
| | |
| | | } |
| | | } |
| | | else if (id == IDC_BUTTON_SETTINGS) { |
| | | |
| | | // æµè¯ IO模å |
| | | CPLC* pPLC = theApp.m_model.getCurrentPlc(); |
| | | if (pPLC != nullptr) { |
| | | CIOMonitoringDlg dlg; |
| | | dlg.SetPLC(pPLC); |
| | | dlg.SetIOManager(pPLC->getName()); |
| | | dlg.DoModal(); |
| | | } |
| | | } |
| | | else if (id == IDC_BUTTON_OPERATOR) { |
| | | /* |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include <fstream> |
| | | #include <iostream> |
| | | #include "IOManager.h" |
| | | #include "ToolUnits.h" |
| | | |
| | | IOManager::IOManager() { |
| | | m_directory = CToolUnits::getCurrentExePath() + _T("\\PLCs"); |
| | | if (!CToolUnits::isDirectory(m_directory)) { |
| | | CToolUnits::createDir(m_directory.c_str()); |
| | | } |
| | | } |
| | | |
| | | void IOManager::DefaultMachineData() { |
| | | std::vector<IOData> vecDefaultData = { |
| | | {FALSE, "X1000", "Unit1_æ¥å EMO", FALSE, "Y1010", "Unit1_åè²ç¯-红"}, |
| | | {FALSE, "X1001", "Unit1_æ»è¿æ°å忣",FALSE,"Y1011", "Unit1_åè²ç¯-é»"}, |
| | | {FALSE, "X1002", "Unit1_伺æçµæçææ¥è¦", FALSE, "Y1012", "Unit1_åè²ç¯-绿"}, |
| | | {FALSE,"X1003", "Unit1_å ççµæçææ¥è¦", FALSE, "Y1013", "Unit1_åè²ç¯-è"}, |
| | | {FALSE, "X1004", "å®å
¨ç»§çµå¨æ£", FALSE, "Y1014", "Unit1_è鸣å¨-1"}, |
| | | {FALSE, "X1005", "", FALSE, "Y1015", "Unit1_è鸣å¨-2"}, |
| | | {FALSE, "X1006", "",FALSE, "Y1016", "Unit1_è鸣å¨-3"}, |
| | | {FALSE, "X1007", "Unit1_å®å
¨é¨ç£æ£1", FALSE,"Y1017", "Unit1_è鸣å¨-4"}, |
| | | {FALSE, "X1008", "Unit1_å®å
¨é¨ç£æ£2",FALSE, "Y1018", "Unit1_æºå°ç
§æ"}, |
| | | {FALSE, "X1009", "Unit1_å®å
¨é¨ç£æ£3",FALSE, "Y1019", "Unit1_å®å
¨é¨éå±è½"}, |
| | | {FALSE, "X100A", "Unit1_å®å
¨é¨ç£æ£4",FALSE, "Y101A", ""}, |
| | | {FALSE, "X100B", "Unit1_å®å
¨é¨ç£æ£5", FALSE,"Y101B", ""}, |
| | | {FALSE, "X100C", "Unit1_å®å
¨é¨ç£æ£6",FALSE, "Y101C", ""}, |
| | | {FALSE, "X100D", "Unit1_å®å
¨é¨éæ£1",FALSE, "Y101D", "Unit1_å®å
¨é¨é1"}, |
| | | {FALSE, "X100E", "Unit1_å®å
¨é¨éæ£2",FALSE, "Y101E", "Unit1_å®å
¨é¨é2"}, |
| | | {FALSE, "X100F", "Unit1_å®å
¨é¨éæ£3",FALSE, "Y101F", "Unit1_å®å
¨é¨é3"}, |
| | | {FALSE, "X1020", "Unit1_ååæ³µ-Alam(8-14)",FALSE, "Y1030", "Unit1_ååæ³µå¯å¨(1-9)"}, |
| | | {FALSE, "X1021", "Unit1_ååæ³µ-è¿ç¨/æ¬å°æ¨¡å¼(7-15)", FALSE,"Y1031", "Unit1_ååæ³µèéè£
ç½®(2-10)"}, |
| | | {FALSE, "X1022", "Unit1_ååæ³µ-æ£å¸¸è¿è¡ï¼4-12ï¼", FALSE,"Y1032", "Unit1_ååæ³µéæææ¿é"}, |
| | | {FALSE, "X1023", "Unit1_ååæ³µéæææ¿éåä½", FALSE,"Y1033", "Unit1_æ°åéæé"}, |
| | | {FALSE, "X1024", "Unit1_ååæ³µéæææ¿éå°ä½", FALSE,"Y1034", ""}, |
| | | {FALSE, "X1025", "Unit1_è
使çå·¦æ°ç¼¸åä½", FALSE,"Y1035", "Unit1_è
使çå·¦æ°ç¼¸åä½"}, |
| | | {FALSE, "X1026", "Unit1_è
使çå·¦æ°ç¼¸å°ä½",FALSE, "Y1036", "Unit1_è
使çå·¦æ°ç¼¸å°ä½"}, |
| | | {FALSE, "X1027", "Unit1_è
使ç峿°ç¼¸åä½", FALSE,"Y1037", "Unit1_è
使ç峿°ç¼¸åä½"}, |
| | | {FALSE, "X1028", "Unit1_è
使ç峿°ç¼¸å°ä½", FALSE,"Y1038", "Unit1_è
使ç峿°ç¼¸å°ä½"}, |
| | | {FALSE, "X1029", "Unit1_é¨éåéæ°ç¼¸åä½", FALSE,"Y1039", "Unit1_é¨éåéæ°ç¼¸"}, |
| | | {FALSE, "X102A", "Unit1_é¨éåéæ°ç¼¸å°ä½",FALSE, "Y103A", ""}, |
| | | {FALSE, "X102B", "Unit1_è
ä½ç ´ç空æ°éåä½",FALSE, "Y103B", "Unit1_è
ä½ç ´ç空æ°é"}, |
| | | {FALSE, "X102C", "Unit1_è
ä½ç ´ç空æ°éå°ä½", FALSE,"Y103C", "Unit1_ååæ³µææ°é"}, |
| | | {FALSE, "X102D", "Unit1_ä¸è
å¹³å°ç空æ£", FALSE,"Y103D", "Unit1_ä¸è
å¹³å°å¸ç空"}, |
| | | {FALSE, "X102E", "Unit1_ååæ³µææ°éåä½",FALSE, "Y103E", "Unit1_ä¸è
å¹³å°ç ´ç空"}, |
| | | {FALSE, "X102F", "Unit1_ååæ³µææ°éå°ä½", FALSE,"Y103F", ""}, |
| | | {FALSE, "X1040", "Unit1_ä¸å çå·²ä¸çµ",FALSE, "Y1050", "Unit1_ä¸å çä¸çµ"}, |
| | | {FALSE, "X1041", "Unit1_ä¸ä¸»æ¸©æ§è¡¨æ¥è¦", FALSE,"Y1051", "Unit1_ä¸å çä¸çµ"}, |
| | | {FALSE, "X1042", "Unit1_ä¸çæ§æ¸©æ§è¡¨æ¥è¦1",FALSE, "Y1052", ""}, |
| | | {FALSE, "X1043", "Unit1_ä¸çæ§æ¸©æ§è¡¨æ¥è¦2",FALSE, "Y1053", ""}, |
| | | {FALSE, "X1044", "Unit1_ä¸çæ§æ¸©æ§è¡¨æ¥è¦3", FALSE,"Y1054", ""}, |
| | | {FALSE, "X1045", "Unit1_ä¸çæ§æ¸©æ§è¡¨æ¥è¦4",FALSE, "Y1055", ""}, |
| | | {FALSE, "X1046", "Unit1_ä¸çæ§æ¸©æ§è¡¨æ¥è¦5",FALSE, "Y1056", ""}, |
| | | {FALSE, "X1047", "Unit1_ä¸å çå·²ä¸çµ",FALSE, "Y1057", ""}, |
| | | {FALSE, "X1048", "Unit1_ä¸ä¸»æ¸©æ§è¡¨æ¥è¦",FALSE, "Y1058", ""}, |
| | | {FALSE, "X1049", "Unit1_ä¸çæ§æ¸©æ§è¡¨æ¥è¦1",FALSE, "Y1059", ""}, |
| | | {FALSE, "X104A", "Unit1_ä¸çæ§æ¸©æ§è¡¨æ¥è¦2", FALSE,"Y105A", ""}, |
| | | {FALSE, "X104B", "Unit1_ä¸çæ§æ¸©æ§è¡¨æ¥è¦3", FALSE,"Y105B", ""}, |
| | | {FALSE, "X104C", "Unit1_ä¸çæ§æ¸©æ§è¡¨æ¥è¦4", FALSE,"Y105C", ""}, |
| | | {FALSE, "X104D", "Unit1_ä¸çæ§æ¸©æ§è¡¨æ¥è¦5",FALSE, "Y105D", ""}, |
| | | {FALSE, "X104E", "",FALSE, "Y105E", ""}, |
| | | {FALSE, "X104F", "", FALSE,"Y105F", ""}, |
| | | {FALSE, "X1060", "Unit1_干泵-DVPè¿è¡æ£æµ-11",FALSE, "Y1070", "Unit1_干泵-DVPå¯å¨-1"}, |
| | | {FALSE, "X1061", "Unit1_干泵-MBPè¿è¡æ£æµ-12",FALSE, "Y1071", "Unit1_干泵-MBPå¯å¨-2"}, |
| | | {FALSE, "X1062", "Unit1_干泵-é误æ¥è¦ä¸-14",FALSE, "Y1072", "Unit1_干泵-å¼å¸¸è§£é¤-3"}, |
| | | {FALSE, "X1063", "Unit1_干泵-é误è¦åä¸-16",FALSE, "Y1073", ""}, |
| | | {FALSE, "X1064", "Unit1_干泵-è¿ç¨/æ¬å°æ¨¡å¼-18",FALSE, "Y1074", "Unit1_æ°®æ°éæçµç£é1"}, |
| | | {FALSE, "X1065", "Unit1_干泵-ç´§æ¥åæ¢ä¸-20",FALSE, "Y1075", "Unit1_æ°®æ°éæçµç£é2"}, |
| | | {FALSE, "X1066", "",FALSE, "Y1076", "Unit1_æ°®æ°éæçµç£é3"}, |
| | | {FALSE, "X1067", "",FALSE, "Y1077", "Unit1_æ°®æ°éæçµç£é4"}, |
| | | {FALSE, "X1068", "",FALSE, "Y1078", "Unit1_å çæ¿æ°´å·éæçµç£é1"}, |
| | | {FALSE, "X1069", "",FALSE, "Y1079", "Unit1_å çæ¿æ°´å·éæçµç£é2"}, |
| | | {FALSE, "X106A", "",FALSE, "Y107A", "Unit1_å çæ¿æ°´å·éæçµç£é3"}, |
| | | {FALSE, "X106B", "", FALSE,"Y107B", "Unit1_å çæ¿æ°´å·éæçµç£é4"}, |
| | | {FALSE, "X106C", "", FALSE,"Y107C", "Unit1_è
ä½åºæ¿éæçµç£é1"}, |
| | | {FALSE, "X106D", "Unit1_æ°´ç®±ä¸æ¶²ä½æ£",FALSE, "Y107D", "Unit1_è
ä½åºæ¿éæçµç£é2"}, |
| | | {FALSE, "X106E", "Unit1_æ°´ç®±ä¸æ¶²ä½æ£",FALSE, "Y107E", "Unit1_æ°´ç®±è¿æ°´é"}, |
| | | {FALSE, "X106F", "Unit1_æ°´ç®±ä¸æ¶²ä½æ£", FALSE,"Y107F", "Unit1_æ°´ç®±åºæ°´é"}, |
| | | {FALSE, "X1080", "Unit2_æ¥å EMO",FALSE, "Y1090", "Unit2_åè²ç¯-红"}, |
| | | {FALSE, "X1081", "Unit2_æ»è¿æ°å忣",FALSE, "Y1091", "Unit2_åè²ç¯-é»"}, |
| | | {FALSE, "X1082", "Unit2_伺æçµæçææ¥è¦",FALSE, "Y1092", "Unit2_åè²ç¯-绿"}, |
| | | {FALSE, "X1083", "Unit2_å ççµæçææ¥è¦", FALSE,"Y1093", "Unit2_åè²ç¯-è"}, |
| | | {FALSE, "X1084", "å®å
¨ç»§çµå¨æ£",FALSE, "Y1094", "Unit2_è鸣å¨-1"}, |
| | | {FALSE, "X1085", "", FALSE,"Y1095", "Unit2_è鸣å¨-2"}, |
| | | {FALSE, "X1086", "", FALSE,"Y1096", "Unit2_è鸣å¨-3"}, |
| | | {FALSE, "X1087", "Unit2_å®å
¨é¨ç£æ£1",FALSE, "Y1097", "Unit2_è鸣å¨-4"}, |
| | | {FALSE, "X1088", "Unit2_å®å
¨é¨ç£æ£2",FALSE, "Y1098", "Unit2_æºå°ç
§æ"}, |
| | | {FALSE, "X1089", "Unit2_å®å
¨é¨ç£æ£3", FALSE,"Y1099", "Unit2_å®å
¨é¨éå±è½"}, |
| | | {FALSE, "X108A", "Unit2_å®å
¨é¨ç£æ£4",FALSE, "Y109A", ""}, |
| | | {FALSE, "X108B", "Unit2_å®å
¨é¨ç£æ£5",FALSE, "Y109B", ""}, |
| | | {FALSE, "X108C", "Unit2_å®å
¨é¨ç£æ£6",FALSE, "Y109C", ""}, |
| | | {FALSE, "X108D", "Unit2_å®å
¨é¨éæ£1",FALSE, "Y109D", "Unit2_å®å
¨é¨é1"}, |
| | | {FALSE, "X108E", "Unit2_å®å
¨é¨éæ£2",FALSE, "Y109E", "Unit2_å®å
¨é¨é2"}, |
| | | {FALSE, "X108F", "Unit2_å®å
¨é¨éæ£3",FALSE, "Y109F", "Unit2_å®å
¨é¨é3"}, |
| | | {FALSE, "X10A0", "Unit2_ååæ³µ-Alam(8-14)", FALSE,"Y10B0", "Unit2_ååæ³µå¯å¨(1-9)"}, |
| | | {FALSE, "X10A1", "Unit2_ååæ³µ-è¿ç¨/æ¬å°æ¨¡å¼(7-15)", FALSE,"Y10B1", "Unit2_ååæ³µèéè£
ç½®(2-10)"}, |
| | | {FALSE, "X10A2", "Unit2_ååæ³µ-æ£å¸¸è¿è¡ï¼4-12ï¼",FALSE, "Y10B2", "Unit2_ååæ³µéæææ¿é"}, |
| | | {FALSE, "X10A3", "", FALSE,"Y10B3", "Unit2_æ°åéæé"}, |
| | | {FALSE, "X10A4", "",FALSE, "Y10B4", ""}, |
| | | {FALSE, "X10A5", "Unit2_è
使çå·¦æ°ç¼¸åä½",FALSE, "Y10B5", "Unit2_è
使çå·¦æ°ç¼¸åä½"}, |
| | | {FALSE, "X10A6", "Unit2_è
使çå·¦æ°ç¼¸å°ä½",FALSE, "Y10B6", "Unit2_è
使çå·¦æ°ç¼¸å°ä½"}, |
| | | {FALSE, "X10A7", "Unit2_è
使ç峿°ç¼¸åä½",FALSE, "Y10B7", "Unit2_è
使ç峿°ç¼¸åä½"}, |
| | | {FALSE, "X10A8", "Unit2_è
使ç峿°ç¼¸å°ä½",FALSE, "Y10B8", "Unit2_è
使ç峿°ç¼¸å°ä½"}, |
| | | {FALSE, "X10A9", "Unit2_é¨éåéæ°ç¼¸åä½", FALSE,"Y10B9", "Unit2_é¨éåéæ°ç¼¸"}, |
| | | {FALSE, "X10AA", "Unit2_é¨éåéæ°ç¼¸å°ä½", FALSE,"Y10BA", ""}, |
| | | {FALSE, "X10AB", "Unit2_è
ä½ç ´ç空æ°éåä½", FALSE,"Y10BB", "Unit2_è
ä½ç ´ç空æ°é"}, |
| | | {FALSE, "X10AC", "Unit2_è
ä½ç ´ç空æ°éå°ä½",FALSE, "Y10BC", "Unit2_ååæ³µææ°é"}, |
| | | {FALSE, "X10AD", "Unit2_ä¸è
å¹³å°ç空æ£", FALSE,"Y10BD", "Unit2_ä¸è
å¹³å°å¸ç空"}, |
| | | {FALSE, "X10AE", "Unit2_ååæ³µææ°éåä½",FALSE, "Y10BE", "Unit2_ä¸è
å¹³å°ç ´ç空"}, |
| | | {FALSE, "X10AF", "Unit2_ååæ³µææ°éå°ä½",FALSE, "Y10BF", ""}, |
| | | {FALSE, "X10C0", "Unit2_ä¸å çå·²ä¸çµ", FALSE,"Y10D0", "Unit2_ä¸å çä¸çµ"}, |
| | | {FALSE, "X10C1", "Unit2_ä¸ä¸»æ¸©æ§è¡¨æ¥è¦",FALSE, "Y10D1", "Unit2_ä¸å çä¸çµ"}, |
| | | {FALSE, "X10C2", "Unit2_ä¸çæ§æ¸©æ§è¡¨æ¥è¦1",FALSE, "Y10D2", ""}, |
| | | {FALSE, "X10C3", "Unit2_ä¸çæ§æ¸©æ§è¡¨æ¥è¦2",FALSE, "Y10D3", ""}, |
| | | {FALSE, "X10C4", "Unit2_ä¸çæ§æ¸©æ§è¡¨æ¥è¦3",FALSE, "Y10D4", ""}, |
| | | {FALSE, "X10C5", "Unit2_ä¸çæ§æ¸©æ§è¡¨æ¥è¦4", FALSE,"Y10D5", ""}, |
| | | {FALSE, "X10C6", "Unit2_ä¸çæ§æ¸©æ§è¡¨æ¥è¦5", FALSE,"Y10D6", ""}, |
| | | {FALSE, "X10C7", "Unit2_ä¸å çå·²ä¸çµ", FALSE,"Y10D7", ""}, |
| | | {FALSE,"X10C8", "Unit2_ä¸ä¸»æ¸©æ§è¡¨æ¥è¦", FALSE,"Y10D8", ""}, |
| | | {FALSE, "X10C9", "Unit2_ä¸çæ§æ¸©æ§è¡¨æ¥è¦1",FALSE, "Y10D9", ""}, |
| | | {FALSE, "X10CA", "Unit2_ä¸çæ§æ¸©æ§è¡¨æ¥è¦2", FALSE,"Y10DA", ""}, |
| | | {FALSE, "X10CB", "Unit2_ä¸çæ§æ¸©æ§è¡¨æ¥è¦3",FALSE, "Y10DB", ""}, |
| | | {FALSE, "X10CC", "Unit2_ä¸çæ§æ¸©æ§è¡¨æ¥è¦4",FALSE, "Y10DC", ""}, |
| | | {FALSE, "X10CD", "Unit2_ä¸çæ§æ¸©æ§è¡¨æ¥è¦5", FALSE,"Y10DD", ""}, |
| | | {FALSE, "X10CE", "",FALSE, "Y10DE", ""}, |
| | | {FALSE, "X10CF", "", FALSE,"Y10DF", ""}, |
| | | {FALSE, "X10E0", "Unit2_干泵-DVPè¿è¡æ£æµ-11",FALSE, "Y10F0", "Unit2_干泵-DVPå¯å¨-1"}, |
| | | {FALSE, "X10E1", "Unit2_干泵-MBPè¿è¡æ£æµ-12",FALSE, "Y10F1", "Unit2_干泵-MBPå¯å¨-2"}, |
| | | {FALSE, "X10E2", "Unit2_干泵-é误æ¥è¦ä¸-14", FALSE,"Y10F2", "Unit2_干泵-å¼å¸¸è§£é¤-3"}, |
| | | {FALSE, "X10E3", "Unit2_干泵-é误è¦åä¸-16",FALSE, "Y10F3", ""}, |
| | | {FALSE, "X10E4", "Unit2_干泵-è¿ç¨/æ¬å°æ¨¡å¼-18",FALSE, "Y10F4", "Unit2_æ°®æ°éæçµç£é1"}, |
| | | {FALSE, "X10E5", "Unit2_干泵-ç´§æ¥åæ¢ä¸-20",FALSE, "Y10F5", "Unit2_æ°®æ°éæçµç£é2"}, |
| | | {FALSE, "X10E6", "",FALSE, "Y10F6", "Unit2_æ°®æ°éæçµç£é3"}, |
| | | {FALSE, "X10E7", "",FALSE, "Y10F7", "Unit2_æ°®æ°éæçµç£é4"}, |
| | | {FALSE, "X10E8", "",FALSE, "Y10F8", "Unit2_å çæ¿æ°´å·éæçµç£é1"}, |
| | | {FALSE, "X10E9", "",FALSE, "Y10F9", "Unit2_å çæ¿æ°´å·éæçµç£é2"}, |
| | | {FALSE, "X10EA", "",FALSE,"Y10FA", "Unit2_å çæ¿æ°´å·éæçµç£é3"}, |
| | | {FALSE, "X10EB", "",FALSE, "Y10FB", "Unit2_å çæ¿æ°´å·éæçµç£é4"}, |
| | | {FALSE, "X10EC", "",FALSE, "Y10FC", "Unit2_è
ä½åºæ¿éæçµç£é1"}, |
| | | {FALSE, "X10ED", "Unit2_æ°´ç®±ä¸æ¶²ä½æ£",FALSE, "Y10FD", "Unit2_è
ä½åºæ¿éæçµç£é2"}, |
| | | {FALSE, "X10EE", "Unit2_æ°´ç®±ä¸æ¶²ä½æ£",FALSE, "Y10FE", "Unit2_æ°´ç®±è¿æ°´é"}, |
| | | {FALSE, "X10EF", "Unit2_æ°´ç®±ä¸æ¶²ä½æ£",FALSE, "Y10FF", "Unit2_æ°´ç®±åºæ°´é"} |
| | | }; |
| | | |
| | | m_vecMachines.resize(vecDefaultData.size()); |
| | | m_vecMachines.assign(vecDefaultData.begin(), vecDefaultData.end()); |
| | | } |
| | | |
| | | void IOManager::SaveToFile(const std::string& strMachineName) { |
| | | std::ofstream file(m_directory + "\\" + strMachineName +"\\" + "IOConfiguration.iom"); |
| | | if (!file.is_open()) { |
| | | std::cerr << "Failed to open file for writing: " << strMachineName << ".iom" << std::endl; |
| | | return; |
| | | } |
| | | |
| | | for (const auto& entry : m_vecMachines) { |
| | | file << entry.inputAddress << "," |
| | | << entry.inputDescription << "," |
| | | << entry.outputAddress << "," |
| | | << entry.outputDescription << "\n"; |
| | | } |
| | | |
| | | file.close(); |
| | | } |
| | | |
| | | bool IOManager::LoadFromFile(const std::string& strMachineName) { |
| | | std::ifstream file(m_directory + "\\" + strMachineName + "\\" + "IOConfiguration.iom"); |
| | | if (!file.is_open()) { |
| | | std::cerr << "Failed to open file for reading: " << strMachineName << ".iom" << std::endl; |
| | | return false; |
| | | } |
| | | |
| | | m_vecMachines.clear(); |
| | | |
| | | std::string line; |
| | | while (std::getline(file, line)) { |
| | | IOData entry; |
| | | size_t pos = 0; |
| | | pos = line.find(","); |
| | | |
| | | entry.bInputStates = FALSE; |
| | | entry.bOutputStates = FALSE; |
| | | |
| | | entry.inputAddress = line.substr(0, pos); |
| | | line.erase(0, pos + 1); |
| | | |
| | | pos = line.find(","); |
| | | entry.inputDescription = line.substr(0, pos); |
| | | line.erase(0, pos + 1); |
| | | |
| | | pos = line.find(","); |
| | | entry.outputAddress = line.substr(0, pos); |
| | | line.erase(0, pos + 1); |
| | | |
| | | entry.outputDescription = line; |
| | | m_vecMachines.push_back(entry); |
| | | } |
| | | |
| | | file.close(); |
| | | return true; |
| | | } |
| | | |
| | | void IOManager::GetMachineData(std::vector<IOData>& vecMachines) { |
| | | vecMachines.resize(m_vecMachines.size()); |
| | | vecMachines.assign(m_vecMachines.begin(), m_vecMachines.end()); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #ifndef IOMANAGER_H |
| | | #define IOMANAGER_H |
| | | |
| | | #include <string> |
| | | #include <vector> |
| | | |
| | | struct IOData { |
| | | BOOL bInputStates; |
| | | std::string inputAddress; |
| | | std::string inputDescription; |
| | | BOOL bOutputStates; |
| | | std::string outputAddress; |
| | | std::string outputDescription; |
| | | }; |
| | | |
| | | class IOManager { |
| | | public: |
| | | IOManager(); |
| | | |
| | | void DefaultMachineData(); |
| | | void SaveToFile(const std::string& strMachineName); |
| | | bool LoadFromFile(const std::string& strMachineName); |
| | | void GetMachineData(std::vector<IOData>& vecMachines); |
| | | |
| | | private: |
| | | std::string m_directory; |
| | | std::vector<IOData> m_vecMachines; |
| | | }; |
| | | |
| | | #endif // IOMANAGER_H |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "stdafx.h" |
| | | #include <sstream> |
| | | #include <fstream> |
| | | #include <iostream> |
| | | #include "RecipeManager.h" |
| | | |
| | | // åä¾è·å |
| | | RecipeManager& RecipeManager::getInstance() { |
| | | static RecipeManager instance; |
| | | return instance; |
| | | } |
| | | |
| | | // æé 彿° |
| | | RecipeManager::RecipeManager() : m_recipeFolder("Recipe"), m_currentRecipeName("") {} |
| | | |
| | | // å è½½è½´ä¿¡æ¯ |
| | | bool RecipeManager::loadAxes(pugi::xml_node axesNode) { |
| | | m_axes.clear(); |
| | | for (auto axisNode : axesNode.children("Axis")) { |
| | | AxisInfo axisInfo; |
| | | axisInfo.id = axisNode.attribute("id").as_int(); |
| | | axisInfo.number = axisNode.attribute("number").value(); |
| | | axisInfo.description = axisNode.attribute("description").value(); |
| | | axisInfo.startAddress = axisNode.attribute("start_address").value(); |
| | | |
| | | // å è½½ ValueRange å¼ |
| | | axisInfo.jogDistance = ValueRange( |
| | | axisNode.child("jog_distance").attribute("min").as_double(), |
| | | axisNode.child("jog_distance").attribute("max").as_double(), |
| | | axisNode.child("jog_distance").attribute("current").as_double() |
| | | ); |
| | | axisInfo.manualSpeed = ValueRange( |
| | | axisNode.child("manual_speed").attribute("min").as_double(), |
| | | axisNode.child("manual_speed").attribute("max").as_double(), |
| | | axisNode.child("manual_speed").attribute("current").as_double() |
| | | ); |
| | | axisInfo.autoSpeed = ValueRange( |
| | | axisNode.child("auto_speed").attribute("min").as_double(), |
| | | axisNode.child("auto_speed").attribute("max").as_double(), |
| | | axisNode.child("auto_speed").attribute("current").as_double() |
| | | ); |
| | | axisInfo.accelerationTime = ValueRange( |
| | | axisNode.child("acceleration_time").attribute("min").as_double(), |
| | | axisNode.child("acceleration_time").attribute("max").as_double(), |
| | | axisNode.child("acceleration_time").attribute("current").as_double() |
| | | ); |
| | | axisInfo.decelerationTime = ValueRange( |
| | | axisNode.child("deceleration_time").attribute("min").as_double(), |
| | | axisNode.child("deceleration_time").attribute("max").as_double(), |
| | | axisNode.child("deceleration_time").attribute("current").as_double() |
| | | ); |
| | | |
| | | // å è½½ PositionRange å¼ |
| | | axisInfo.positioningPointCount = axisNode.child("Positions").attribute("positioningPointCount").as_int(); |
| | | for (auto positionNode : axisNode.child("Positions").children("Position")) { |
| | | bool isEnable = positionNode.attribute("isEnable").as_bool(); |
| | | std::string description = positionNode.attribute("description").value(); |
| | | ValueRange positionRange( |
| | | positionNode.attribute("min").as_double(), |
| | | positionNode.attribute("max").as_double(), |
| | | positionNode.attribute("current").as_double() |
| | | ); |
| | | |
| | | axisInfo.positions.emplace_back(PositionRange(isEnable, description, positionRange)); |
| | | } |
| | | |
| | | m_axes[axisInfo.id] = axisInfo; |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | // ä¿åè½´ä¿¡æ¯ |
| | | void RecipeManager::saveAxes(pugi::xml_node& axesNode) { |
| | | for (const auto& axisEntry : m_axes) { |
| | | const AxisInfo& axisInfo = axisEntry.second; |
| | | |
| | | auto axisNode = axesNode.append_child("Axis"); |
| | | axisNode.append_attribute("id") = axisInfo.id; |
| | | axisNode.append_attribute("number") = axisInfo.number.c_str(); |
| | | axisNode.append_attribute("description") = axisInfo.description.c_str(); |
| | | axisNode.append_attribute("start_address") = axisInfo.startAddress.c_str(); |
| | | |
| | | // ä¿å ValueRange å¼ |
| | | auto jog_distance = axisNode.append_child("jog_distance"); |
| | | jog_distance.append_attribute("min") = axisInfo.jogDistance.minValue; |
| | | jog_distance.append_attribute("max") = axisInfo.jogDistance.maxValue; |
| | | jog_distance.append_attribute("current") = axisInfo.jogDistance.currentValue; |
| | | |
| | | auto manual_speed = axisNode.append_child("manual_speed"); |
| | | manual_speed.append_attribute("min") = axisInfo.manualSpeed.minValue; |
| | | manual_speed.append_attribute("max") = axisInfo.manualSpeed.maxValue; |
| | | manual_speed.append_attribute("current") = axisInfo.manualSpeed.currentValue; |
| | | |
| | | auto auto_speed = axisNode.append_child("auto_speed"); |
| | | auto_speed.append_attribute("min") = axisInfo.autoSpeed.minValue; |
| | | auto_speed.append_attribute("max") = axisInfo.autoSpeed.maxValue; |
| | | auto_speed.append_attribute("current") = axisInfo.autoSpeed.currentValue; |
| | | |
| | | auto acceleration_time = axisNode.append_child("acceleration_time"); |
| | | acceleration_time.append_attribute("min") = axisInfo.accelerationTime.minValue; |
| | | acceleration_time.append_attribute("max") = axisInfo.accelerationTime.maxValue; |
| | | acceleration_time.append_attribute("current") = axisInfo.accelerationTime.currentValue; |
| | | |
| | | auto deceleration_time = axisNode.append_child("deceleration_time"); |
| | | deceleration_time.append_attribute("min") = axisInfo.decelerationTime.minValue; |
| | | deceleration_time.append_attribute("max") = axisInfo.decelerationTime.maxValue; |
| | | deceleration_time.append_attribute("current") = axisInfo.decelerationTime.currentValue; |
| | | |
| | | // ä¿å PositionRange å¼ |
| | | auto positionsNode = axisNode.append_child("Positions"); |
| | | positionsNode.append_attribute("positioningPointCount") = axisInfo.positioningPointCount; |
| | | for (const auto& position : axisInfo.positions) { |
| | | auto positionNode = positionsNode.append_child("Position"); |
| | | positionNode.append_attribute("isEnable") = position.isEnable; |
| | | positionNode.append_attribute("description") = position.description.c_str(); |
| | | positionNode.append_attribute("min") = position.range.minValue; |
| | | positionNode.append_attribute("max") = position.range.maxValue; |
| | | positionNode.append_attribute("current") = position.range.currentValue; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 设置é
æ¹æä»¶å¤¹ |
| | | void RecipeManager::setRecipeFolder(const std::string& folderPath) { |
| | | m_recipeFolder = folderPath; |
| | | } |
| | | |
| | | // è·åå½åé
æ¹åç§° |
| | | std::string RecipeManager::getCurrentRecipeName() const { |
| | | return m_currentRecipeName; |
| | | } |
| | | |
| | | // å è½½é
æ¹ï¼å¦ææä»¶ä¸åå¨ï¼å è½½é»è®¤æ°æ®ï¼ |
| | | bool RecipeManager::loadRecipe(const std::string& recipeName) { |
| | | std::string filePath = m_recipeFolder + "/" + recipeName + ".xml"; |
| | | pugi::xml_document doc; |
| | | |
| | | if (!doc.load_file(filePath.c_str())) { |
| | | std::cerr << "Recipe file not found: " << filePath << ". Loading default recipe." << std::endl; |
| | | return false; // æä»¶ä¸åå¨ |
| | | } |
| | | m_currentRecipeName = recipeName; |
| | | |
| | | auto recipeNode = doc.child("Recipe"); |
| | | auto axesNode = recipeNode.child("Axes"); |
| | | loadAxes(axesNode); // å è½½è½´ä¿¡æ¯ |
| | | |
| | | return true; |
| | | } |
| | | |
| | | // ä¿åé
æ¹ |
| | | bool RecipeManager::saveRecipe(const std::string& recipeName) { |
| | | // çææä»¶è·¯å¾ |
| | | std::string filePath = m_recipeFolder + "/" + recipeName + ".xml"; |
| | | |
| | | // å建 XML ææ¡£å¯¹è±¡ |
| | | pugi::xml_document doc; |
| | | |
| | | // å¦æè½´æ°æ®ä¸ºç©ºï¼çæé»è®¤é
æ¹ |
| | | if (m_axes.empty()) { |
| | | generateDefaultRecipe(); |
| | | } |
| | | |
| | | // æ·»å é
æ¹æ ¹èç¹ |
| | | auto recipeNode = doc.append_child("Recipe"); |
| | | |
| | | // æ·»å è½´ä¿¡æ¯ |
| | | auto axesNode = recipeNode.append_child("Axes"); |
| | | saveAxes(axesNode); |
| | | |
| | | // ä¿å XML æä»¶ |
| | | return doc.save_file(filePath.c_str()); |
| | | } |
| | | |
| | | // çæé»è®¤é
æ¹ |
| | | void RecipeManager::generateDefaultRecipe() { |
| | | m_axes.clear(); |
| | | m_currentRecipeName = "Default"; |
| | | |
| | | for (int axisId = 1; axisId <= 12; ++axisId) { |
| | | AxisInfo axisInfo; |
| | | axisInfo.id = axisId; |
| | | axisInfo.positioningPointCount = 25; |
| | | axisInfo.number = "M100-M" + std::to_string(axisId); |
| | | axisInfo.description = "Default_Axis" + std::to_string(axisId); |
| | | axisInfo.startAddress = "ZR" + std::to_string(10000 + (axisId - 1) * 300); |
| | | |
| | | // 设置é»è®¤ç ValueRange |
| | | axisInfo.jogDistance = ValueRange(1.0, 10.0, 1.0); |
| | | axisInfo.manualSpeed = ValueRange(1.0, 100.0, 10.0); |
| | | axisInfo.autoSpeed = ValueRange(5.0, 200.0, 50.0); |
| | | axisInfo.accelerationTime = ValueRange(1.0, 10.0, 1.0); |
| | | axisInfo.decelerationTime = ValueRange(1.0, 10.0, 1.0); |
| | | |
| | | // æ·»å å®ä½ç¹å¹¶è®¾ç½®é»è®¤çæå°å¼åæå¤§å¼ |
| | | for (int posId = 0; posId < axisInfo.positioningPointCount; ++posId) { |
| | | double minPos = (posId + 1) * 5.0; |
| | | double maxPos = (posId + 1) * 20.0; |
| | | axisInfo.positions.emplace_back(PositionRange(TRUE, "Position " + std::to_string(posId + 1), ValueRange(minPos, maxPos, (posId + 1) * 10.0))); |
| | | } |
| | | |
| | | m_axes[axisId] = axisInfo; |
| | | } |
| | | } |
| | | |
| | | // è·åææè½´ä¿¡æ¯ |
| | | const std::map<int, AxisInfo>& RecipeManager::getAxes() const { |
| | | return m_axes; |
| | | } |
| | | |
| | | // è·ååä¸ªè½´ä¿¡æ¯ |
| | | AxisInfo RecipeManager::getAxis(int axisId) const { |
| | | auto it = m_axes.find(axisId); |
| | | if (it != m_axes.end()) { |
| | | return it->second; // 妿æ¾å°äºè½´ï¼è¿åå
¶è¯¦ç»ä¿¡æ¯ |
| | | } |
| | | |
| | | // å¦ææ²¡ææ¾å°è¯¥è½´ï¼è¿åä¸ä¸ªé»è®¤çæ æ AxisInfo |
| | | return AxisInfo{ -1, 0, /*0.0, 0.0,*/ "", "", "", ValueRange(), ValueRange(), ValueRange(), ValueRange(), ValueRange(), {} }; |
| | | } |
| | | |
| | | // æ´æ°è½´ä¿¡æ¯ |
| | | bool RecipeManager::updateAxis(const AxisInfo& axisInfo) { |
| | | if (m_axes.find(axisInfo.id) == m_axes.end()) { |
| | | return false; // è½´ä¸åå¨ |
| | | } |
| | | m_axes[axisInfo.id] = axisInfo; |
| | | return true; |
| | | } |
| | | |
| | | // æ·»å æ°çè½´ä¿¡æ¯ |
| | | bool RecipeManager::addAxis(const AxisInfo& axisInfo) { |
| | | if (m_axes.find(axisInfo.id) != m_axes.end()) { |
| | | return false; // è½´å·²åå¨ |
| | | } |
| | | m_axes[axisInfo.id] = axisInfo; |
| | | return true; |
| | | } |
| | | |
| | | // å é¤è½´ä¿¡æ¯ |
| | | bool RecipeManager::deleteAxis(int axisId) { |
| | | return m_axes.erase(axisId) > 0; |
| | | } |
| | | |
| | | // è·åææè½´ç¼å· |
| | | std::vector<int> RecipeManager::getAllAxisID() const { |
| | | std::vector<int> axisNumbers; |
| | | for (const auto& axis : m_axes) { |
| | | int axisId = axis.first; |
| | | axisNumbers.push_back(axisId); |
| | | } |
| | | |
| | | return axisNumbers; |
| | | } |
| | | |
| | | // è·åæå®é¡µçå®ä½ç¹ |
| | | std::vector<PositionRange> RecipeManager::getPositions(int axisId, int pageNumber, int pageSize) const { |
| | | std::vector<PositionRange> result; |
| | | |
| | | // æ£æ¥è½´æ¯å¦åå¨ |
| | | auto it = m_axes.find(axisId); |
| | | if (it == m_axes.end()) { |
| | | return result; // å¦æè½´ ID ä¸åå¨ï¼è¿åç©ºç»æ |
| | | } |
| | | |
| | | // è·åæå®è½´çææå®ä½ç¹ |
| | | const auto& positions = it->second.positions; |
| | | |
| | | // ç¡®å®å页èå´ |
| | | int startIndex = (pageNumber - 1) * pageSize; |
| | | int endIndex = startIndex + pageSize; |
| | | |
| | | // éåå®ä½ç¹ï¼æå页æåæ°æ® |
| | | int index = 0; |
| | | for (const auto& pos : positions) { |
| | | const PositionRange& position = pos; // å®ä½ç¹å
å«æè¿°ãä½ç½®ãæå°å¼ãæå¤§å¼åå½åå¼ |
| | | |
| | | if (index >= startIndex && index < endIndex) { |
| | | result.push_back(position); // æ·»å 宿´ç PositionRange 对象 |
| | | } |
| | | |
| | | ++index; |
| | | if (index >= endIndex) { |
| | | break; // è¾¾å°åé¡µç»æç¹ |
| | | } |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | // è·åæå®è½´çå®ä½ç¹ |
| | | PositionRange RecipeManager::getPositionByIndex(int axisId, int pageNumber, int pageSize, int currentIndex) const { |
| | | // æ£æ¥è½´æ¯å¦åå¨ |
| | | auto it = m_axes.find(axisId); |
| | | if (it == m_axes.end()) { |
| | | return PositionRange(); // è½´ä¸åå¨ï¼è¿åé»è®¤æé ç PositionRangeï¼æ æçå®ä½ç¹ï¼ |
| | | } |
| | | |
| | | // è·åæå®è½´çææå®ä½ç¹ |
| | | const auto& positions = it->second.positions; |
| | | |
| | | // ç¡®å®å页èå´ |
| | | int startIndex = (pageNumber - 1) * pageSize; |
| | | int endIndex = startIndex + pageSize; |
| | | |
| | | // 妿 currentIndex è¶
è¿äºå½å页çèå´ï¼è¿åæ æç PositionRange |
| | | if (currentIndex < 0 || currentIndex >= pageSize || currentIndex + startIndex >= positions.size()) { |
| | | return PositionRange(); // è¿åæ æçå®ä½ç¹ |
| | | } |
| | | |
| | | // è¿åæå®å®ä½ç¹ï¼èèåé¡µï¼ |
| | | return positions[startIndex + currentIndex]; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #ifndef RECIPE_MANAGER_H |
| | | #define RECIPE_MANAGER_H |
| | | |
| | | #include <string> |
| | | #include <vector> |
| | | #include <map> |
| | | #include "pugixml.hpp" |
| | | |
| | | struct ValueRange { |
| | | double minValue; // æå°å¼ |
| | | double maxValue; // æå¤§å¼ |
| | | double currentValue; // å½åå¼ |
| | | |
| | | // æé 彿°åå§å |
| | | ValueRange(double minVal = 0.0, double maxVal = 0.0, double curVal = 0.0) |
| | | : minValue(minVal), maxValue(maxVal), currentValue(curVal) {} |
| | | }; |
| | | |
| | | struct PositionRange { |
| | | BOOL isEnable; // æ¯å¦å¯ç¨ |
| | | std::string description; // å®ä½ç¹æè¿° |
| | | ValueRange range; // ä½ç½®çæå°å¼ãæå¤§å¼åå½åå¼ |
| | | |
| | | // æé 彿°åå§å |
| | | PositionRange(BOOL b = TRUE, const std::string& desc = "", const ValueRange& r = ValueRange()) |
| | | :isEnable(b), description(desc), range(r) {} |
| | | }; |
| | | |
| | | // è½´ä¿¡æ¯ç»æä½ |
| | | struct AxisInfo { |
| | | int id; // è½´ID |
| | | int positioningPointCount; // å®ä½ç¹æ° |
| | | //double maxPositioningSpeed; // å®ä½é度ä¸é |
| | | //double maxManualSpeed; // æå¨é度ä¸é |
| | | std::string number; // è½´ç¼å· |
| | | std::string description; // è½´æè¿° |
| | | std::string startAddress; // èµ·å§å°å |
| | | ValueRange jogDistance; // å¾®å¨éï¼æå°å¼ãæå¤§å¼ãå½åå¼ï¼ |
| | | ValueRange manualSpeed; // æå¨éåº¦ï¼æå°å¼ãæå¤§å¼ãå½åå¼ï¼ |
| | | ValueRange autoSpeed; // èªå¨éåº¦ï¼æå°å¼ãæå¤§å¼ãå½åå¼ï¼ |
| | | ValueRange accelerationTime; // å éæ¶é´ï¼æå°å¼ãæå¤§å¼ãå½åå¼ï¼ |
| | | ValueRange decelerationTime; // åéæ¶é´ï¼æå°å¼ãæå¤§å¼ãå½åå¼ï¼ |
| | | std::vector<PositionRange> positions; // å®ä½ç¹ï¼æè¿°ãä½ç½®åæå°æå¤§å¼ |
| | | }; |
| | | |
| | | // é
æ¹ç®¡çç±» |
| | | class RecipeManager { |
| | | public: |
| | | // å便¨¡å¼è·åå®ä¾ |
| | | static RecipeManager& getInstance(); |
| | | |
| | | // 设置é
æ¹æä»¶å¤¹è·¯å¾ |
| | | void setRecipeFolder(const std::string& folderPath); |
| | | |
| | | // è·åå½åé
æ¹åç§° |
| | | std::string getCurrentRecipeName() const; |
| | | |
| | | // å è½½é
æ¹ï¼æä»¶ä¸å卿¶å è½½é»è®¤æ°æ®ï¼ |
| | | bool loadRecipe(const std::string& recipeName); |
| | | |
| | | // ä¿åé
æ¹ |
| | | bool saveRecipe(const std::string& recipeName); |
| | | |
| | | // çæé»è®¤é
æ¹ |
| | | void generateDefaultRecipe(); |
| | | |
| | | // è·åææè½´ä¿¡æ¯ |
| | | const std::map<int, AxisInfo>& getAxes() const; |
| | | |
| | | // è·ååä¸ªè½´ä¿¡æ¯ |
| | | AxisInfo getAxis(int axisId) const; |
| | | |
| | | // æ´æ°è½´ä¿¡æ¯ |
| | | bool updateAxis(const AxisInfo& axisInfo); |
| | | |
| | | // æ·»å æ°çè½´ä¿¡æ¯ |
| | | bool addAxis(const AxisInfo& axisInfo); |
| | | |
| | | // å é¤è½´ä¿¡æ¯ |
| | | bool deleteAxis(int axisId); |
| | | |
| | | // è·åææè½´ID |
| | | std::vector<int> getAllAxisID() const; |
| | | |
| | | // è·åæå®é¡µçå®ä½ç¹ |
| | | std::vector<PositionRange> getPositions(int axisId, int pageNumber, int pageSize) const; |
| | | |
| | | // è·åæå®é¡µçå®ä½ç¹ |
| | | PositionRange getPositionByIndex(int axisId, int pageNumber, int pageSize, int currentIndex) const; |
| | | |
| | | private: |
| | | RecipeManager(); |
| | | |
| | | // è½´å è½½åä¿å彿° |
| | | bool loadAxes(pugi::xml_node axesNode); |
| | | void saveAxes(pugi::xml_node& axesNode); |
| | | |
| | | private: |
| | | std::string m_currentRecipeName; // å½åé
æ¹åç§° |
| | | std::string m_recipeFolder; // é
æ¹æä»¶å¤¹è·¯å¾ |
| | | std::map<int, AxisInfo> m_axes; // è½´ä¿¡æ¯ç¼å |
| | | }; |
| | | |
| | | #endif // RECIPE_MANAGER_H |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | /** |
| | | * pugixml parser - version 1.14 |
| | | * -------------------------------------------------------- |
| | | * Copyright (C) 2006-2023, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) |
| | | * Report bugs and download new versions at https://pugixml.org/ |
| | | * |
| | | * This library is distributed under the MIT License. See notice at the end |
| | | * of this file. |
| | | * |
| | | * This work is based on the pugxml parser, which is: |
| | | * Copyright (C) 2003, by Kristen Wegner (kristen@tima.net) |
| | | */ |
| | | |
| | | #ifndef HEADER_PUGICONFIG_HPP |
| | | #define HEADER_PUGICONFIG_HPP |
| | | |
| | | // Uncomment this to enable wchar_t mode |
| | | // #define PUGIXML_WCHAR_MODE |
| | | |
| | | // Uncomment this to enable compact mode |
| | | // #define PUGIXML_COMPACT |
| | | |
| | | // Uncomment this to disable XPath |
| | | // #define PUGIXML_NO_XPATH |
| | | |
| | | // Uncomment this to disable STL |
| | | // #define PUGIXML_NO_STL |
| | | |
| | | // Uncomment this to disable exceptions |
| | | // #define PUGIXML_NO_EXCEPTIONS |
| | | |
| | | // Set this to control attributes for public classes/functions, i.e.: |
| | | // #define PUGIXML_API __declspec(dllexport) // to export all public symbols from DLL |
| | | // #define PUGIXML_CLASS __declspec(dllimport) // to import all classes from DLL |
| | | // #define PUGIXML_FUNCTION __fastcall // to set calling conventions to all public functions to fastcall |
| | | // In absence of PUGIXML_CLASS/PUGIXML_FUNCTION definitions PUGIXML_API is used instead |
| | | |
| | | // Tune these constants to adjust memory-related behavior |
| | | // #define PUGIXML_MEMORY_PAGE_SIZE 32768 |
| | | // #define PUGIXML_MEMORY_OUTPUT_STACK 10240 |
| | | // #define PUGIXML_MEMORY_XPATH_PAGE_SIZE 4096 |
| | | |
| | | // Tune this constant to adjust max nesting for XPath queries |
| | | // #define PUGIXML_XPATH_DEPTH_LIMIT 1024 |
| | | |
| | | // Uncomment this to switch to header-only version |
| | | // #define PUGIXML_HEADER_ONLY |
| | | |
| | | // Uncomment this to enable long long support |
| | | // #define PUGIXML_HAS_LONG_LONG |
| | | |
| | | #endif |
| | | |
| | | /** |
| | | * Copyright (c) 2006-2023 Arseny Kapoulkine |
| | | * |
| | | * Permission is hereby granted, free of charge, to any person |
| | | * obtaining a copy of this software and associated documentation |
| | | * files (the "Software"), to deal in the Software without |
| | | * restriction, including without limitation the rights to use, |
| | | * copy, modify, merge, publish, distribute, sublicense, and/or sell |
| | | * copies of the Software, and to permit persons to whom the |
| | | * Software is furnished to do so, subject to the following |
| | | * conditions: |
| | | * |
| | | * The above copyright notice and this permission notice shall be |
| | | * included in all copies or substantial portions of the Software. |
| | | * |
| | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| | | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
| | | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| | | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
| | | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
| | | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| | | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| | | * OTHER DEALINGS IN THE SOFTWARE. |
| | | */ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | /** |
| | | * pugixml parser - version 1.14 |
| | | * -------------------------------------------------------- |
| | | * Copyright (C) 2006-2023, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) |
| | | * Report bugs and download new versions at https://pugixml.org/ |
| | | * |
| | | * This library is distributed under the MIT License. See notice at the end |
| | | * of this file. |
| | | * |
| | | * This work is based on the pugxml parser, which is: |
| | | * Copyright (C) 2003, by Kristen Wegner (kristen@tima.net) |
| | | */ |
| | | |
| | | // Define version macro; evaluates to major * 1000 + minor * 10 + patch so that it's safe to use in less-than comparisons |
| | | // Note: pugixml used major * 100 + minor * 10 + patch format up until 1.9 (which had version identifier 190); starting from pugixml 1.10, the minor version number is two digits |
| | | #ifndef PUGIXML_VERSION |
| | | # define PUGIXML_VERSION 1140 // 1.14 |
| | | #endif |
| | | |
| | | // Include user configuration file (this can define various configuration macros) |
| | | #include "pugiconfig.hpp" |
| | | |
| | | #ifndef HEADER_PUGIXML_HPP |
| | | #define HEADER_PUGIXML_HPP |
| | | |
| | | // Include stddef.h for size_t and ptrdiff_t |
| | | #include <stddef.h> |
| | | |
| | | // Include exception header for XPath |
| | | #if !defined(PUGIXML_NO_XPATH) && !defined(PUGIXML_NO_EXCEPTIONS) |
| | | # include <exception> |
| | | #endif |
| | | |
| | | // Include STL headers |
| | | #ifndef PUGIXML_NO_STL |
| | | # include <iterator> |
| | | # include <iosfwd> |
| | | # include <string> |
| | | #endif |
| | | |
| | | // Macro for deprecated features |
| | | #ifndef PUGIXML_DEPRECATED |
| | | # if defined(__GNUC__) |
| | | # define PUGIXML_DEPRECATED __attribute__((deprecated)) |
| | | # elif defined(_MSC_VER) && _MSC_VER >= 1300 |
| | | # define PUGIXML_DEPRECATED __declspec(deprecated) |
| | | # else |
| | | # define PUGIXML_DEPRECATED |
| | | # endif |
| | | #endif |
| | | |
| | | // If no API is defined, assume default |
| | | #ifndef PUGIXML_API |
| | | # define PUGIXML_API |
| | | #endif |
| | | |
| | | // If no API for classes is defined, assume default |
| | | #ifndef PUGIXML_CLASS |
| | | # define PUGIXML_CLASS PUGIXML_API |
| | | #endif |
| | | |
| | | // If no API for functions is defined, assume default |
| | | #ifndef PUGIXML_FUNCTION |
| | | # define PUGIXML_FUNCTION PUGIXML_API |
| | | #endif |
| | | |
| | | // If the platform is known to have long long support, enable long long functions |
| | | #ifndef PUGIXML_HAS_LONG_LONG |
| | | # if __cplusplus >= 201103 |
| | | # define PUGIXML_HAS_LONG_LONG |
| | | # elif defined(_MSC_VER) && _MSC_VER >= 1400 |
| | | # define PUGIXML_HAS_LONG_LONG |
| | | # endif |
| | | #endif |
| | | |
| | | // If the platform is known to have move semantics support, compile move ctor/operator implementation |
| | | #ifndef PUGIXML_HAS_MOVE |
| | | # if __cplusplus >= 201103 |
| | | # define PUGIXML_HAS_MOVE |
| | | # elif defined(_MSC_VER) && _MSC_VER >= 1600 |
| | | # define PUGIXML_HAS_MOVE |
| | | # endif |
| | | #endif |
| | | |
| | | // If C++ is 2011 or higher, add 'noexcept' specifiers |
| | | #ifndef PUGIXML_NOEXCEPT |
| | | # if __cplusplus >= 201103 |
| | | # define PUGIXML_NOEXCEPT noexcept |
| | | # elif defined(_MSC_VER) && _MSC_VER >= 1900 |
| | | # define PUGIXML_NOEXCEPT noexcept |
| | | # else |
| | | # define PUGIXML_NOEXCEPT |
| | | # endif |
| | | #endif |
| | | |
| | | // Some functions can not be noexcept in compact mode |
| | | #ifdef PUGIXML_COMPACT |
| | | # define PUGIXML_NOEXCEPT_IF_NOT_COMPACT |
| | | #else |
| | | # define PUGIXML_NOEXCEPT_IF_NOT_COMPACT PUGIXML_NOEXCEPT |
| | | #endif |
| | | |
| | | // If C++ is 2011 or higher, add 'override' qualifiers |
| | | #ifndef PUGIXML_OVERRIDE |
| | | # if __cplusplus >= 201103 |
| | | # define PUGIXML_OVERRIDE override |
| | | # elif defined(_MSC_VER) && _MSC_VER >= 1700 |
| | | # define PUGIXML_OVERRIDE override |
| | | # else |
| | | # define PUGIXML_OVERRIDE |
| | | # endif |
| | | #endif |
| | | |
| | | // If C++ is 2011 or higher, use 'nullptr' |
| | | #ifndef PUGIXML_NULL |
| | | # if __cplusplus >= 201103 |
| | | # define PUGIXML_NULL nullptr |
| | | # elif defined(_MSC_VER) && _MSC_VER >= 1600 |
| | | # define PUGIXML_NULL nullptr |
| | | # else |
| | | # define PUGIXML_NULL 0 |
| | | # endif |
| | | #endif |
| | | |
| | | // Character interface macros |
| | | #ifdef PUGIXML_WCHAR_MODE |
| | | # define PUGIXML_TEXT(t) L ## t |
| | | # define PUGIXML_CHAR wchar_t |
| | | #else |
| | | # define PUGIXML_TEXT(t) t |
| | | # define PUGIXML_CHAR char |
| | | #endif |
| | | |
| | | namespace pugi |
| | | { |
| | | // Character type used for all internal storage and operations; depends on PUGIXML_WCHAR_MODE |
| | | typedef PUGIXML_CHAR char_t; |
| | | |
| | | #ifndef PUGIXML_NO_STL |
| | | // String type used for operations that work with STL string; depends on PUGIXML_WCHAR_MODE |
| | | typedef std::basic_string<PUGIXML_CHAR, std::char_traits<PUGIXML_CHAR>, std::allocator<PUGIXML_CHAR> > string_t; |
| | | #endif |
| | | } |
| | | |
| | | // The PugiXML namespace |
| | | namespace pugi |
| | | { |
| | | // Tree node types |
| | | enum xml_node_type |
| | | { |
| | | node_null, // Empty (null) node handle |
| | | node_document, // A document tree's absolute root |
| | | node_element, // Element tag, i.e. '<node/>' |
| | | node_pcdata, // Plain character data, i.e. 'text' |
| | | node_cdata, // Character data, i.e. '<![CDATA[text]]>' |
| | | node_comment, // Comment tag, i.e. '<!-- text -->' |
| | | node_pi, // Processing instruction, i.e. '<?name?>' |
| | | node_declaration, // Document declaration, i.e. '<?xml version="1.0"?>' |
| | | node_doctype // Document type declaration, i.e. '<!DOCTYPE doc>' |
| | | }; |
| | | |
| | | // Parsing options |
| | | |
| | | // Minimal parsing mode (equivalent to turning all other flags off). |
| | | // Only elements and PCDATA sections are added to the DOM tree, no text conversions are performed. |
| | | const unsigned int parse_minimal = 0x0000; |
| | | |
| | | // This flag determines if processing instructions (node_pi) are added to the DOM tree. This flag is off by default. |
| | | const unsigned int parse_pi = 0x0001; |
| | | |
| | | // This flag determines if comments (node_comment) are added to the DOM tree. This flag is off by default. |
| | | const unsigned int parse_comments = 0x0002; |
| | | |
| | | // This flag determines if CDATA sections (node_cdata) are added to the DOM tree. This flag is on by default. |
| | | const unsigned int parse_cdata = 0x0004; |
| | | |
| | | // This flag determines if plain character data (node_pcdata) that consist only of whitespace are added to the DOM tree. |
| | | // This flag is off by default; turning it on usually results in slower parsing and more memory consumption. |
| | | const unsigned int parse_ws_pcdata = 0x0008; |
| | | |
| | | // This flag determines if character and entity references are expanded during parsing. This flag is on by default. |
| | | const unsigned int parse_escapes = 0x0010; |
| | | |
| | | // This flag determines if EOL characters are normalized (converted to #xA) during parsing. This flag is on by default. |
| | | const unsigned int parse_eol = 0x0020; |
| | | |
| | | // This flag determines if attribute values are normalized using CDATA normalization rules during parsing. This flag is on by default. |
| | | const unsigned int parse_wconv_attribute = 0x0040; |
| | | |
| | | // This flag determines if attribute values are normalized using NMTOKENS normalization rules during parsing. This flag is off by default. |
| | | const unsigned int parse_wnorm_attribute = 0x0080; |
| | | |
| | | // This flag determines if document declaration (node_declaration) is added to the DOM tree. This flag is off by default. |
| | | const unsigned int parse_declaration = 0x0100; |
| | | |
| | | // This flag determines if document type declaration (node_doctype) is added to the DOM tree. This flag is off by default. |
| | | const unsigned int parse_doctype = 0x0200; |
| | | |
| | | // This flag determines if plain character data (node_pcdata) that is the only child of the parent node and that consists only |
| | | // of whitespace is added to the DOM tree. |
| | | // This flag is off by default; turning it on may result in slower parsing and more memory consumption. |
| | | const unsigned int parse_ws_pcdata_single = 0x0400; |
| | | |
| | | // This flag determines if leading and trailing whitespace is to be removed from plain character data. This flag is off by default. |
| | | const unsigned int parse_trim_pcdata = 0x0800; |
| | | |
| | | // This flag determines if plain character data that does not have a parent node is added to the DOM tree, and if an empty document |
| | | // is a valid document. This flag is off by default. |
| | | const unsigned int parse_fragment = 0x1000; |
| | | |
| | | // This flag determines if plain character data is be stored in the parent element's value. This significantly changes the structure of |
| | | // the document; this flag is only recommended for parsing documents with many PCDATA nodes in memory-constrained environments. |
| | | // This flag is off by default. |
| | | const unsigned int parse_embed_pcdata = 0x2000; |
| | | |
| | | // This flag determines whether determines whether the the two pcdata should be merged or not, if no intermediatory data are parsed in the document. |
| | | // This flag is off by default. |
| | | const unsigned int parse_merge_pcdata = 0x4000; |
| | | |
| | | // The default parsing mode. |
| | | // Elements, PCDATA and CDATA sections are added to the DOM tree, character/reference entities are expanded, |
| | | // End-of-Line characters are normalized, attribute values are normalized using CDATA normalization rules. |
| | | const unsigned int parse_default = parse_cdata | parse_escapes | parse_wconv_attribute | parse_eol; |
| | | |
| | | // The full parsing mode. |
| | | // Nodes of all types are added to the DOM tree, character/reference entities are expanded, |
| | | // End-of-Line characters are normalized, attribute values are normalized using CDATA normalization rules. |
| | | const unsigned int parse_full = parse_default | parse_pi | parse_comments | parse_declaration | parse_doctype; |
| | | |
| | | // These flags determine the encoding of input data for XML document |
| | | enum xml_encoding |
| | | { |
| | | encoding_auto, // Auto-detect input encoding using BOM or < / <? detection; use UTF8 if BOM is not found |
| | | encoding_utf8, // UTF8 encoding |
| | | encoding_utf16_le, // Little-endian UTF16 |
| | | encoding_utf16_be, // Big-endian UTF16 |
| | | encoding_utf16, // UTF16 with native endianness |
| | | encoding_utf32_le, // Little-endian UTF32 |
| | | encoding_utf32_be, // Big-endian UTF32 |
| | | encoding_utf32, // UTF32 with native endianness |
| | | encoding_wchar, // The same encoding wchar_t has (either UTF16 or UTF32) |
| | | encoding_latin1 |
| | | }; |
| | | |
| | | // Formatting flags |
| | | |
| | | // Indent the nodes that are written to output stream with as many indentation strings as deep the node is in DOM tree. This flag is on by default. |
| | | const unsigned int format_indent = 0x01; |
| | | |
| | | // Write encoding-specific BOM to the output stream. This flag is off by default. |
| | | const unsigned int format_write_bom = 0x02; |
| | | |
| | | // Use raw output mode (no indentation and no line breaks are written). This flag is off by default. |
| | | const unsigned int format_raw = 0x04; |
| | | |
| | | // Omit default XML declaration even if there is no declaration in the document. This flag is off by default. |
| | | const unsigned int format_no_declaration = 0x08; |
| | | |
| | | // Don't escape attribute values and PCDATA contents. This flag is off by default. |
| | | const unsigned int format_no_escapes = 0x10; |
| | | |
| | | // Open file using text mode in xml_document::save_file. This enables special character (i.e. new-line) conversions on some systems. This flag is off by default. |
| | | const unsigned int format_save_file_text = 0x20; |
| | | |
| | | // Write every attribute on a new line with appropriate indentation. This flag is off by default. |
| | | const unsigned int format_indent_attributes = 0x40; |
| | | |
| | | // Don't output empty element tags, instead writing an explicit start and end tag even if there are no children. This flag is off by default. |
| | | const unsigned int format_no_empty_element_tags = 0x80; |
| | | |
| | | // Skip characters belonging to range [0; 32) instead of "&#xNN;" encoding. This flag is off by default. |
| | | const unsigned int format_skip_control_chars = 0x100; |
| | | |
| | | // Use single quotes ' instead of double quotes " for enclosing attribute values. This flag is off by default. |
| | | const unsigned int format_attribute_single_quote = 0x200; |
| | | |
| | | // The default set of formatting flags. |
| | | // Nodes are indented depending on their depth in DOM tree, a default declaration is output if document has none. |
| | | const unsigned int format_default = format_indent; |
| | | |
| | | const int default_double_precision = 17; |
| | | const int default_float_precision = 9; |
| | | |
| | | // Forward declarations |
| | | struct xml_attribute_struct; |
| | | struct xml_node_struct; |
| | | |
| | | class xml_node_iterator; |
| | | class xml_attribute_iterator; |
| | | class xml_named_node_iterator; |
| | | |
| | | class xml_tree_walker; |
| | | |
| | | struct xml_parse_result; |
| | | |
| | | class xml_node; |
| | | |
| | | class xml_text; |
| | | |
| | | #ifndef PUGIXML_NO_XPATH |
| | | class xpath_node; |
| | | class xpath_node_set; |
| | | class xpath_query; |
| | | class xpath_variable_set; |
| | | #endif |
| | | |
| | | // Range-based for loop support |
| | | template <typename It> class xml_object_range |
| | | { |
| | | public: |
| | | typedef It const_iterator; |
| | | typedef It iterator; |
| | | |
| | | xml_object_range(It b, It e): _begin(b), _end(e) |
| | | { |
| | | } |
| | | |
| | | It begin() const { return _begin; } |
| | | It end() const { return _end; } |
| | | |
| | | bool empty() const { return _begin == _end; } |
| | | |
| | | private: |
| | | It _begin, _end; |
| | | }; |
| | | |
| | | // Writer interface for node printing (see xml_node::print) |
| | | class PUGIXML_CLASS xml_writer |
| | | { |
| | | public: |
| | | virtual ~xml_writer(); |
| | | |
| | | // Write memory chunk into stream/file/whatever |
| | | virtual void write(const void* data, size_t size) = 0; |
| | | }; |
| | | |
| | | // xml_writer implementation for FILE* |
| | | class PUGIXML_CLASS xml_writer_file: public xml_writer |
| | | { |
| | | public: |
| | | // Construct writer from a FILE* object; void* is used to avoid header dependencies on stdio |
| | | xml_writer_file(void* file); |
| | | |
| | | virtual void write(const void* data, size_t size) PUGIXML_OVERRIDE; |
| | | |
| | | private: |
| | | void* file; |
| | | }; |
| | | |
| | | #ifndef PUGIXML_NO_STL |
| | | // xml_writer implementation for streams |
| | | class PUGIXML_CLASS xml_writer_stream: public xml_writer |
| | | { |
| | | public: |
| | | // Construct writer from an output stream object |
| | | xml_writer_stream(std::basic_ostream<char, std::char_traits<char> >& stream); |
| | | xml_writer_stream(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& stream); |
| | | |
| | | virtual void write(const void* data, size_t size) PUGIXML_OVERRIDE; |
| | | |
| | | private: |
| | | std::basic_ostream<char, std::char_traits<char> >* narrow_stream; |
| | | std::basic_ostream<wchar_t, std::char_traits<wchar_t> >* wide_stream; |
| | | }; |
| | | #endif |
| | | |
| | | // A light-weight handle for manipulating attributes in DOM tree |
| | | class PUGIXML_CLASS xml_attribute |
| | | { |
| | | friend class xml_attribute_iterator; |
| | | friend class xml_node; |
| | | |
| | | private: |
| | | xml_attribute_struct* _attr; |
| | | |
| | | typedef void (*unspecified_bool_type)(xml_attribute***); |
| | | |
| | | public: |
| | | // Default constructor. Constructs an empty attribute. |
| | | xml_attribute(); |
| | | |
| | | // Constructs attribute from internal pointer |
| | | explicit xml_attribute(xml_attribute_struct* attr); |
| | | |
| | | // Safe bool conversion operator |
| | | operator unspecified_bool_type() const; |
| | | |
| | | // Borland C++ workaround |
| | | bool operator!() const; |
| | | |
| | | // Comparison operators (compares wrapped attribute pointers) |
| | | bool operator==(const xml_attribute& r) const; |
| | | bool operator!=(const xml_attribute& r) const; |
| | | bool operator<(const xml_attribute& r) const; |
| | | bool operator>(const xml_attribute& r) const; |
| | | bool operator<=(const xml_attribute& r) const; |
| | | bool operator>=(const xml_attribute& r) const; |
| | | |
| | | // Check if attribute is empty |
| | | bool empty() const; |
| | | |
| | | // Get attribute name/value, or "" if attribute is empty |
| | | const char_t* name() const; |
| | | const char_t* value() const; |
| | | |
| | | // Get attribute value, or the default value if attribute is empty |
| | | const char_t* as_string(const char_t* def = PUGIXML_TEXT("")) const; |
| | | |
| | | // Get attribute value as a number, or the default value if conversion did not succeed or attribute is empty |
| | | int as_int(int def = 0) const; |
| | | unsigned int as_uint(unsigned int def = 0) const; |
| | | double as_double(double def = 0) const; |
| | | float as_float(float def = 0) const; |
| | | |
| | | #ifdef PUGIXML_HAS_LONG_LONG |
| | | long long as_llong(long long def = 0) const; |
| | | unsigned long long as_ullong(unsigned long long def = 0) const; |
| | | #endif |
| | | |
| | | // Get attribute value as bool (returns true if first character is in '1tTyY' set), or the default value if attribute is empty |
| | | bool as_bool(bool def = false) const; |
| | | |
| | | // Set attribute name/value (returns false if attribute is empty or there is not enough memory) |
| | | bool set_name(const char_t* rhs); |
| | | bool set_name(const char_t* rhs, size_t size); |
| | | bool set_value(const char_t* rhs); |
| | | bool set_value(const char_t* rhs, size_t size); |
| | | |
| | | // Set attribute value with type conversion (numbers are converted to strings, boolean is converted to "true"/"false") |
| | | bool set_value(int rhs); |
| | | bool set_value(unsigned int rhs); |
| | | bool set_value(long rhs); |
| | | bool set_value(unsigned long rhs); |
| | | bool set_value(double rhs); |
| | | bool set_value(double rhs, int precision); |
| | | bool set_value(float rhs); |
| | | bool set_value(float rhs, int precision); |
| | | bool set_value(bool rhs); |
| | | |
| | | #ifdef PUGIXML_HAS_LONG_LONG |
| | | bool set_value(long long rhs); |
| | | bool set_value(unsigned long long rhs); |
| | | #endif |
| | | |
| | | // Set attribute value (equivalent to set_value without error checking) |
| | | xml_attribute& operator=(const char_t* rhs); |
| | | xml_attribute& operator=(int rhs); |
| | | xml_attribute& operator=(unsigned int rhs); |
| | | xml_attribute& operator=(long rhs); |
| | | xml_attribute& operator=(unsigned long rhs); |
| | | xml_attribute& operator=(double rhs); |
| | | xml_attribute& operator=(float rhs); |
| | | xml_attribute& operator=(bool rhs); |
| | | |
| | | #ifdef PUGIXML_HAS_LONG_LONG |
| | | xml_attribute& operator=(long long rhs); |
| | | xml_attribute& operator=(unsigned long long rhs); |
| | | #endif |
| | | |
| | | // Get next/previous attribute in the attribute list of the parent node |
| | | xml_attribute next_attribute() const; |
| | | xml_attribute previous_attribute() const; |
| | | |
| | | // Get hash value (unique for handles to the same object) |
| | | size_t hash_value() const; |
| | | |
| | | // Get internal pointer |
| | | xml_attribute_struct* internal_object() const; |
| | | }; |
| | | |
| | | #ifdef __BORLANDC__ |
| | | // Borland C++ workaround |
| | | bool PUGIXML_FUNCTION operator&&(const xml_attribute& lhs, bool rhs); |
| | | bool PUGIXML_FUNCTION operator||(const xml_attribute& lhs, bool rhs); |
| | | #endif |
| | | |
| | | // A light-weight handle for manipulating nodes in DOM tree |
| | | class PUGIXML_CLASS xml_node |
| | | { |
| | | friend class xml_attribute_iterator; |
| | | friend class xml_node_iterator; |
| | | friend class xml_named_node_iterator; |
| | | |
| | | protected: |
| | | xml_node_struct* _root; |
| | | |
| | | typedef void (*unspecified_bool_type)(xml_node***); |
| | | |
| | | public: |
| | | // Default constructor. Constructs an empty node. |
| | | xml_node(); |
| | | |
| | | // Constructs node from internal pointer |
| | | explicit xml_node(xml_node_struct* p); |
| | | |
| | | // Safe bool conversion operator |
| | | operator unspecified_bool_type() const; |
| | | |
| | | // Borland C++ workaround |
| | | bool operator!() const; |
| | | |
| | | // Comparison operators (compares wrapped node pointers) |
| | | bool operator==(const xml_node& r) const; |
| | | bool operator!=(const xml_node& r) const; |
| | | bool operator<(const xml_node& r) const; |
| | | bool operator>(const xml_node& r) const; |
| | | bool operator<=(const xml_node& r) const; |
| | | bool operator>=(const xml_node& r) const; |
| | | |
| | | // Check if node is empty. |
| | | bool empty() const; |
| | | |
| | | // Get node type |
| | | xml_node_type type() const; |
| | | |
| | | // Get node name, or "" if node is empty or it has no name |
| | | const char_t* name() const; |
| | | |
| | | // Get node value, or "" if node is empty or it has no value |
| | | // Note: For <node>text</node> node.value() does not return "text"! Use child_value() or text() methods to access text inside nodes. |
| | | const char_t* value() const; |
| | | |
| | | // Get attribute list |
| | | xml_attribute first_attribute() const; |
| | | xml_attribute last_attribute() const; |
| | | |
| | | // Get children list |
| | | xml_node first_child() const; |
| | | xml_node last_child() const; |
| | | |
| | | // Get next/previous sibling in the children list of the parent node |
| | | xml_node next_sibling() const; |
| | | xml_node previous_sibling() const; |
| | | |
| | | // Get parent node |
| | | xml_node parent() const; |
| | | |
| | | // Get root of DOM tree this node belongs to |
| | | xml_node root() const; |
| | | |
| | | // Get text object for the current node |
| | | xml_text text() const; |
| | | |
| | | // Get child, attribute or next/previous sibling with the specified name |
| | | xml_node child(const char_t* name) const; |
| | | xml_attribute attribute(const char_t* name) const; |
| | | xml_node next_sibling(const char_t* name) const; |
| | | xml_node previous_sibling(const char_t* name) const; |
| | | |
| | | // Get attribute, starting the search from a hint (and updating hint so that searching for a sequence of attributes is fast) |
| | | xml_attribute attribute(const char_t* name, xml_attribute& hint) const; |
| | | |
| | | // Get child value of current node; that is, value of the first child node of type PCDATA/CDATA |
| | | const char_t* child_value() const; |
| | | |
| | | // Get child value of child with specified name. Equivalent to child(name).child_value(). |
| | | const char_t* child_value(const char_t* name) const; |
| | | |
| | | // Set node name/value (returns false if node is empty, there is not enough memory, or node can not have name/value) |
| | | bool set_name(const char_t* rhs); |
| | | bool set_name(const char_t* rhs, size_t size); |
| | | bool set_value(const char_t* rhs); |
| | | bool set_value(const char_t* rhs, size_t size); |
| | | |
| | | // Add attribute with specified name. Returns added attribute, or empty attribute on errors. |
| | | xml_attribute append_attribute(const char_t* name); |
| | | xml_attribute prepend_attribute(const char_t* name); |
| | | xml_attribute insert_attribute_after(const char_t* name, const xml_attribute& attr); |
| | | xml_attribute insert_attribute_before(const char_t* name, const xml_attribute& attr); |
| | | |
| | | // Add a copy of the specified attribute. Returns added attribute, or empty attribute on errors. |
| | | xml_attribute append_copy(const xml_attribute& proto); |
| | | xml_attribute prepend_copy(const xml_attribute& proto); |
| | | xml_attribute insert_copy_after(const xml_attribute& proto, const xml_attribute& attr); |
| | | xml_attribute insert_copy_before(const xml_attribute& proto, const xml_attribute& attr); |
| | | |
| | | // Add child node with specified type. Returns added node, or empty node on errors. |
| | | xml_node append_child(xml_node_type type = node_element); |
| | | xml_node prepend_child(xml_node_type type = node_element); |
| | | xml_node insert_child_after(xml_node_type type, const xml_node& node); |
| | | xml_node insert_child_before(xml_node_type type, const xml_node& node); |
| | | |
| | | // Add child element with specified name. Returns added node, or empty node on errors. |
| | | xml_node append_child(const char_t* name); |
| | | xml_node prepend_child(const char_t* name); |
| | | xml_node insert_child_after(const char_t* name, const xml_node& node); |
| | | xml_node insert_child_before(const char_t* name, const xml_node& node); |
| | | |
| | | // Add a copy of the specified node as a child. Returns added node, or empty node on errors. |
| | | xml_node append_copy(const xml_node& proto); |
| | | xml_node prepend_copy(const xml_node& proto); |
| | | xml_node insert_copy_after(const xml_node& proto, const xml_node& node); |
| | | xml_node insert_copy_before(const xml_node& proto, const xml_node& node); |
| | | |
| | | // Move the specified node to become a child of this node. Returns moved node, or empty node on errors. |
| | | xml_node append_move(const xml_node& moved); |
| | | xml_node prepend_move(const xml_node& moved); |
| | | xml_node insert_move_after(const xml_node& moved, const xml_node& node); |
| | | xml_node insert_move_before(const xml_node& moved, const xml_node& node); |
| | | |
| | | // Remove specified attribute |
| | | bool remove_attribute(const xml_attribute& a); |
| | | bool remove_attribute(const char_t* name); |
| | | |
| | | // Remove all attributes |
| | | bool remove_attributes(); |
| | | |
| | | // Remove specified child |
| | | bool remove_child(const xml_node& n); |
| | | bool remove_child(const char_t* name); |
| | | |
| | | // Remove all children |
| | | bool remove_children(); |
| | | |
| | | // Parses buffer as an XML document fragment and appends all nodes as children of the current node. |
| | | // Copies/converts the buffer, so it may be deleted or changed after the function returns. |
| | | // Note: append_buffer allocates memory that has the lifetime of the owning document; removing the appended nodes does not immediately reclaim that memory. |
| | | xml_parse_result append_buffer(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); |
| | | |
| | | // Find attribute using predicate. Returns first attribute for which predicate returned true. |
| | | template <typename Predicate> xml_attribute find_attribute(Predicate pred) const |
| | | { |
| | | if (!_root) return xml_attribute(); |
| | | |
| | | for (xml_attribute attrib = first_attribute(); attrib; attrib = attrib.next_attribute()) |
| | | if (pred(attrib)) |
| | | return attrib; |
| | | |
| | | return xml_attribute(); |
| | | } |
| | | |
| | | // Find child node using predicate. Returns first child for which predicate returned true. |
| | | template <typename Predicate> xml_node find_child(Predicate pred) const |
| | | { |
| | | if (!_root) return xml_node(); |
| | | |
| | | for (xml_node node = first_child(); node; node = node.next_sibling()) |
| | | if (pred(node)) |
| | | return node; |
| | | |
| | | return xml_node(); |
| | | } |
| | | |
| | | // Find node from subtree using predicate. Returns first node from subtree (depth-first), for which predicate returned true. |
| | | template <typename Predicate> xml_node find_node(Predicate pred) const |
| | | { |
| | | if (!_root) return xml_node(); |
| | | |
| | | xml_node cur = first_child(); |
| | | |
| | | while (cur._root && cur._root != _root) |
| | | { |
| | | if (pred(cur)) return cur; |
| | | |
| | | if (cur.first_child()) cur = cur.first_child(); |
| | | else if (cur.next_sibling()) cur = cur.next_sibling(); |
| | | else |
| | | { |
| | | while (!cur.next_sibling() && cur._root != _root) cur = cur.parent(); |
| | | |
| | | if (cur._root != _root) cur = cur.next_sibling(); |
| | | } |
| | | } |
| | | |
| | | return xml_node(); |
| | | } |
| | | |
| | | // Find child node by attribute name/value |
| | | xml_node find_child_by_attribute(const char_t* name, const char_t* attr_name, const char_t* attr_value) const; |
| | | xml_node find_child_by_attribute(const char_t* attr_name, const char_t* attr_value) const; |
| | | |
| | | #ifndef PUGIXML_NO_STL |
| | | // Get the absolute node path from root as a text string. |
| | | string_t path(char_t delimiter = '/') const; |
| | | #endif |
| | | |
| | | // Search for a node by path consisting of node names and . or .. elements. |
| | | xml_node first_element_by_path(const char_t* path, char_t delimiter = '/') const; |
| | | |
| | | // Recursively traverse subtree with xml_tree_walker |
| | | bool traverse(xml_tree_walker& walker); |
| | | |
| | | #ifndef PUGIXML_NO_XPATH |
| | | // Select single node by evaluating XPath query. Returns first node from the resulting node set. |
| | | xpath_node select_node(const char_t* query, xpath_variable_set* variables = PUGIXML_NULL) const; |
| | | xpath_node select_node(const xpath_query& query) const; |
| | | |
| | | // Select node set by evaluating XPath query |
| | | xpath_node_set select_nodes(const char_t* query, xpath_variable_set* variables = PUGIXML_NULL) const; |
| | | xpath_node_set select_nodes(const xpath_query& query) const; |
| | | |
| | | // (deprecated: use select_node instead) Select single node by evaluating XPath query. |
| | | PUGIXML_DEPRECATED xpath_node select_single_node(const char_t* query, xpath_variable_set* variables = PUGIXML_NULL) const; |
| | | PUGIXML_DEPRECATED xpath_node select_single_node(const xpath_query& query) const; |
| | | |
| | | #endif |
| | | |
| | | // Print subtree using a writer object |
| | | void print(xml_writer& writer, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const; |
| | | |
| | | #ifndef PUGIXML_NO_STL |
| | | // Print subtree to stream |
| | | void print(std::basic_ostream<char, std::char_traits<char> >& os, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const; |
| | | void print(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& os, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, unsigned int depth = 0) const; |
| | | #endif |
| | | |
| | | // Child nodes iterators |
| | | typedef xml_node_iterator iterator; |
| | | |
| | | iterator begin() const; |
| | | iterator end() const; |
| | | |
| | | // Attribute iterators |
| | | typedef xml_attribute_iterator attribute_iterator; |
| | | |
| | | attribute_iterator attributes_begin() const; |
| | | attribute_iterator attributes_end() const; |
| | | |
| | | // Range-based for support |
| | | xml_object_range<xml_node_iterator> children() const; |
| | | xml_object_range<xml_attribute_iterator> attributes() const; |
| | | |
| | | // Range-based for support for all children with the specified name |
| | | // Note: name pointer must have a longer lifetime than the returned object; be careful with passing temporaries! |
| | | xml_object_range<xml_named_node_iterator> children(const char_t* name) const; |
| | | |
| | | // Get node offset in parsed file/string (in char_t units) for debugging purposes |
| | | ptrdiff_t offset_debug() const; |
| | | |
| | | // Get hash value (unique for handles to the same object) |
| | | size_t hash_value() const; |
| | | |
| | | // Get internal pointer |
| | | xml_node_struct* internal_object() const; |
| | | }; |
| | | |
| | | #ifdef __BORLANDC__ |
| | | // Borland C++ workaround |
| | | bool PUGIXML_FUNCTION operator&&(const xml_node& lhs, bool rhs); |
| | | bool PUGIXML_FUNCTION operator||(const xml_node& lhs, bool rhs); |
| | | #endif |
| | | |
| | | // A helper for working with text inside PCDATA nodes |
| | | class PUGIXML_CLASS xml_text |
| | | { |
| | | friend class xml_node; |
| | | |
| | | xml_node_struct* _root; |
| | | |
| | | typedef void (*unspecified_bool_type)(xml_text***); |
| | | |
| | | explicit xml_text(xml_node_struct* root); |
| | | |
| | | xml_node_struct* _data_new(); |
| | | xml_node_struct* _data() const; |
| | | |
| | | public: |
| | | // Default constructor. Constructs an empty object. |
| | | xml_text(); |
| | | |
| | | // Safe bool conversion operator |
| | | operator unspecified_bool_type() const; |
| | | |
| | | // Borland C++ workaround |
| | | bool operator!() const; |
| | | |
| | | // Check if text object is empty |
| | | bool empty() const; |
| | | |
| | | // Get text, or "" if object is empty |
| | | const char_t* get() const; |
| | | |
| | | // Get text, or the default value if object is empty |
| | | const char_t* as_string(const char_t* def = PUGIXML_TEXT("")) const; |
| | | |
| | | // Get text as a number, or the default value if conversion did not succeed or object is empty |
| | | int as_int(int def = 0) const; |
| | | unsigned int as_uint(unsigned int def = 0) const; |
| | | double as_double(double def = 0) const; |
| | | float as_float(float def = 0) const; |
| | | |
| | | #ifdef PUGIXML_HAS_LONG_LONG |
| | | long long as_llong(long long def = 0) const; |
| | | unsigned long long as_ullong(unsigned long long def = 0) const; |
| | | #endif |
| | | |
| | | // Get text as bool (returns true if first character is in '1tTyY' set), or the default value if object is empty |
| | | bool as_bool(bool def = false) const; |
| | | |
| | | // Set text (returns false if object is empty or there is not enough memory) |
| | | bool set(const char_t* rhs); |
| | | bool set(const char_t* rhs, size_t size); |
| | | |
| | | // Set text with type conversion (numbers are converted to strings, boolean is converted to "true"/"false") |
| | | bool set(int rhs); |
| | | bool set(unsigned int rhs); |
| | | bool set(long rhs); |
| | | bool set(unsigned long rhs); |
| | | bool set(double rhs); |
| | | bool set(double rhs, int precision); |
| | | bool set(float rhs); |
| | | bool set(float rhs, int precision); |
| | | bool set(bool rhs); |
| | | |
| | | #ifdef PUGIXML_HAS_LONG_LONG |
| | | bool set(long long rhs); |
| | | bool set(unsigned long long rhs); |
| | | #endif |
| | | |
| | | // Set text (equivalent to set without error checking) |
| | | xml_text& operator=(const char_t* rhs); |
| | | xml_text& operator=(int rhs); |
| | | xml_text& operator=(unsigned int rhs); |
| | | xml_text& operator=(long rhs); |
| | | xml_text& operator=(unsigned long rhs); |
| | | xml_text& operator=(double rhs); |
| | | xml_text& operator=(float rhs); |
| | | xml_text& operator=(bool rhs); |
| | | |
| | | #ifdef PUGIXML_HAS_LONG_LONG |
| | | xml_text& operator=(long long rhs); |
| | | xml_text& operator=(unsigned long long rhs); |
| | | #endif |
| | | |
| | | // Get the data node (node_pcdata or node_cdata) for this object |
| | | xml_node data() const; |
| | | }; |
| | | |
| | | #ifdef __BORLANDC__ |
| | | // Borland C++ workaround |
| | | bool PUGIXML_FUNCTION operator&&(const xml_text& lhs, bool rhs); |
| | | bool PUGIXML_FUNCTION operator||(const xml_text& lhs, bool rhs); |
| | | #endif |
| | | |
| | | // Child node iterator (a bidirectional iterator over a collection of xml_node) |
| | | class PUGIXML_CLASS xml_node_iterator |
| | | { |
| | | friend class xml_node; |
| | | |
| | | private: |
| | | mutable xml_node _wrap; |
| | | xml_node _parent; |
| | | |
| | | xml_node_iterator(xml_node_struct* ref, xml_node_struct* parent); |
| | | |
| | | public: |
| | | // Iterator traits |
| | | typedef ptrdiff_t difference_type; |
| | | typedef xml_node value_type; |
| | | typedef xml_node* pointer; |
| | | typedef xml_node& reference; |
| | | |
| | | #ifndef PUGIXML_NO_STL |
| | | typedef std::bidirectional_iterator_tag iterator_category; |
| | | #endif |
| | | |
| | | // Default constructor |
| | | xml_node_iterator(); |
| | | |
| | | // Construct an iterator which points to the specified node |
| | | xml_node_iterator(const xml_node& node); |
| | | |
| | | // Iterator operators |
| | | bool operator==(const xml_node_iterator& rhs) const; |
| | | bool operator!=(const xml_node_iterator& rhs) const; |
| | | |
| | | xml_node& operator*() const; |
| | | xml_node* operator->() const; |
| | | |
| | | xml_node_iterator& operator++(); |
| | | xml_node_iterator operator++(int); |
| | | |
| | | xml_node_iterator& operator--(); |
| | | xml_node_iterator operator--(int); |
| | | }; |
| | | |
| | | // Attribute iterator (a bidirectional iterator over a collection of xml_attribute) |
| | | class PUGIXML_CLASS xml_attribute_iterator |
| | | { |
| | | friend class xml_node; |
| | | |
| | | private: |
| | | mutable xml_attribute _wrap; |
| | | xml_node _parent; |
| | | |
| | | xml_attribute_iterator(xml_attribute_struct* ref, xml_node_struct* parent); |
| | | |
| | | public: |
| | | // Iterator traits |
| | | typedef ptrdiff_t difference_type; |
| | | typedef xml_attribute value_type; |
| | | typedef xml_attribute* pointer; |
| | | typedef xml_attribute& reference; |
| | | |
| | | #ifndef PUGIXML_NO_STL |
| | | typedef std::bidirectional_iterator_tag iterator_category; |
| | | #endif |
| | | |
| | | // Default constructor |
| | | xml_attribute_iterator(); |
| | | |
| | | // Construct an iterator which points to the specified attribute |
| | | xml_attribute_iterator(const xml_attribute& attr, const xml_node& parent); |
| | | |
| | | // Iterator operators |
| | | bool operator==(const xml_attribute_iterator& rhs) const; |
| | | bool operator!=(const xml_attribute_iterator& rhs) const; |
| | | |
| | | xml_attribute& operator*() const; |
| | | xml_attribute* operator->() const; |
| | | |
| | | xml_attribute_iterator& operator++(); |
| | | xml_attribute_iterator operator++(int); |
| | | |
| | | xml_attribute_iterator& operator--(); |
| | | xml_attribute_iterator operator--(int); |
| | | }; |
| | | |
| | | // Named node range helper |
| | | class PUGIXML_CLASS xml_named_node_iterator |
| | | { |
| | | friend class xml_node; |
| | | |
| | | public: |
| | | // Iterator traits |
| | | typedef ptrdiff_t difference_type; |
| | | typedef xml_node value_type; |
| | | typedef xml_node* pointer; |
| | | typedef xml_node& reference; |
| | | |
| | | #ifndef PUGIXML_NO_STL |
| | | typedef std::bidirectional_iterator_tag iterator_category; |
| | | #endif |
| | | |
| | | // Default constructor |
| | | xml_named_node_iterator(); |
| | | |
| | | // Construct an iterator which points to the specified node |
| | | // Note: name pointer is stored in the iterator and must have a longer lifetime than iterator itself |
| | | xml_named_node_iterator(const xml_node& node, const char_t* name); |
| | | |
| | | // Iterator operators |
| | | bool operator==(const xml_named_node_iterator& rhs) const; |
| | | bool operator!=(const xml_named_node_iterator& rhs) const; |
| | | |
| | | xml_node& operator*() const; |
| | | xml_node* operator->() const; |
| | | |
| | | xml_named_node_iterator& operator++(); |
| | | xml_named_node_iterator operator++(int); |
| | | |
| | | xml_named_node_iterator& operator--(); |
| | | xml_named_node_iterator operator--(int); |
| | | |
| | | private: |
| | | mutable xml_node _wrap; |
| | | xml_node _parent; |
| | | const char_t* _name; |
| | | |
| | | xml_named_node_iterator(xml_node_struct* ref, xml_node_struct* parent, const char_t* name); |
| | | }; |
| | | |
| | | // Abstract tree walker class (see xml_node::traverse) |
| | | class PUGIXML_CLASS xml_tree_walker |
| | | { |
| | | friend class xml_node; |
| | | |
| | | private: |
| | | int _depth; |
| | | |
| | | protected: |
| | | // Get current traversal depth |
| | | int depth() const; |
| | | |
| | | public: |
| | | xml_tree_walker(); |
| | | virtual ~xml_tree_walker(); |
| | | |
| | | // Callback that is called when traversal begins |
| | | virtual bool begin(xml_node& node); |
| | | |
| | | // Callback that is called for each node traversed |
| | | virtual bool for_each(xml_node& node) = 0; |
| | | |
| | | // Callback that is called when traversal ends |
| | | virtual bool end(xml_node& node); |
| | | }; |
| | | |
| | | // Parsing status, returned as part of xml_parse_result object |
| | | enum xml_parse_status |
| | | { |
| | | status_ok = 0, // No error |
| | | |
| | | status_file_not_found, // File was not found during load_file() |
| | | status_io_error, // Error reading from file/stream |
| | | status_out_of_memory, // Could not allocate memory |
| | | status_internal_error, // Internal error occurred |
| | | |
| | | status_unrecognized_tag, // Parser could not determine tag type |
| | | |
| | | status_bad_pi, // Parsing error occurred while parsing document declaration/processing instruction |
| | | status_bad_comment, // Parsing error occurred while parsing comment |
| | | status_bad_cdata, // Parsing error occurred while parsing CDATA section |
| | | status_bad_doctype, // Parsing error occurred while parsing document type declaration |
| | | status_bad_pcdata, // Parsing error occurred while parsing PCDATA section |
| | | status_bad_start_element, // Parsing error occurred while parsing start element tag |
| | | status_bad_attribute, // Parsing error occurred while parsing element attribute |
| | | status_bad_end_element, // Parsing error occurred while parsing end element tag |
| | | status_end_element_mismatch,// There was a mismatch of start-end tags (closing tag had incorrect name, some tag was not closed or there was an excessive closing tag) |
| | | |
| | | status_append_invalid_root, // Unable to append nodes since root type is not node_element or node_document (exclusive to xml_node::append_buffer) |
| | | |
| | | status_no_document_element // Parsing resulted in a document without element nodes |
| | | }; |
| | | |
| | | // Parsing result |
| | | struct PUGIXML_CLASS xml_parse_result |
| | | { |
| | | // Parsing status (see xml_parse_status) |
| | | xml_parse_status status; |
| | | |
| | | // Last parsed offset (in char_t units from start of input data) |
| | | ptrdiff_t offset; |
| | | |
| | | // Source document encoding |
| | | xml_encoding encoding; |
| | | |
| | | // Default constructor, initializes object to failed state |
| | | xml_parse_result(); |
| | | |
| | | // Cast to bool operator |
| | | operator bool() const; |
| | | |
| | | // Get error description |
| | | const char* description() const; |
| | | }; |
| | | |
| | | // Document class (DOM tree root) |
| | | class PUGIXML_CLASS xml_document: public xml_node |
| | | { |
| | | private: |
| | | char_t* _buffer; |
| | | |
| | | char _memory[192]; |
| | | |
| | | // Non-copyable semantics |
| | | xml_document(const xml_document&); |
| | | xml_document& operator=(const xml_document&); |
| | | |
| | | void _create(); |
| | | void _destroy(); |
| | | void _move(xml_document& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT; |
| | | |
| | | public: |
| | | // Default constructor, makes empty document |
| | | xml_document(); |
| | | |
| | | // Destructor, invalidates all node/attribute handles to this document |
| | | ~xml_document(); |
| | | |
| | | #ifdef PUGIXML_HAS_MOVE |
| | | // Move semantics support |
| | | xml_document(xml_document&& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT; |
| | | xml_document& operator=(xml_document&& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT; |
| | | #endif |
| | | |
| | | // Removes all nodes, leaving the empty document |
| | | void reset(); |
| | | |
| | | // Removes all nodes, then copies the entire contents of the specified document |
| | | void reset(const xml_document& proto); |
| | | |
| | | #ifndef PUGIXML_NO_STL |
| | | // Load document from stream. |
| | | xml_parse_result load(std::basic_istream<char, std::char_traits<char> >& stream, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); |
| | | xml_parse_result load(std::basic_istream<wchar_t, std::char_traits<wchar_t> >& stream, unsigned int options = parse_default); |
| | | #endif |
| | | |
| | | // (deprecated: use load_string instead) Load document from zero-terminated string. No encoding conversions are applied. |
| | | PUGIXML_DEPRECATED xml_parse_result load(const char_t* contents, unsigned int options = parse_default); |
| | | |
| | | // Load document from zero-terminated string. No encoding conversions are applied. |
| | | xml_parse_result load_string(const char_t* contents, unsigned int options = parse_default); |
| | | |
| | | // Load document from file |
| | | xml_parse_result load_file(const char* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); |
| | | xml_parse_result load_file(const wchar_t* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); |
| | | |
| | | // Load document from buffer. Copies/converts the buffer, so it may be deleted or changed after the function returns. |
| | | xml_parse_result load_buffer(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); |
| | | |
| | | // Load document from buffer, using the buffer for in-place parsing (the buffer is modified and used for storage of document data). |
| | | // You should ensure that buffer data will persist throughout the document's lifetime, and free the buffer memory manually once document is destroyed. |
| | | xml_parse_result load_buffer_inplace(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); |
| | | |
| | | // Load document from buffer, using the buffer for in-place parsing (the buffer is modified and used for storage of document data). |
| | | // You should allocate the buffer with pugixml allocation function; document will free the buffer when it is no longer needed (you can't use it anymore). |
| | | xml_parse_result load_buffer_inplace_own(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); |
| | | |
| | | // Save XML document to writer (semantics is slightly different from xml_node::print, see documentation for details). |
| | | void save(xml_writer& writer, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; |
| | | |
| | | #ifndef PUGIXML_NO_STL |
| | | // Save XML document to stream (semantics is slightly different from xml_node::print, see documentation for details). |
| | | void save(std::basic_ostream<char, std::char_traits<char> >& stream, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; |
| | | void save(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& stream, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default) const; |
| | | #endif |
| | | |
| | | // Save XML to file |
| | | bool save_file(const char* path, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; |
| | | bool save_file(const wchar_t* path, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; |
| | | |
| | | // Get document element |
| | | xml_node document_element() const; |
| | | }; |
| | | |
| | | #ifndef PUGIXML_NO_XPATH |
| | | // XPath query return type |
| | | enum xpath_value_type |
| | | { |
| | | xpath_type_none, // Unknown type (query failed to compile) |
| | | xpath_type_node_set, // Node set (xpath_node_set) |
| | | xpath_type_number, // Number |
| | | xpath_type_string, // String |
| | | xpath_type_boolean // Boolean |
| | | }; |
| | | |
| | | // XPath parsing result |
| | | struct PUGIXML_CLASS xpath_parse_result |
| | | { |
| | | // Error message (0 if no error) |
| | | const char* error; |
| | | |
| | | // Last parsed offset (in char_t units from string start) |
| | | ptrdiff_t offset; |
| | | |
| | | // Default constructor, initializes object to failed state |
| | | xpath_parse_result(); |
| | | |
| | | // Cast to bool operator |
| | | operator bool() const; |
| | | |
| | | // Get error description |
| | | const char* description() const; |
| | | }; |
| | | |
| | | // A single XPath variable |
| | | class PUGIXML_CLASS xpath_variable |
| | | { |
| | | friend class xpath_variable_set; |
| | | |
| | | protected: |
| | | xpath_value_type _type; |
| | | xpath_variable* _next; |
| | | |
| | | xpath_variable(xpath_value_type type); |
| | | |
| | | // Non-copyable semantics |
| | | xpath_variable(const xpath_variable&); |
| | | xpath_variable& operator=(const xpath_variable&); |
| | | |
| | | public: |
| | | // Get variable name |
| | | const char_t* name() const; |
| | | |
| | | // Get variable type |
| | | xpath_value_type type() const; |
| | | |
| | | // Get variable value; no type conversion is performed, default value (false, NaN, empty string, empty node set) is returned on type mismatch error |
| | | bool get_boolean() const; |
| | | double get_number() const; |
| | | const char_t* get_string() const; |
| | | const xpath_node_set& get_node_set() const; |
| | | |
| | | // Set variable value; no type conversion is performed, false is returned on type mismatch error |
| | | bool set(bool value); |
| | | bool set(double value); |
| | | bool set(const char_t* value); |
| | | bool set(const xpath_node_set& value); |
| | | }; |
| | | |
| | | // A set of XPath variables |
| | | class PUGIXML_CLASS xpath_variable_set |
| | | { |
| | | private: |
| | | xpath_variable* _data[64]; |
| | | |
| | | void _assign(const xpath_variable_set& rhs); |
| | | void _swap(xpath_variable_set& rhs); |
| | | |
| | | xpath_variable* _find(const char_t* name) const; |
| | | |
| | | static bool _clone(xpath_variable* var, xpath_variable** out_result); |
| | | static void _destroy(xpath_variable* var); |
| | | |
| | | public: |
| | | // Default constructor/destructor |
| | | xpath_variable_set(); |
| | | ~xpath_variable_set(); |
| | | |
| | | // Copy constructor/assignment operator |
| | | xpath_variable_set(const xpath_variable_set& rhs); |
| | | xpath_variable_set& operator=(const xpath_variable_set& rhs); |
| | | |
| | | #ifdef PUGIXML_HAS_MOVE |
| | | // Move semantics support |
| | | xpath_variable_set(xpath_variable_set&& rhs) PUGIXML_NOEXCEPT; |
| | | xpath_variable_set& operator=(xpath_variable_set&& rhs) PUGIXML_NOEXCEPT; |
| | | #endif |
| | | |
| | | // Add a new variable or get the existing one, if the types match |
| | | xpath_variable* add(const char_t* name, xpath_value_type type); |
| | | |
| | | // Set value of an existing variable; no type conversion is performed, false is returned if there is no such variable or if types mismatch |
| | | bool set(const char_t* name, bool value); |
| | | bool set(const char_t* name, double value); |
| | | bool set(const char_t* name, const char_t* value); |
| | | bool set(const char_t* name, const xpath_node_set& value); |
| | | |
| | | // Get existing variable by name |
| | | xpath_variable* get(const char_t* name); |
| | | const xpath_variable* get(const char_t* name) const; |
| | | }; |
| | | |
| | | // A compiled XPath query object |
| | | class PUGIXML_CLASS xpath_query |
| | | { |
| | | private: |
| | | void* _impl; |
| | | xpath_parse_result _result; |
| | | |
| | | typedef void (*unspecified_bool_type)(xpath_query***); |
| | | |
| | | // Non-copyable semantics |
| | | xpath_query(const xpath_query&); |
| | | xpath_query& operator=(const xpath_query&); |
| | | |
| | | public: |
| | | // Construct a compiled object from XPath expression. |
| | | // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on compilation errors. |
| | | explicit xpath_query(const char_t* query, xpath_variable_set* variables = PUGIXML_NULL); |
| | | |
| | | // Constructor |
| | | xpath_query(); |
| | | |
| | | // Destructor |
| | | ~xpath_query(); |
| | | |
| | | #ifdef PUGIXML_HAS_MOVE |
| | | // Move semantics support |
| | | xpath_query(xpath_query&& rhs) PUGIXML_NOEXCEPT; |
| | | xpath_query& operator=(xpath_query&& rhs) PUGIXML_NOEXCEPT; |
| | | #endif |
| | | |
| | | // Get query expression return type |
| | | xpath_value_type return_type() const; |
| | | |
| | | // Evaluate expression as boolean value in the specified context; performs type conversion if necessary. |
| | | // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. |
| | | bool evaluate_boolean(const xpath_node& n) const; |
| | | |
| | | // Evaluate expression as double value in the specified context; performs type conversion if necessary. |
| | | // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. |
| | | double evaluate_number(const xpath_node& n) const; |
| | | |
| | | #ifndef PUGIXML_NO_STL |
| | | // Evaluate expression as string value in the specified context; performs type conversion if necessary. |
| | | // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. |
| | | string_t evaluate_string(const xpath_node& n) const; |
| | | #endif |
| | | |
| | | // Evaluate expression as string value in the specified context; performs type conversion if necessary. |
| | | // At most capacity characters are written to the destination buffer, full result size is returned (includes terminating zero). |
| | | // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. |
| | | // If PUGIXML_NO_EXCEPTIONS is defined, returns empty set instead. |
| | | size_t evaluate_string(char_t* buffer, size_t capacity, const xpath_node& n) const; |
| | | |
| | | // Evaluate expression as node set in the specified context. |
| | | // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on type mismatch and std::bad_alloc on out of memory errors. |
| | | // If PUGIXML_NO_EXCEPTIONS is defined, returns empty node set instead. |
| | | xpath_node_set evaluate_node_set(const xpath_node& n) const; |
| | | |
| | | // Evaluate expression as node set in the specified context. |
| | | // Return first node in document order, or empty node if node set is empty. |
| | | // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on type mismatch and std::bad_alloc on out of memory errors. |
| | | // If PUGIXML_NO_EXCEPTIONS is defined, returns empty node instead. |
| | | xpath_node evaluate_node(const xpath_node& n) const; |
| | | |
| | | // Get parsing result (used to get compilation errors in PUGIXML_NO_EXCEPTIONS mode) |
| | | const xpath_parse_result& result() const; |
| | | |
| | | // Safe bool conversion operator |
| | | operator unspecified_bool_type() const; |
| | | |
| | | // Borland C++ workaround |
| | | bool operator!() const; |
| | | }; |
| | | |
| | | #ifndef PUGIXML_NO_EXCEPTIONS |
| | | #if defined(_MSC_VER) |
| | | // C4275 can be ignored in Visual C++ if you are deriving |
| | | // from a type in the Standard C++ Library |
| | | #pragma warning(push) |
| | | #pragma warning(disable: 4275) |
| | | #endif |
| | | // XPath exception class |
| | | class PUGIXML_CLASS xpath_exception: public std::exception |
| | | { |
| | | private: |
| | | xpath_parse_result _result; |
| | | |
| | | public: |
| | | // Construct exception from parse result |
| | | explicit xpath_exception(const xpath_parse_result& result); |
| | | |
| | | // Get error message |
| | | virtual const char* what() const throw() PUGIXML_OVERRIDE; |
| | | |
| | | // Get parse result |
| | | const xpath_parse_result& result() const; |
| | | }; |
| | | #if defined(_MSC_VER) |
| | | #pragma warning(pop) |
| | | #endif |
| | | #endif |
| | | |
| | | // XPath node class (either xml_node or xml_attribute) |
| | | class PUGIXML_CLASS xpath_node |
| | | { |
| | | private: |
| | | xml_node _node; |
| | | xml_attribute _attribute; |
| | | |
| | | typedef void (*unspecified_bool_type)(xpath_node***); |
| | | |
| | | public: |
| | | // Default constructor; constructs empty XPath node |
| | | xpath_node(); |
| | | |
| | | // Construct XPath node from XML node/attribute |
| | | xpath_node(const xml_node& node); |
| | | xpath_node(const xml_attribute& attribute, const xml_node& parent); |
| | | |
| | | // Get node/attribute, if any |
| | | xml_node node() const; |
| | | xml_attribute attribute() const; |
| | | |
| | | // Get parent of contained node/attribute |
| | | xml_node parent() const; |
| | | |
| | | // Safe bool conversion operator |
| | | operator unspecified_bool_type() const; |
| | | |
| | | // Borland C++ workaround |
| | | bool operator!() const; |
| | | |
| | | // Comparison operators |
| | | bool operator==(const xpath_node& n) const; |
| | | bool operator!=(const xpath_node& n) const; |
| | | }; |
| | | |
| | | #ifdef __BORLANDC__ |
| | | // Borland C++ workaround |
| | | bool PUGIXML_FUNCTION operator&&(const xpath_node& lhs, bool rhs); |
| | | bool PUGIXML_FUNCTION operator||(const xpath_node& lhs, bool rhs); |
| | | #endif |
| | | |
| | | // A fixed-size collection of XPath nodes |
| | | class PUGIXML_CLASS xpath_node_set |
| | | { |
| | | public: |
| | | // Collection type |
| | | enum type_t |
| | | { |
| | | type_unsorted, // Not ordered |
| | | type_sorted, // Sorted by document order (ascending) |
| | | type_sorted_reverse // Sorted by document order (descending) |
| | | }; |
| | | |
| | | // Constant iterator type |
| | | typedef const xpath_node* const_iterator; |
| | | |
| | | // We define non-constant iterator to be the same as constant iterator so that various generic algorithms (i.e. boost foreach) work |
| | | typedef const xpath_node* iterator; |
| | | |
| | | // Default constructor. Constructs empty set. |
| | | xpath_node_set(); |
| | | |
| | | // Constructs a set from iterator range; data is not checked for duplicates and is not sorted according to provided type, so be careful |
| | | xpath_node_set(const_iterator begin, const_iterator end, type_t type = type_unsorted); |
| | | |
| | | // Destructor |
| | | ~xpath_node_set(); |
| | | |
| | | // Copy constructor/assignment operator |
| | | xpath_node_set(const xpath_node_set& ns); |
| | | xpath_node_set& operator=(const xpath_node_set& ns); |
| | | |
| | | #ifdef PUGIXML_HAS_MOVE |
| | | // Move semantics support |
| | | xpath_node_set(xpath_node_set&& rhs) PUGIXML_NOEXCEPT; |
| | | xpath_node_set& operator=(xpath_node_set&& rhs) PUGIXML_NOEXCEPT; |
| | | #endif |
| | | |
| | | // Get collection type |
| | | type_t type() const; |
| | | |
| | | // Get collection size |
| | | size_t size() const; |
| | | |
| | | // Indexing operator |
| | | const xpath_node& operator[](size_t index) const; |
| | | |
| | | // Collection iterators |
| | | const_iterator begin() const; |
| | | const_iterator end() const; |
| | | |
| | | // Sort the collection in ascending/descending order by document order |
| | | void sort(bool reverse = false); |
| | | |
| | | // Get first node in the collection by document order |
| | | xpath_node first() const; |
| | | |
| | | // Check if collection is empty |
| | | bool empty() const; |
| | | |
| | | private: |
| | | type_t _type; |
| | | |
| | | xpath_node _storage[1]; |
| | | |
| | | xpath_node* _begin; |
| | | xpath_node* _end; |
| | | |
| | | void _assign(const_iterator begin, const_iterator end, type_t type); |
| | | void _move(xpath_node_set& rhs) PUGIXML_NOEXCEPT; |
| | | }; |
| | | #endif |
| | | |
| | | #ifndef PUGIXML_NO_STL |
| | | // Convert wide string to UTF8 |
| | | std::basic_string<char, std::char_traits<char>, std::allocator<char> > PUGIXML_FUNCTION as_utf8(const wchar_t* str); |
| | | std::basic_string<char, std::char_traits<char>, std::allocator<char> > PUGIXML_FUNCTION as_utf8(const std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >& str); |
| | | |
| | | // Convert UTF8 to wide string |
| | | std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > PUGIXML_FUNCTION as_wide(const char* str); |
| | | std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > PUGIXML_FUNCTION as_wide(const std::basic_string<char, std::char_traits<char>, std::allocator<char> >& str); |
| | | #endif |
| | | |
| | | // Memory allocation function interface; returns pointer to allocated memory or NULL on failure |
| | | typedef void* (*allocation_function)(size_t size); |
| | | |
| | | // Memory deallocation function interface |
| | | typedef void (*deallocation_function)(void* ptr); |
| | | |
| | | // Override default memory management functions. All subsequent allocations/deallocations will be performed via supplied functions. |
| | | void PUGIXML_FUNCTION set_memory_management_functions(allocation_function allocate, deallocation_function deallocate); |
| | | |
| | | // Get current memory management functions |
| | | allocation_function PUGIXML_FUNCTION get_memory_allocation_function(); |
| | | deallocation_function PUGIXML_FUNCTION get_memory_deallocation_function(); |
| | | } |
| | | |
| | | #if !defined(PUGIXML_NO_STL) && (defined(_MSC_VER) || defined(__ICC)) |
| | | namespace std |
| | | { |
| | | // Workarounds for (non-standard) iterator category detection for older versions (MSVC7/IC8 and earlier) |
| | | std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_node_iterator&); |
| | | std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_attribute_iterator&); |
| | | std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_named_node_iterator&); |
| | | } |
| | | #endif |
| | | |
| | | #if !defined(PUGIXML_NO_STL) && defined(__SUNPRO_CC) |
| | | namespace std |
| | | { |
| | | // Workarounds for (non-standard) iterator category detection |
| | | std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_node_iterator&); |
| | | std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_attribute_iterator&); |
| | | std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_named_node_iterator&); |
| | | } |
| | | #endif |
| | | |
| | | #endif |
| | | |
| | | // Make sure implementation is included in header-only mode |
| | | // Use macro expansion in #include to work around QMake (QTBUG-11923) |
| | | #if defined(PUGIXML_HEADER_ONLY) && !defined(PUGIXML_SOURCE) |
| | | # define PUGIXML_SOURCE "pugixml.cpp" |
| | | # include PUGIXML_SOURCE |
| | | #endif |
| | | |
| | | /** |
| | | * Copyright (c) 2006-2023 Arseny Kapoulkine |
| | | * |
| | | * Permission is hereby granted, free of charge, to any person |
| | | * obtaining a copy of this software and associated documentation |
| | | * files (the "Software"), to deal in the Software without |
| | | * restriction, including without limitation the rights to use, |
| | | * copy, modify, merge, publish, distribute, sublicense, and/or sell |
| | | * copies of the Software, and to permit persons to whom the |
| | | * Software is furnished to do so, subject to the following |
| | | * conditions: |
| | | * |
| | | * The above copyright notice and this permission notice shall be |
| | | * included in all copies or substantial portions of the Software. |
| | | * |
| | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| | | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
| | | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| | | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
| | | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
| | | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| | | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| | | * OTHER DEALINGS IN THE SOFTWARE. |
| | | */ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // IOMonitoringDlg.cpp: å®ç°æä»¶ |
| | | // |
| | | |
| | | #include "stdafx.h" |
| | | #include "BoounionPLC.h" |
| | | #include "afxdialogex.h" |
| | | #include "IOMonitoringDlg.h" |
| | | #include "ToolUnits.h" |
| | | |
| | | #define TIMER_INIT 1 |
| | | #define TIMER_READ_PLC_DATA 2 |
| | | #define TIMER_READ_UPDATE 3 |
| | | |
| | | #define LABEL_ID_BEGIN 2000 |
| | | #define ADDR_WND _T("ADDR_WND") |
| | | |
| | | #define ID_MSG_IO_CLICK WM_USER + 101 |
| | | |
| | | // CIOMonitoringDlg å¯¹è¯æ¡ |
| | | |
| | | IMPLEMENT_DYNAMIC(CIOMonitoringDlg, CDialogEx) |
| | | |
| | | CIOMonitoringDlg::CIOMonitoringDlg(CWnd* pParent /*=nullptr*/) |
| | | : CDialogEx(IDD_DIALOG_IO_MONITORING, pParent) |
| | | { |
| | | m_nCurrentPage = 1; |
| | | m_nTotalPages = 1; |
| | | m_nRowsPerPage = 16; |
| | | m_nCols = 6; |
| | | } |
| | | |
| | | CIOMonitoringDlg::~CIOMonitoringDlg() |
| | | { |
| | | for (auto& pair : m_mapFonts) { |
| | | if (pair.second) { |
| | | pair.second->DeleteObject(); |
| | | delete pair.second; |
| | | } |
| | | } |
| | | m_mapFonts.clear(); |
| | | |
| | | ClearDynamicControls(); |
| | | } |
| | | |
| | | void CIOMonitoringDlg::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | DDX_Control(pDX, IDC_STATIC_PAGE_NUMBER, m_staticPageNum); |
| | | } |
| | | |
| | | void CIOMonitoringDlg::SetIOManager(const std::string& machineName) |
| | | { |
| | | // å è½½æ°æ® |
| | | IOManager manager; |
| | | manager.LoadFromFile(machineName); |
| | | manager.GetMachineData(m_displayData); |
| | | |
| | | // 计ç®é¡µæ° |
| | | m_nCurrentPage = 1; |
| | | m_nTotalPages = ((int)m_displayData.size() + m_nRowsPerPage - 1) / m_nRowsPerPage; |
| | | } |
| | | |
| | | void CIOMonitoringDlg::SetPLC(CPLC* pPLC) |
| | | { |
| | | ASSERT(pPLC); |
| | | m_pPLC = pPLC; |
| | | } |
| | | |
| | | CFont* CIOMonitoringDlg::GetOrCreateFont(int nFontSize) |
| | | { |
| | | auto it = m_mapFonts.find(nFontSize); |
| | | if (it != m_mapFonts.end()) { |
| | | return it->second; |
| | | } |
| | | |
| | | CFont* font = new CFont(); |
| | | LOGFONT logFont = { 0 }; |
| | | _tcscpy_s(logFont.lfFaceName, _T("Segoe UI")); |
| | | logFont.lfHeight = -nFontSize; |
| | | logFont.lfQuality = CLEARTYPE_QUALITY; |
| | | font->CreateFontIndirect(&logFont); |
| | | m_mapFonts[nFontSize] = font; |
| | | |
| | | return font; |
| | | } |
| | | |
| | | void CIOMonitoringDlg::SetDefaultFont() |
| | | { |
| | | CFont* defaultFont = GetOrCreateFont(12); |
| | | |
| | | // éåæææ§ä»¶ï¼åºç¨é»è®¤åä½ |
| | | CWnd* pWnd = GetWindow(GW_CHILD); |
| | | while (pWnd) { |
| | | pWnd->SetFont(defaultFont, TRUE); |
| | | pWnd = pWnd->GetNextWindow(); |
| | | } |
| | | } |
| | | |
| | | void CIOMonitoringDlg::AdjustControls(float dScaleX, float dScaleY) |
| | | { |
| | | CWnd* pWnd = GetWindow(GW_CHILD); |
| | | while (pWnd) { |
| | | int nCtrlID = pWnd->GetDlgCtrlID(); |
| | | if (nCtrlID != -1 && m_mapCtrlLayouts.find(nCtrlID) != m_mapCtrlLayouts.end()) { |
| | | CRect originalRect = m_mapCtrlLayouts[nCtrlID]; |
| | | CRect newRect( |
| | | static_cast<int>(originalRect.left * dScaleX), |
| | | static_cast<int>(originalRect.top * dScaleY), |
| | | static_cast<int>(originalRect.right * dScaleX), |
| | | static_cast<int>(originalRect.bottom * dScaleY)); |
| | | |
| | | pWnd->MoveWindow(&newRect); |
| | | AdjustControlFont(pWnd, newRect.Width(), newRect.Height()); |
| | | } |
| | | pWnd = pWnd->GetNextWindow(); |
| | | } |
| | | } |
| | | |
| | | void CIOMonitoringDlg::AdjustControlFont(CWnd* pWnd, int nWidth, int nHeight) |
| | | { |
| | | TCHAR szClassName[256]; |
| | | GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName)); |
| | | |
| | | // æ ¹æ®æ§ä»¶é«åº¦å¨æè°æ´åä½å¤§å° |
| | | int fontSize = nHeight / 2; |
| | | if (fontSize < 8) fontSize = 8; |
| | | if (fontSize < 24) fontSize = 24; |
| | | |
| | | // è·åæå建åä½ |
| | | CFont* pFont = GetOrCreateFont(fontSize); |
| | | |
| | | pWnd->SetFont(pFont); |
| | | pWnd->Invalidate(); // å·æ°æ§ä»¶æ¾ç¤º |
| | | } |
| | | |
| | | void CIOMonitoringDlg::UpdatePageInfo() |
| | | { |
| | | // æ ¼å¼å页ç ä¿¡æ¯ä¸º "å½å页/æ»é¡µæ°" |
| | | CString pageInfo; |
| | | pageInfo.Format(_T("%d/%d 页"), m_nCurrentPage, m_nTotalPages); |
| | | m_staticPageNum.SetWindowText(pageInfo); |
| | | } |
| | | |
| | | void CIOMonitoringDlg::CreateDynamicControls() |
| | | { |
| | | CRect rect; |
| | | GetClientRect(&rect); |
| | | |
| | | // è·åæé®çå¤§å° |
| | | CWnd* pPrevButton = GetDlgItem(IDC_BUTTON_PREV_PAGE); |
| | | CWnd* pNextButton = GetDlgItem(IDC_BUTTON_NEXT_PAGE); |
| | | |
| | | CRect prevButtonRect, nextButtonRect; |
| | | pPrevButton->GetWindowRect(&prevButtonRect); |
| | | pNextButton->GetWindowRect(&nextButtonRect); |
| | | |
| | | // è½¬æ¢æé®åæ å°å¯¹è¯æ¡çåæ ç³»ç» |
| | | ScreenToClient(&prevButtonRect); |
| | | ScreenToClient(&nextButtonRect); |
| | | |
| | | int buttonHeight = prevButtonRect.Height(); // æé®çé«åº¦ |
| | | int topMargin = int(rect.Height() * 0.05); // é¡¶é¨ä¿ç 5% çé«åº¦ |
| | | int bottomMargin = buttonHeight + topMargin; // åºé¨ä¿çæé®é«åº¦å é´è· |
| | | int sideMargin = topMargin; // å·¦å³é´è·ä¸é¡¶é¨é´è·ç¸å |
| | | int groupSpacing = 20; // 两ç»ä¹é´çé´è· |
| | | int verticalSpacing = 10; // åç´é´è· |
| | | |
| | | // æ¯è¡é«åº¦åå宽度 |
| | | int availableHeight = rect.Height() - topMargin - bottomMargin; |
| | | int rowHeight = (availableHeight / m_nRowsPerPage) - verticalSpacing; // æ§ä»¶é«åº¦å
å«é´è· |
| | | |
| | | int availableWidth = rect.Width() - 2 * sideMargin; // å¯ç¨å®½åº¦ï¼åå»å·¦å³é´è·ï¼ |
| | | int colWidthSmall = availableWidth / 14; // å°å®½åº¦åæ´å° |
| | | int colWidthLarge = availableWidth * 4 / 14; // å¤§å®½åº¦åæ¯ä¾ |
| | | int groupWidth = colWidthSmall * 2 + colWidthLarge; // æ¯ç»æ»å®½åº¦ |
| | | |
| | | UINT id = LABEL_ID_BEGIN; |
| | | for (int i = 0; i < m_nRowsPerPage; ++i) { |
| | | // æ¯ä¸è¡çèµ·å§ Y åæ |
| | | int y = topMargin + i * (rowHeight + verticalSpacing); |
| | | |
| | | // å建第 1 ç» (0, 1, 2) |
| | | int x = sideMargin; // ä»å·¦è¾¹è·å¼å§ |
| | | CreateStaticControl(++id, x, y, colWidthSmall, rowHeight, _T("OFF"), true, AlignCenter); |
| | | x += colWidthSmall; |
| | | CreateStaticControl(++id, x, y, colWidthSmall, rowHeight, _T("X1000"), false, AlignCenter); |
| | | x += colWidthSmall; |
| | | CreateStaticControl(++id, x, y, colWidthLarge, rowHeight, _T("æè¿°ææ¬"), false); |
| | | |
| | | // 第 2 ç»èµ·å§ä½ç½®ï¼å ä¸ç»é´è· |
| | | x += colWidthLarge + groupSpacing; |
| | | |
| | | // å建第 2 ç» (3, 4, 5) |
| | | id++; |
| | | CWnd* pBtn = CreateStaticControl(id, x, y, colWidthSmall, rowHeight, _T("OFF"), true, AlignCenter, [this, id, i, x, y]() { |
| | | // èªå®ä¹ç¹å»äºä»¶çé»è¾ |
| | | auto* pControl = static_cast<CBLLabel*>(m_staticControls[i * m_nCols + 3]); |
| | | CString currentText; |
| | | pControl->GetWindowText(currentText); |
| | | PostMessage(ID_MSG_IO_CLICK, id, currentText == _T("OFF") ? 1 : 0); |
| | | }); |
| | | x += colWidthSmall; |
| | | CWnd* pLabel = CreateStaticControl(++id, x, y, colWidthSmall, rowHeight, _T("Y1010"), false, AlignCenter); |
| | | x += colWidthSmall; |
| | | CreateStaticControl(++id, x, y, colWidthLarge, rowHeight, _T("æè¿°ææ¬"), false); |
| | | ::SetProp(pBtn->GetSafeHwnd(), ADDR_WND, pLabel); |
| | | } |
| | | } |
| | | |
| | | CWnd* CIOMonitoringDlg::CreateStaticControl(UINT id, int x, int y, int width, int height, const CString& text, bool hasBorder, TextAlign alignment, std::function<void()> clickCallback) |
| | | { |
| | | // åå»ºå¨ææ§ä»¶ |
| | | CBLLabel* pStatic = new CBLLabel(); |
| | | DWORD style = WS_CHILD | WS_VISIBLE | SS_CENTERIMAGE; // ç¡®ä¿åç´å±
ä¸ |
| | | if (!hasBorder) { |
| | | pStatic->DisableBorder(); |
| | | } |
| | | pStatic->Create(text, style, CRect(x, y, x + width, y + height), this, id); |
| | | |
| | | // è®¾ç½®ææ¬å¯¹é½æ¹å¼ |
| | | pStatic->SetAlignment(alignment); |
| | | |
| | | // è®¾ç½®å¨æåä½è°æ´ï¼å¹¶è®¾ç½®åä½å¤§å°ï¼å¨æåä½ä¼æ ¹æ®æ§ä»¶å¤§å°è°æ´ï¼ |
| | | int nSize = height / 3; |
| | | CFont* pFont = GetOrCreateFont(nSize); |
| | | pStatic->SetFont(pFont); |
| | | pStatic->SetFontSize(nSize); |
| | | pStatic->SetDynamicFont(TRUE); |
| | | |
| | | // 设置åè° |
| | | //UserManager& userManager = UserManager::getInstance(); |
| | | //UserRole enRole = userManager.getCurrentUserRole(); |
| | | if (clickCallback/* && (enRole == UserRole::SuperAdmin || enRole == UserRole::Operator)*/) { |
| | | pStatic->SetClickCallback(clickCallback); |
| | | pStatic->SetRoundedCorners(TRUE, 5); |
| | | pStatic->DisableBorder(); |
| | | } |
| | | |
| | | // å卿§ä»¶æé |
| | | m_staticControls.push_back(pStatic); |
| | | |
| | | return pStatic; |
| | | } |
| | | |
| | | CWnd* CIOMonitoringDlg::GetStaticControl(UINT id) |
| | | { |
| | | for (auto item : m_staticControls) { |
| | | TRACE(">>idï¼%d\n", item->GetDlgCtrlID()); |
| | | if (item->GetDlgCtrlID() == id) { |
| | | return item; |
| | | } |
| | | } |
| | | |
| | | return nullptr; |
| | | } |
| | | |
| | | CString& CIOMonitoringDlg::GetStaticControlAddrText(UINT id, CString& strAddr) |
| | | { |
| | | CWnd* pBtn = GetStaticControl(id); |
| | | if (pBtn != nullptr) { |
| | | CWnd* pLabel = (CWnd*)::GetProp(pBtn->GetSafeHwnd(), ADDR_WND); |
| | | if (pLabel != nullptr) { |
| | | pLabel->GetWindowText(strAddr); |
| | | } |
| | | } |
| | | |
| | | return strAddr; |
| | | } |
| | | |
| | | void CIOMonitoringDlg::DisplayCurrentPage() |
| | | { |
| | | int startIndex = (m_nCurrentPage - 1) * m_nRowsPerPage; |
| | | int endIndex = min(startIndex + m_nRowsPerPage, static_cast<int>(m_displayData.size())); |
| | | |
| | | m_inputStates.clear(); |
| | | m_outputStates.clear(); |
| | | m_inputPLCAddresses.clear(); |
| | | m_outputPLCAddresses.clear(); |
| | | |
| | | for (int i = 0; i < m_nRowsPerPage; ++i) { |
| | | int row = i; |
| | | |
| | | if (startIndex + i < endIndex) { |
| | | const auto& data = m_displayData[startIndex + i]; |
| | | |
| | | // æ·»å ç¶æå°å®¹å¨ä¸ |
| | | m_inputStates.push_back(FALSE); // 0 å |
| | | m_outputStates.push_back(FALSE); // 3 å |
| | | |
| | | // æ·»å PLC å°åå°å®¹å¨ä¸ |
| | | m_inputPLCAddresses.push_back(CString(data.inputAddress.c_str())); // 1 å |
| | | m_outputPLCAddresses.push_back(CString(data.outputAddress.c_str())); // 4 å |
| | | |
| | | // æ¾ç¤ºæ§ä»¶å¹¶è®¾ç½®å
容 |
| | | m_staticControls[row * m_nCols + 0]->SetWindowText(_T("OFF")); |
| | | m_staticControls[row * m_nCols + 0]->ShowWindow(SW_SHOW); |
| | | m_staticControls[row * m_nCols + 0]->SetBkColor(RGB(255, 0, 0)); |
| | | |
| | | m_staticControls[row * m_nCols + 1]->SetWindowText(CString(data.inputAddress.c_str())); |
| | | m_staticControls[row * m_nCols + 1]->ShowWindow(SW_SHOW); |
| | | |
| | | m_staticControls[row * m_nCols + 2]->SetWindowText(CString(data.inputDescription.c_str())); |
| | | m_staticControls[row * m_nCols + 2]->ShowWindow(SW_SHOW); |
| | | |
| | | m_staticControls[row * m_nCols + 3]->SetWindowText(_T("OFF")); |
| | | m_staticControls[row * m_nCols + 3]->ShowWindow(SW_SHOW); |
| | | m_staticControls[row * m_nCols + 3]->SetBkColor(RGB(255, 0, 0)); |
| | | |
| | | m_staticControls[row * m_nCols + 4]->SetWindowText(CString(data.outputAddress.c_str())); |
| | | m_staticControls[row * m_nCols + 4]->ShowWindow(SW_SHOW); |
| | | |
| | | m_staticControls[row * m_nCols + 5]->SetWindowText(CString(data.outputDescription.c_str())); |
| | | m_staticControls[row * m_nCols + 5]->ShowWindow(SW_SHOW); |
| | | } |
| | | else { |
| | | // éèè¿ä¸è¡çæææ§ä»¶ |
| | | for (int col = 0; col < m_nCols; ++col) { |
| | | m_staticControls[row * m_nCols + col]->ShowWindow(SW_HIDE); |
| | | } |
| | | } |
| | | } |
| | | |
| | | UpdatePageInfo(); |
| | | } |
| | | |
| | | void CIOMonitoringDlg::ClearDynamicControls() |
| | | { |
| | | for (auto* pStatic : m_staticControls) { |
| | | if (pStatic) { |
| | | pStatic->DestroyWindow(); |
| | | delete pStatic; |
| | | } |
| | | } |
| | | m_staticControls.clear(); |
| | | } |
| | | |
| | | bool CIOMonitoringDlg::ParsePLCAddress(const CString& address, MC::SOFT_COMPONENT& component, int& addr) |
| | | { |
| | | if (address.GetLength() < 2) { |
| | | return false; |
| | | } |
| | | |
| | | // æåç»ä»¶ç±»åï¼ç¬¬ä¸ä¸ªåç¬¦ï¼ |
| | | TCHAR componentChar = address[0]; |
| | | if (address.Left(2) == _T("ZR")) { |
| | | component = MC::SOFT_COMPONENT::ZR; |
| | | // æåæ°åé¨åï¼å»é¤ZRåç¼ï¼ |
| | | CString numericAddress = address.Mid(2); |
| | | addr = _tcstoul(numericAddress, nullptr, 16); |
| | | return addr != 0 || numericAddress.CompareNoCase(_T("0")) == 0; // å¦ææ¯ "0"ï¼ä¹è®¤ä¸ºææ |
| | | } |
| | | |
| | | // 对äºå
¶ä»ç»ä»¶ï¼æç
§å¸¸è§è§åå¤ç |
| | | CString hexAddress = address.Mid(1); |
| | | switch (componentChar) { |
| | | case 'D': |
| | | component = MC::SOFT_COMPONENT::D; |
| | | addr = _ttoi(hexAddress); |
| | | break; |
| | | case 'M': |
| | | component = MC::SOFT_COMPONENT::M; |
| | | addr = _tcstoul(hexAddress, nullptr, 16); |
| | | break; |
| | | case 'X': |
| | | component = MC::SOFT_COMPONENT::X; |
| | | addr = _tcstoul(hexAddress, nullptr, 16); |
| | | break; |
| | | case 'Y': |
| | | component = MC::SOFT_COMPONENT::Y; |
| | | addr = _tcstoul(hexAddress, nullptr, 16); |
| | | break; |
| | | case 'W': |
| | | component = MC::SOFT_COMPONENT::W; |
| | | addr = _tcstoul(hexAddress, nullptr, 16); |
| | | break; |
| | | case 'L': |
| | | component = MC::SOFT_COMPONENT::L; |
| | | addr = _tcstoul(hexAddress, nullptr, 16); |
| | | break; |
| | | case 'S': |
| | | component = MC::SOFT_COMPONENT::S; |
| | | addr = _tcstoul(hexAddress, nullptr, 16); |
| | | break; |
| | | case 'B': |
| | | component = MC::SOFT_COMPONENT::B; |
| | | addr = _tcstoul(hexAddress, nullptr, 16); |
| | | break; |
| | | case 'F': |
| | | component = MC::SOFT_COMPONENT::F; |
| | | addr = _tcstoul(hexAddress, nullptr, 16); |
| | | break; |
| | | default: |
| | | return false; |
| | | } |
| | | |
| | | // æ£æ¥å°åæ¯å¦ææ |
| | | if (addr == 0 && hexAddress.CompareNoCase(_T("0")) != 0) { |
| | | return false; |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | bool CIOMonitoringDlg::GeneratePLCAddress(MC::SOFT_COMPONENT component, int addr, CString& address, bool bHexFormat) |
| | | { |
| | | // æ ¹æ®ç»ä»¶ç±»åçæåç¼ |
| | | CString prefix; |
| | | switch (component) { |
| | | case MC::SOFT_COMPONENT::D: |
| | | prefix = _T("D"); |
| | | break; |
| | | case MC::SOFT_COMPONENT::M: |
| | | prefix = _T("M"); |
| | | break; |
| | | case MC::SOFT_COMPONENT::X: |
| | | prefix = _T("X"); |
| | | break; |
| | | case MC::SOFT_COMPONENT::Y: |
| | | prefix = _T("Y"); |
| | | break; |
| | | case MC::SOFT_COMPONENT::W: |
| | | prefix = _T("W"); |
| | | break; |
| | | case MC::SOFT_COMPONENT::L: |
| | | prefix = _T("L"); |
| | | break; |
| | | case MC::SOFT_COMPONENT::S: |
| | | prefix = _T("S"); |
| | | break; |
| | | case MC::SOFT_COMPONENT::B: |
| | | prefix = _T("B"); |
| | | break; |
| | | case MC::SOFT_COMPONENT::F: |
| | | prefix = _T("F"); |
| | | break; |
| | | case MC::SOFT_COMPONENT::ZR: |
| | | prefix = _T("ZR"); |
| | | break; |
| | | default: |
| | | return false; // å¦ææ¯æªç¥ç»ä»¶ç±»åï¼è¿å失败 |
| | | } |
| | | |
| | | // æ ¹æ® bHexFormat 夿è¾åºæ ¼å¼ |
| | | CString strAddr; |
| | | if (bHexFormat) { |
| | | strAddr.Format(_T("%X"), addr); // åå
è¿å¶æ ¼å¼ |
| | | } |
| | | else { |
| | | strAddr.Format(_T("%d"), addr); // åè¿å¶æ ¼å¼ |
| | | } |
| | | |
| | | // çææç»çå°åå符串 |
| | | address = prefix + strAddr; |
| | | return true; |
| | | } |
| | | |
| | | // å¤çPLCæ°æ®è¯»åçéç¨æ¹æ³ |
| | | void CIOMonitoringDlg::ReadPLCData(MC::SOFT_COMPONENT softComponent, int startAddr, int endAddr, std::function<void(IMcChannel*, int, char*, unsigned int, int)> callback) |
| | | { |
| | | int nSize; |
| | | // æ£æ¥å°åæ¯å¦ææï¼ä»¥åç»ä»¶æ¯å¦å¹é
|
| | | nSize = endAddr - startAddr + 1; |
| | | if (nSize < 1) { |
| | | return; |
| | | } |
| | | |
| | | // è¯»åæ°æ® |
| | | m_pPLC->readData(softComponent, startAddr, nSize, callback); |
| | | } |
| | | |
| | | void CIOMonitoringDlg::ReadPLCStates() |
| | | { |
| | | if (m_displayData.empty()) { |
| | | return; |
| | | } |
| | | |
| | | auto startData = m_displayData.front(); |
| | | auto endData = m_displayData.back(); |
| | | MC::SOFT_COMPONENT startSoftComponent, endSoftComponent; |
| | | int inputStartAddr, inputEndAddr; |
| | | ParsePLCAddress(CString(startData.inputAddress.c_str()), startSoftComponent, inputStartAddr); |
| | | ParsePLCAddress(CString(endData.inputAddress.c_str()), endSoftComponent, inputEndAddr); |
| | | ASSERT(startSoftComponent == endSoftComponent); |
| | | |
| | | // 读åè¾å
¥æ°æ® |
| | | ReadPLCData(startSoftComponent, inputStartAddr, inputEndAddr, [this, inputStartAddr](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) { |
| | | if (!::IsWindow(m_hWnd)) return; |
| | | for (auto& data : m_displayData) { |
| | | int nAddress; |
| | | MC::SOFT_COMPONENT enComponent; |
| | | if (ParsePLCAddress(CString(data.inputAddress.c_str()), enComponent, nAddress)) { |
| | | int nOffset = nAddress - inputStartAddr; |
| | | if (nOffset >= 0 && nOffset < (int)nDataSize) { |
| | | int byteIndex = nOffset / 8; |
| | | int bitIndex = nOffset % 8; |
| | | data.bInputStates = CToolUnits::getBit(pData[byteIndex], bitIndex); |
| | | } |
| | | } |
| | | } |
| | | }); |
| | | |
| | | // 读åè¾åºæ°æ® |
| | | int outputStartAddr, outputEndAddr; |
| | | ParsePLCAddress(CString(startData.outputAddress.c_str()), startSoftComponent, outputStartAddr); |
| | | ParsePLCAddress(CString(endData.outputAddress.c_str()), endSoftComponent, outputEndAddr); |
| | | ASSERT(startSoftComponent == endSoftComponent); |
| | | ReadPLCData(startSoftComponent, outputStartAddr, outputEndAddr, [this, outputStartAddr](IMcChannel* pChannel, int addr, char* pData, unsigned int nDataSize, int flag) { |
| | | if (!::IsWindow(m_hWnd)) return; |
| | | for (auto& data : m_displayData) { |
| | | int nAddress; |
| | | MC::SOFT_COMPONENT enComponent; |
| | | if (ParsePLCAddress(CString(data.outputAddress.c_str()), enComponent, nAddress)) { |
| | | int nOffset = nAddress - outputStartAddr; |
| | | if (nOffset >= 0 && nOffset < (int)nDataSize) { |
| | | int byteIndex = nOffset / 8; |
| | | int bitIndex = nOffset % 8; |
| | | data.bOutputStates = CToolUnits::getBit(pData[byteIndex], bitIndex); |
| | | TRACE(">>>> %d %d %d |||| %d\n", nOffset, byteIndex, bitIndex, data.bOutputStates); |
| | | } |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | |
| | | void CIOMonitoringDlg::UpdatePLCStatesToUI() |
| | | { |
| | | int startIndex = (m_nCurrentPage - 1) * m_nRowsPerPage; |
| | | int endIndex = min(startIndex + m_nRowsPerPage, static_cast<int>(m_displayData.size())); |
| | | |
| | | for (int i = 0; i < m_nRowsPerPage; ++i) { |
| | | int row = i; |
| | | |
| | | if (startIndex + i < endIndex) { |
| | | const auto& data = m_displayData[startIndex + i]; |
| | | // 设置å
容åèæ¯é¢è² |
| | | if (m_inputStates[i] != data.bInputStates) |
| | | { |
| | | m_staticControls[row * m_nCols + 0]->SetText(data.bInputStates ? _T("ON") : _T("OFF")); |
| | | m_staticControls[row * m_nCols + 0]->SetBkColor(data.bInputStates ? RGB(0, 255, 0) : RGB(255, 0, 0)); |
| | | m_inputStates[i] = data.bInputStates; |
| | | } |
| | | |
| | | if (m_outputStates[i] != data.bOutputStates) |
| | | { |
| | | m_staticControls[row * m_nCols + 3]->SetText(data.bOutputStates ? _T("ON") : _T("OFF")); |
| | | m_staticControls[row * m_nCols + 3]->SetBkColor(data.bOutputStates ? RGB(0, 255, 0) : RGB(255, 0, 0)); |
| | | m_outputStates[i] = data.bOutputStates; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | BEGIN_MESSAGE_MAP(CIOMonitoringDlg, CDialogEx) |
| | | ON_BN_CLICKED(IDC_BUTTON_PREV_PAGE, &CIOMonitoringDlg::OnBnClickedButtonPrevPage) |
| | | ON_BN_CLICKED(IDC_BUTTON_NEXT_PAGE, &CIOMonitoringDlg::OnBnClickedButtonNextPage) |
| | | ON_MESSAGE(ID_MSG_IO_CLICK, &CIOMonitoringDlg::OnIoClicked) |
| | | ON_WM_SIZE() |
| | | ON_WM_TIMER() |
| | | ON_WM_CLOSE() |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | | // CIOMonitoringDlg æ¶æ¯å¤çç¨åº |
| | | |
| | | |
| | | BOOL CIOMonitoringDlg::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | |
| | | // TODO: 卿¤æ·»å é¢å¤çåå§å |
| | | CRect screenRect, dlgRect, clientRect; |
| | | SystemParametersInfo(SPI_GETWORKAREA, 0, &screenRect, 0); |
| | | |
| | | GetClientRect(&clientRect); |
| | | m_nInitialWidth = clientRect.Width(); |
| | | m_nInitialHeight = clientRect.Height(); |
| | | |
| | | // åå§åé»è®¤åä½ |
| | | CFont* pDefaultFont = GetOrCreateFont(12); |
| | | |
| | | // éåææåæ§ä»¶ï¼è®°å½åå§ä½ç½®å¹¶è®¾ç½®é»è®¤åä½ |
| | | CWnd* pWnd = GetWindow(GW_CHILD); |
| | | while (pWnd) { |
| | | int nCtrlID = pWnd->GetDlgCtrlID(); |
| | | if (nCtrlID != -1) { |
| | | // è®°å½æ§ä»¶åå§å¸å± |
| | | CRect ctrlRect; |
| | | pWnd->GetWindowRect(&ctrlRect); |
| | | ScreenToClient(&ctrlRect); |
| | | m_mapCtrlLayouts[nCtrlID] = ctrlRect; |
| | | |
| | | // è·³è¿ç¹æ®æ§ä»¶ï¼å¦ MFCGridCtrlï¼ |
| | | TCHAR szClassName[256]; |
| | | GetClassName(pWnd->m_hWnd, szClassName, sizeof(szClassName)); |
| | | if (_tcsicmp(szClassName, _T("MFCGridCtrl")) == 0) { |
| | | pWnd = pWnd->GetNextWindow(); |
| | | continue; |
| | | } |
| | | |
| | | // 设置é»è®¤åä½ |
| | | pWnd->SetFont(pDefaultFont); |
| | | } |
| | | pWnd = pWnd->GetNextWindow(); |
| | | } |
| | | |
| | | GetWindowRect(&dlgRect); |
| | | int dlgWidth = dlgRect.Width() * 3; |
| | | int dlgHeight = dlgRect.Height() * 3; |
| | | |
| | | if (dlgWidth > screenRect.Width()) { |
| | | dlgWidth = screenRect.Width(); |
| | | } |
| | | if (dlgHeight > screenRect.Height()) { |
| | | dlgHeight = screenRect.Height(); |
| | | } |
| | | |
| | | int centerX = screenRect.left + (screenRect.Width() - dlgWidth) / 2; |
| | | int centerY = screenRect.top + (screenRect.Height() - dlgHeight) / 2; |
| | | MoveWindow(centerX, centerY, dlgWidth, dlgHeight); |
| | | |
| | | CreateDynamicControls(); |
| | | DisplayCurrentPage(); |
| | | |
| | | GetDlgItem(IDC_BUTTON_PREV_PAGE)->EnableWindow(m_nCurrentPage > 1); |
| | | GetDlgItem(IDC_BUTTON_NEXT_PAGE)->EnableWindow(m_nCurrentPage < m_nTotalPages); |
| | | |
| | | SetTimer(TIMER_READ_PLC_DATA, 500, nullptr); |
| | | SetTimer(TIMER_READ_UPDATE, 200, nullptr); |
| | | |
| | | return TRUE; // return TRUE unless you set the focus to a control |
| | | // å¼å¸¸: OCX 屿§é¡µåºè¿å FALSE |
| | | } |
| | | |
| | | void CIOMonitoringDlg::OnSize(UINT nType, int cx, int cy) |
| | | { |
| | | CDialogEx::OnSize(nType, cx, cy); |
| | | |
| | | // TODO: 卿¤å¤æ·»å æ¶æ¯å¤çç¨åºä»£ç |
| | | if (nType == SIZE_MINIMIZED || m_mapCtrlLayouts.empty()) { |
| | | return; |
| | | } |
| | | |
| | | float dScaleX = static_cast<float>(cx) / m_nInitialWidth; |
| | | float dScaleY = static_cast<float>(cy) / m_nInitialHeight; |
| | | |
| | | // éåå¯¹è¯æ¡ä¸çæææ§ä»¶ |
| | | AdjustControls(dScaleX, dScaleY); |
| | | } |
| | | |
| | | void CIOMonitoringDlg::OnBnClickedButtonPrevPage() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | if (m_nCurrentPage > 1) { |
| | | --m_nCurrentPage; |
| | | DisplayCurrentPage(); |
| | | } |
| | | else { |
| | | AfxMessageBox(_T("å·²ç»æ¯ç¬¬ä¸é¡µï¼")); |
| | | } |
| | | |
| | | GetDlgItem(IDC_BUTTON_PREV_PAGE)->EnableWindow(m_nCurrentPage > 1); |
| | | GetDlgItem(IDC_BUTTON_NEXT_PAGE)->EnableWindow(m_nCurrentPage < m_nTotalPages); |
| | | } |
| | | |
| | | void CIOMonitoringDlg::OnBnClickedButtonNextPage() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | if (m_nCurrentPage < m_nTotalPages) { |
| | | ++m_nCurrentPage; |
| | | DisplayCurrentPage(); |
| | | } |
| | | else { |
| | | AfxMessageBox(_T("å·²ç»æ¯æåä¸é¡µï¼")); |
| | | } |
| | | |
| | | GetDlgItem(IDC_BUTTON_PREV_PAGE)->EnableWindow(m_nCurrentPage > 1); |
| | | GetDlgItem(IDC_BUTTON_NEXT_PAGE)->EnableWindow(m_nCurrentPage < m_nTotalPages); |
| | | } |
| | | |
| | | LRESULT CIOMonitoringDlg::OnIoClicked(WPARAM wParam, LPARAM lParam) |
| | | { |
| | | CString strAddr; |
| | | GetStaticControlAddrText((UINT)wParam, strAddr); |
| | | |
| | | BOOL bOn = (BOOL)lParam; |
| | | int nAddress; |
| | | MC::SOFT_COMPONENT component; |
| | | if (ParsePLCAddress(strAddr, component, nAddress) && m_pPLC) { |
| | | TRACE("å°åè§£ææå: %s %d\n", strAddr, GetCurrentThreadId()); |
| | | int n = m_pPLC->writeBit(component, nAddress, bOn, [](IMcChannel* pChannel, int addr, DWORD value, int flag) { |
| | | if (flag == 0) { |
| | | TRACE("åå
¥æå: å°å: %d, å¼: %lu\n", addr, value); |
| | | } |
| | | else { |
| | | TRACE("åå
¥å¤±è´¥: å°å: %d, é误ç : %d\n", addr, flag); |
| | | } |
| | | }); |
| | | TRACE("å°åè§£ææå2: %d\n", n); |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | void CIOMonitoringDlg::OnTimer(UINT_PTR nIDEvent) |
| | | { |
| | | // TODO: 卿¤æ·»å æ¶æ¯å¤çç¨åºä»£ç å/æè°ç¨é»è®¤å¼ |
| | | if (TIMER_READ_PLC_DATA == nIDEvent) { |
| | | ASSERT(m_pPLC); |
| | | ReadPLCStates(); |
| | | } |
| | | else if (TIMER_READ_UPDATE == nIDEvent) { |
| | | ASSERT(m_pPLC); |
| | | UpdatePLCStatesToUI(); |
| | | } |
| | | |
| | | CDialogEx::OnTimer(nIDEvent); |
| | | } |
| | | |
| | | void CIOMonitoringDlg::OnClose() |
| | | { |
| | | // TODO: 卿¤æ·»å æ¶æ¯å¤çç¨åºä»£ç å/æè°ç¨é»è®¤å¼ |
| | | KillTimer(TIMER_READ_PLC_DATA); |
| | | KillTimer(TIMER_READ_UPDATE); |
| | | CDialogEx::OnClose(); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include "afxdialogex.h" |
| | | #include "IOManager.h" |
| | | #include "BLLabel.h" |
| | | #include "PLC.h" |
| | | |
| | | |
| | | // CIOMonitoringDlg å¯¹è¯æ¡ |
| | | |
| | | class CIOMonitoringDlg : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CIOMonitoringDlg) |
| | | |
| | | public: |
| | | CIOMonitoringDlg(CWnd* pParent = nullptr); // æ åæé 彿° |
| | | virtual ~CIOMonitoringDlg(); |
| | | void SetIOManager(const std::string& machineName); // 设置 IOManager åæºå¨å |
| | | void SetPLC(CPLC* pPLC); // 设置 PLC |
| | | |
| | | // å¯¹è¯æ¡æ°æ® |
| | | #ifdef AFX_DESIGN_TIME |
| | | enum { IDD = IDD_DIALOG_IO_MONITORING }; |
| | | #endif |
| | | |
| | | private: |
| | | CFont* GetOrCreateFont(int nFontSize); // è·åæå建åä½ |
| | | void SetDefaultFont(); // 设置é»è®¤åä½ |
| | | void AdjustControls(float dScaleX, float dScaleY); // è°æ´æ§ä»¶å¤§å° |
| | | void AdjustControlFont(CWnd* pWnd, int nWidth, int nHeight); // è°æ´æ§ä»¶åä½å¤§å° |
| | | |
| | | void UpdatePageInfo(); // æ´æ°åé¡µä¿¡æ¯ |
| | | void CreateDynamicControls(); // 卿å建æ§ä»¶ |
| | | CWnd* CreateStaticControl(UINT id, int x, int y, int width, int height, const CString& text, bool hasBorder = false, TextAlign alignment = AlignLeft, std::function<void()> clickCallback = nullptr); // åå»ºéææ§ä»¶ |
| | | CWnd* GetStaticControl(UINT id); // è·åéææ§ä»¶ |
| | | CString& GetStaticControlAddrText(UINT id, CString& strAddr); // è·åéææ§ä»¶å°åææ¬ |
| | | void DisplayCurrentPage(); // æ¾ç¤ºå½åé¡µæ°æ® |
| | | void ClearDynamicControls(); // æ¸
é¤å¨æåå»ºçæ§ä»¶ |
| | | bool ParsePLCAddress(const CString& address, MC::SOFT_COMPONENT& component, int& addr); // è§£æ PLC å°å |
| | | bool GeneratePLCAddress(MC::SOFT_COMPONENT component, int addr, CString& address, bool bHexFormat = false); // çæ PLC å°å |
| | | void ReadPLCData(MC::SOFT_COMPONENT softComponent, int startAddr, int endAddr, std::function<void(IMcChannel*, int, char*, unsigned int, int)> callback); // 读å PLC æ°æ® |
| | | void ReadPLCStates(); // 宿¶å¨è¯»PLC |
| | | void UpdatePLCStatesToUI(); // 宿¶å¨æ´æ°ç¶æçæ¹æ³ |
| | | |
| | | private: |
| | | CPLC* m_pPLC; |
| | | int m_nInitialWidth; |
| | | int m_nInitialHeight; |
| | | int m_nCurrentPage; // å½å页 |
| | | int m_nTotalPages; // æ»é¡µæ° |
| | | int m_nRowsPerPage; // æ¯é¡µæ¾ç¤ºçè¡æ° |
| | | int m_nCols; // æ¯è¡çæ§ä»¶ç»æ° |
| | | std::map<int, CFont*> m_mapFonts; // å使 å° |
| | | std::map<int, CRect> m_mapCtrlLayouts; // æ§ä»¶å¸å±æ å° |
| | | std::vector<IOData> m_displayData; // å½åæ¾ç¤ºçæ°æ® |
| | | std::vector<BOOL> m_inputStates; // è¾å
¥ç¶æ |
| | | std::vector<BOOL> m_outputStates; // è¾åºç¶æ |
| | | std::vector<CString> m_inputPLCAddresses; // åå¨ 1 å PLC å°å |
| | | std::vector<CString> m_outputPLCAddresses; // åå¨ 4 å PLC å°å |
| | | |
| | | private: |
| | | CStatic m_staticPageNum; |
| | | std::vector<CBLLabel*> m_staticControls; // 卿å建çéææ§ä»¶ |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV æ¯æ |
| | | |
| | | DECLARE_MESSAGE_MAP() |
| | | public: |
| | | virtual BOOL OnInitDialog(); |
| | | afx_msg void OnSize(UINT nType, int cx, int cy); |
| | | afx_msg void OnBnClickedButtonPrevPage(); |
| | | afx_msg void OnBnClickedButtonNextPage(); |
| | | afx_msg LRESULT OnIoClicked(WPARAM wParam, LPARAM lParam); |
| | | afx_msg void OnTimer(UINT_PTR nIDEvent); |
| | | afx_msg void OnClose(); |
| | | }; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // InputDialog.cpp: å®ç°æä»¶ |
| | | // |
| | | |
| | | #include "stdafx.h" |
| | | #include "BoounionPLC.h" |
| | | #include "afxdialogex.h" |
| | | #include "InputDialog.h" |
| | | |
| | | |
| | | // CInputDialog å¯¹è¯æ¡ |
| | | |
| | | IMPLEMENT_DYNAMIC(CInputDialog, CDialogEx) |
| | | |
| | | CInputDialog::CInputDialog(const CString& strTitle, const CString& strPrompt, CWnd* pParent /*=nullptr*/) |
| | | : CDialogEx(IDD_DIALOG_INPUT, pParent), m_strTitle(strTitle), m_strPrompt(strPrompt), m_strInput(_T("")) |
| | | { |
| | | |
| | | } |
| | | |
| | | CInputDialog::~CInputDialog() |
| | | { |
| | | } |
| | | |
| | | CString CInputDialog::GetInputText() const |
| | | { |
| | | return m_strInput; |
| | | } |
| | | |
| | | void CInputDialog::DoDataExchange(CDataExchange* pDX) |
| | | { |
| | | CDialogEx::DoDataExchange(pDX); |
| | | DDX_Control(pDX, IDC_EDIT_INPUT, m_editInput); |
| | | DDX_Control(pDX, IDC_STATIC_PROMPT, m_staticPrompt); |
| | | } |
| | | |
| | | |
| | | BEGIN_MESSAGE_MAP(CInputDialog, CDialogEx) |
| | | ON_BN_CLICKED(IDOK, &CInputDialog::OnBnClickedOk) |
| | | END_MESSAGE_MAP() |
| | | |
| | | |
| | | // CInputDialog æ¶æ¯å¤çç¨åº |
| | | |
| | | |
| | | BOOL CInputDialog::OnInitDialog() |
| | | { |
| | | CDialogEx::OnInitDialog(); |
| | | |
| | | // TODO: 卿¤æ·»å é¢å¤çåå§å |
| | | SetWindowText(m_strTitle); |
| | | m_staticPrompt.SetWindowText(m_strPrompt); |
| | | m_editInput.SetFocus(); |
| | | m_editInput.SetWindowText("1"); |
| | | |
| | | return TRUE; // return TRUE unless you set the focus to a control |
| | | // å¼å¸¸: OCX 屿§é¡µåºè¿å FALSE |
| | | } |
| | | |
| | | |
| | | void CInputDialog::OnBnClickedOk() |
| | | { |
| | | // TODO: 卿¤æ·»å æ§ä»¶éç¥å¤çç¨åºä»£ç |
| | | m_editInput.GetWindowText(m_strInput); |
| | | if (m_strInput.IsEmpty()) { |
| | | AfxMessageBox(_T("è¾å
¥ä¸è½ä¸ºç©ºï¼")); |
| | | return; |
| | | } |
| | | |
| | | CDialogEx::OnOK(); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #pragma once |
| | | #include "afxdialogex.h" |
| | | |
| | | |
| | | // CInputDialog å¯¹è¯æ¡ |
| | | |
| | | class CInputDialog : public CDialogEx |
| | | { |
| | | DECLARE_DYNAMIC(CInputDialog) |
| | | |
| | | public: |
| | | CInputDialog(const CString& strTitle, const CString& strPrompt, CWnd* pParent = nullptr); |
| | | virtual ~CInputDialog(); |
| | | |
| | | CString GetInputText() const; // è·åè¾å
¥å
容 |
| | | |
| | | // å¯¹è¯æ¡æ°æ® |
| | | #ifdef AFX_DESIGN_TIME |
| | | enum { IDD = IDD_DIALOG_INPUT }; |
| | | #endif |
| | | |
| | | private: |
| | | CEdit m_editInput; |
| | | CStatic m_staticPrompt; |
| | | |
| | | CString m_strTitle; // å¯¹è¯æ¡æ é¢ |
| | | CString m_strPrompt; // æç¤ºææ¬ |
| | | CString m_strInput; // è¾å
¥çææ¬ |
| | | |
| | | protected: |
| | | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV æ¯æ |
| | | |
| | | DECLARE_MESSAGE_MAP() |
| | | public: |
| | | virtual BOOL OnInitDialog(); |
| | | afx_msg void OnBnClickedOk(); |
| | | }; |
| | |
| | | #if defined(_WIN64) |
| | | #if defined(_DEBUG) |
| | | #pragma comment(lib, "..\\DatabaseSDK\\lib\\x64\\Debug\\DatabaseEx.lib") |
| | | #pragma comment(lib, "..\\BLControlsSDK\\lib\\x64\\Debug\\BLControlsD.lib") |
| | | #else |
| | | #pragma comment(lib, "..\\DatabaseSDK\\lib\\x64\\Release\\DatabaseEx.lib") |
| | | #pragma comment(lib, "..\\BLControlsSDK\\lib\\x64\\Release\\BLControls.lib") |
| | | #endif |
| | | #else |
| | | #if defined(_DEBUG) |
| | | #pragma comment(lib, "..\\DatabaseSDK\\lib\\Win32\\Debug\\DatabaseEx.lib") |
| | | #pragma comment(lib, "..\\BLControlsSDK\\lib\\Win32\\Debug\\BLControlsD.lib") |
| | | #else |
| | | #pragma comment(lib, "..\\DatabaseSDK\\lib\\Win32\\Release\\DatabaseEx.lib") |
| | | #pragma comment(lib, "..\\BLControlsSDK\\lib\\Win32\\Release\\BLControls.lib") |
| | | #endif |
| | | #endif |
| | | |