QuakeGod
2024-12-24 61deef5cdf96cbfdd6ad45be49e80d597c00ca65
提交 | 用户 | age
0ed438 1 
Q 2 // MTerm1.cpp: 定义应用程序的类行为。
3 //
4
5 #include "pch.h"
6 #include "framework.h"
7 #include "afxwinappex.h"
8 #include "afxdialogex.h"
9 #include "MTerm1.h"
10 #include "MainFrm.h"
11
12 #include "ChildFrm.h"
13 #include "MTerm1Doc.h"
14 #include "MTerm1View.h"
418cb3 15 #include "MTerm1LdsView.h"
Q 16 #include "MTerm1BldView.h"
17 #include "MTerm1BnlView.h"
18
19 #include "MTerm1CoilView.h"
20 #include "MTerm1DataView.h"
21
22 #include "MTerm1TestView.h"
23 #include "MTerm1CtrlView.h"
24 #include "MTerm1ProgTxt.h"
25
26
27
28 #include "MTerm1CommDevView.h"
0ed438 29
Q 30 #ifdef _DEBUG
31 #define new DEBUG_NEW
32 #endif
33
34 #include <devguid.h>
35 #include <SetupAPI.h>
418cb3 36 //#include "HvSerialPort.h"
Q 37 //#include "CAnsiParser.h"
38 //#include "CDataParser1.h"
39 //#include "KLink.h"
0ed438 40
Q 41 #include <eh.h>
42 #include <dbghelp.h>
43 #pragma comment(lib,"dbghelp.lib")
44 #pragma comment(lib,"SetupAPI.lib")
418cb3 45 #pragma comment(lib,"gdiplus.lib")
0ed438 46
418cb3 47 #include "../KLink1/KLink.h"
Q 48
49 #pragma comment(lib,"KLink1.lib")
0ed438 50 MHash MyCfg1;
418cb3 51 Logger myLogger1;
61deef 52 MHash DeviceList;
0ed438 53
Q 54 // CMTerm1App
55
56 BEGIN_MESSAGE_MAP(CMTerm1App, CWinAppEx)
57     ON_COMMAND(ID_APP_ABOUT, &CMTerm1App::OnAppAbout)
58     // 基于文件的标准文档命令
59 //    ON_COMMAND(ID_FILE_NEW, &CWinAppEx::OnFileNew)
60     ON_COMMAND(ID_FILE_NEW, &OnFileNew)
61     ON_COMMAND(ID_FILE_OPEN, &CWinAppEx::OnFileOpen)
62     // 标准打印设置命令
63     ON_COMMAND(ID_FILE_PRINT_SETUP, &CWinAppEx::OnFilePrintSetup)
418cb3 64 //    ON_COMMAND(ID_COMUNICATION_SET, &CMTerm1App::OnComunicationSet)
Q 65     ON_COMMAND(ID_ENV_SET, &CMTerm1App::OnEnvSet)
0ed438 66 END_MESSAGE_MAP()
Q 67
68
69 // CMTerm1App 构造
70
71 CMTerm1App::CMTerm1App() noexcept
72 {
73     m_bHiColorIcons = TRUE;
74     // 支持重新启动管理器
75     m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_ALL_ASPECTS;
76 #ifdef _MANAGED
77     // 如果应用程序是利用公共语言运行时支持(/clr)构建的,则: 
78     //     1) 必须有此附加设置,“重新启动管理器”支持才能正常工作。
79     //     2) 在您的项目中,您必须按照生成顺序向 System.Windows.Forms 添加引用。
80     System::Windows::Forms::Application::SetUnhandledExceptionMode(System::Windows::Forms::UnhandledExceptionMode::ThrowException);
81 #endif
82
83     // TODO: 将以下应用程序 ID 字符串替换为唯一的 ID 字符串;建议的字符串格式
84     //为 CompanyName.ProductName.SubProduct.VersionInformation
418cb3 85     SetAppID(_T("MultiTerminal2.AppID.NoVersion"));
0ed438 86
Q 87     // TODO: 在此处添加构造代码,
88     // 将所有重要的初始化放置在 InitInstance 中
89 }
90
91 // 唯一的 CMTerm1App 对象
92
93 CMTerm1App theApp;
94
95
96 // CMTerm1App 初始化
97
98 BOOL CMTerm1App::InitInstance()
99 {
100     // 如果一个运行在 Windows XP 上的应用程序清单指定要
101     // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
102     //则需要 InitCommonControlsEx()。  否则,将无法创建窗口。
103     INITCOMMONCONTROLSEX InitCtrls;
104     InitCtrls.dwSize = sizeof(InitCtrls);
105     // 将它设置为包括所有要在应用程序中使用的
106     // 公共控件类。
107     InitCtrls.dwICC = ICC_WIN95_CLASSES;
108     InitCommonControlsEx(&InitCtrls);
109
110     CWinAppEx::InitInstance();
111
418cb3 112     if (!AfxSocketInit())
Q 113     {
114         AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
115         return FALSE;
116     }
0ed438 117
Q 118     // 初始化 OLE 库
119     if (!AfxOleInit())
120     {
121         AfxMessageBox(IDP_OLE_INIT_FAILED);
122         return FALSE;
123     }
124
125     AfxEnableControlContainer();
126
418cb3 127     EnableTaskbarInteraction(FALSE);
0ed438 128
Q 129     // 使用 RichEdit 控件需要 AfxInitRichEdit2()
418cb3 130      AfxInitRichEdit2();
0ed438 131
Q 132     // 标准初始化
133     // 如果未使用这些功能并希望减小
134     // 最终可执行文件的大小,则应移除下列
135     // 不需要的特定初始化例程
136     // 更改用于存储设置的注册表项
137     // TODO: 应适当修改该字符串,
138     // 例如修改为公司或组织名
139     SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
140     LoadStdProfileSettings(4);  // 加载标准 INI 文件选项(包括 MRU)
141
61deef 142     DeviceList.LoadFromFile(_T("./DeviceList.Ini"));
0ed438 143     // 注册应用程序的文档模板。  文档模板
Q 144     // 将用作文档、框架窗口和视图之间的连接
418cb3 145 //    CMultiDocTemplate* pDocTemplate;
0ed438 146     pDocTemplate = new CMultiDocTemplate(IDR_MTerm1TYPE,
Q 147         RUNTIME_CLASS(CMTerm1Doc),
148         RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
149         RUNTIME_CLASS(CMTerm1View));
150     if (!pDocTemplate)
151         return FALSE;
152     AddDocTemplate(pDocTemplate);
418cb3 153 ///*
Q 154 //    CMultiDocTemplate * m_pNewDocTemplate;
155 ///*
156     m_pLdsViewTemplate = new CMultiDocTemplate(IDR_MTerm1TYPE,
157         RUNTIME_CLASS(CMTerm1Doc),
158         RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
159         RUNTIME_CLASS(CMTerm1LdsView));
160     if (!m_pLdsViewTemplate)
161         return FALSE;
162     AddDocTemplate(m_pLdsViewTemplate);
0ed438 163
418cb3 164     m_pBldViewTemplate = new CMultiDocTemplate(IDR_MTerm1TYPE,
Q 165         RUNTIME_CLASS(CMTerm1Doc),
166         RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
167         RUNTIME_CLASS(CMTerm1BldView));
168     if (!m_pBldViewTemplate)
169         return FALSE;
170     AddDocTemplate(m_pBldViewTemplate);
171
172     m_pBnlViewTemplate = new CMultiDocTemplate(IDR_MTerm1TYPE,
173         RUNTIME_CLASS(CMTerm1Doc),
174         RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
175         RUNTIME_CLASS(CMTerm1BnlView));
176     if (!m_pBnlViewTemplate)
177         return FALSE;
178     AddDocTemplate(m_pBnlViewTemplate);
61deef 179 /*
418cb3 180     m_pCommDevViewTemplate = new CMultiDocTemplate(IDR_MTerm1TYPE,
Q 181         RUNTIME_CLASS(CMTerm1Doc),
182         RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
183         RUNTIME_CLASS(CMTerm1CommDevView));
184     if (!m_pCommDevViewTemplate)
185         return FALSE;
186     AddDocTemplate(m_pCommDevViewTemplate);
61deef 187 */
Q 188 /*
418cb3 189     m_pCtrlViewTemplate = new CMultiDocTemplate(IDR_MTerm1TYPE,
Q 190         RUNTIME_CLASS(CMTerm1Doc),
191         RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
192         RUNTIME_CLASS(CMTerm1CtrlView));
193     if (!m_pCtrlViewTemplate)
194         return FALSE;
195     AddDocTemplate(m_pCtrlViewTemplate);
61deef 196 // */
Q 197 /*
418cb3 198     m_pProgViewTemplate = new CMultiDocTemplate(IDR_MTerm1TYPE,
Q 199         RUNTIME_CLASS(CMTerm1Doc),
200         RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
201         RUNTIME_CLASS(CMTerm1ProgTxt));
202     if (!m_pProgViewTemplate)
203         return FALSE;
204     AddDocTemplate(m_pProgViewTemplate);
61deef 205   */
418cb3 206     m_pCoilViewTemplate = new CMultiDocTemplate(IDR_MTerm1TYPE,
Q 207         RUNTIME_CLASS(CMTerm1Doc),
208         RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
209         RUNTIME_CLASS(CMTerm1CoilView));
210     if (!m_pCoilViewTemplate)
211         return FALSE;
212     AddDocTemplate(m_pCoilViewTemplate);
213
214     m_pDataViewTemplate = new CMultiDocTemplate(IDR_MTerm1TYPE,
215         RUNTIME_CLASS(CMTerm1Doc),
216         RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
217         RUNTIME_CLASS(CMTerm1DataView));
218     if (!m_pDataViewTemplate)
219         return FALSE;
220     AddDocTemplate(m_pDataViewTemplate);
61deef 221 /*
418cb3 222     m_pNewDocTemplate = new CMultiDocTemplate(IDR_MTerm1TYPE,
Q 223         RUNTIME_CLASS(CMTerm1Doc),
224         RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
225         RUNTIME_CLASS(CMTerm1TestView));
226     if (!m_pNewDocTemplate)
227         return FALSE;
228     AddDocTemplate(m_pNewDocTemplate);
61deef 229
Q 230  //*/
0ed438 231     // 创建主 MDI 框架窗口
Q 232     CMainFrame* pMainFrame = new CMainFrame;
233     if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME))
234     {
235         delete pMainFrame;
236         return FALSE;
237     }
238     m_pMainWnd = pMainFrame;
239
240
241     // 分析标准 shell 命令、DDE、打开文件操作的命令行
242     CCommandLineInfo cmdInfo;
243     ParseCommandLine(cmdInfo);
244
418cb3 245     if (cmdInfo.m_nShellCommand == CCommandLineInfo::FileNew)
Q 246         cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;
0ed438 247
Q 248     // 调度在命令行中指定的命令。  如果
249     // 用 /RegServer、/Register、/Unregserver 或 /Unregister 启动应用程序,则返回 FALSE。
250     if (!ProcessShellCommand(cmdInfo))
251         return FALSE;
252     // 主窗口已初始化,因此显示它并对其进行更新
253     pMainFrame->ShowWindow(m_nCmdShow);
254     pMainFrame->UpdateWindow();
255     return TRUE;
256 }
257
258 int CMTerm1App::ExitInstance()
259 {
260     //TODO: 处理可能已添加的附加资源
261     AfxOleTerm(FALSE);
4ed7fc 262     //this->CleanState();
0ed438 263
Q 264     return CWinAppEx::ExitInstance();
265 }
266
267 // CMTerm1App 消息处理程序
268
269
270 // 用于应用程序“关于”菜单项的 CAboutDlg 对话框
271
272 class CAboutDlg : public CDialogEx
273 {
274 public:
275     CAboutDlg() noexcept;
276
277 // 对话框数据
278 #ifdef AFX_DESIGN_TIME
279     enum { IDD = IDD_ABOUTBOX };
280 #endif
281
282 protected:
283     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
284
285 // 实现
286 protected:
287     DECLARE_MESSAGE_MAP()
288 };
289
290 CAboutDlg::CAboutDlg() noexcept : CDialogEx(IDD_ABOUTBOX)
291 {
292 }
293
294 void CAboutDlg::DoDataExchange(CDataExchange* pDX)
295 {
296     CDialogEx::DoDataExchange(pDX);
297 }
298
299 BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
300 END_MESSAGE_MAP()
301
302 // 用于运行对话框的应用程序命令
303 void CMTerm1App::OnAppAbout()
304 {
305     CAboutDlg aboutDlg;
306     aboutDlg.DoModal();
307 }
308
309 // CMTerm1App 消息处理程序
418cb3 310
Q 311 void CMTerm1App::OnFileNew()
312 {
313     // TODO: 在此添加命令处理程序代码
314     POSITION ps = m_pDocManager->GetFirstDocTemplatePosition();
315     CDocTemplate *pDocTemplate = m_pDocManager->GetNextDocTemplate(ps);
316     pDocTemplate->OpenDocumentFile(NULL);
317 }
318
319
320
321 void CMTerm1App::OnComunicationSet()
322 {
323     // TODO: 在此添加命令处理程序代码
324 }
325
326
327 void CMTerm1App::OnEnvSet()
328 {
329     // TODO: 在此添加命令处理程序代码
330 }
0ed438 331
Q 332
333 int SysLog(CString s, int channel)
334 {
418cb3 335     myLogger1.LogTxt(s, channel);
Q 336     return 1;
337 }
338
339 int DbgLog(CString s, int channel)
340 {
341     myLogger1.LogTxt(s, channel);
0ed438 342     return 1;
Q 343 }
344
345 int PopupMessage(CString Msg, int channel)
346 {
347     Msg.Trim(_T("\r\n"));
348     SysLog(_T("报警信息: ") + Msg + _T("\r\n"), channel);
349     return 0;
350 }
351
352 void DoEvents()
353 {
354     MSG msg;
355     while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
356     {
357         DispatchMessage(&msg);
358         TranslateMessage(&msg);
359     }
360 }
361
362 void dump_callstack(PCONTEXT pcontext, CString & infostr)
363 {
364 #ifdef _WIN64
365
366     STACKFRAME64 sf;
367     memset(&sf, 0, sizeof(STACKFRAME64));
368
369     sf.AddrPC.Offset = pcontext->Rip;
370     //context->
371     sf.AddrPC.Mode = AddrModeFlat;
372     sf.AddrStack.Offset = pcontext->Rsp;
373     sf.AddrStack.Mode = AddrModeFlat;
374     sf.AddrFrame.Offset = pcontext->Rbp;
375     sf.AddrFrame.Mode = AddrModeFlat;
376
377     DWORD machineType = //IMAGE_FILE_MACHINE_I386;
378         IMAGE_FILE_MACHINE_AMD64;
379 #elif defined _WIN32
380     STACKFRAME sf;
381     memset(&sf, 0, sizeof(STACKFRAME));
382
383     sf.AddrPC.Offset = pcontext->Eip;
384     //context->
385     sf.AddrPC.Mode = AddrModeFlat;
386     sf.AddrStack.Offset = pcontext->Esp;
387     sf.AddrStack.Mode = AddrModeFlat;
388     sf.AddrFrame.Offset = pcontext->Ebp;
389     sf.AddrFrame.Mode = AddrModeFlat;
390
391     DWORD machineType = //IMAGE_FILE_MACHINE_I386;
392         IMAGE_FILE_MACHINE_AMD64;
393 #endif
394     HANDLE hProcess = GetCurrentProcess();
395     HANDLE hThread = GetCurrentThread();
396
397     for (;;)
398     {
399         if (!StackWalk(machineType, hProcess, hThread, &sf, pcontext, 0, SymFunctionTableAccess, SymGetModuleBase, 0))
400         {
401             break;
402         }
403
404         if (sf.AddrFrame.Offset == 0)
405         {
406             break;
407         }
408         BYTE symbolBuffer[sizeof(SYMBOL_INFO) + 1024];
409         PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)symbolBuffer;
410
411         pSymbol->SizeOfStruct = sizeof(symbolBuffer);
412         pSymbol->MaxNameLen = 1024;
413
414         DWORD64 symDisplacement = 0;
415         if (SymFromAddr(hProcess, sf.AddrPC.Offset, 0, pSymbol))
416         {
417             printf("Function : %s\n", pSymbol->Name);
418             infostr.AppendFormat(_T("Function : %S \r\n"), pSymbol->Name);
419         }
420         else
421         {
422             printf("SymFromAdd failed!\n");
423             //    infostr.AppendFormat(_T("SymFromAdd failed \r\n"),pSymbol->Name);
424         }
425
426         DWORD dwLineDisplacement;
427 #ifdef _WIN64
428         IMAGEHLP_LINEW64 lineInfoW = { sizeof(IMAGEHLP_LINEW64) };
429         if (SymGetLineFromAddrW(hProcess, sf.AddrPC.Offset, &dwLineDisplacement, &lineInfoW))
430         {
431             //        printf( "[Source File : %s]\n", lineInfo.FileName ); 
432             //        printf( "[Source Line : %u]\n", lineInfo.LineNumber ); 
433             CString s1(lineInfoW.FileName);
434             infostr.AppendFormat(_T("File %s Line %d\r\n"), s1.Mid(s1.ReverseFind(_T('\\')) + 1, 99), lineInfoW.LineNumber);
435         }
436         else
437         {
438             printf("SymGetLineFromAddr failed!\n");
439             //    infostr.Append(_T("SymGetLineFromAddr failed!\r\n"));
440         }
441 #elif defined _WIN32
442         IMAGEHLP_LINE lineInfo = { sizeof(IMAGEHLP_LINE) };
443         if (SymGetLineFromAddr(hProcess, sf.AddrPC.Offset, &dwLineDisplacement, &lineInfo))
444         {
445             //        printf( "[Source File : %s]\n", lineInfo.FileName ); 
446             //        printf( "[Source Line : %u]\n", lineInfo.LineNumber ); 
447             CString s1(lineInfo.FileName);
448             infostr.AppendFormat(_T("File %s Line %d\r\n"), s1.Mid(s1.ReverseFind(_T('\\')) + 1, 99), lineInfo.LineNumber);
449         }
450         else
451         {
452             printf("SymGetLineFromAddr failed!\n");
453             //    infostr.Append(_T("SymGetLineFromAddr failed!\r\n"));
454         }
455 #endif
456
457     }
458 }
459 DWORD excep_filter(LPEXCEPTION_POINTERS lpEP)
460 {
461     /**//// init dbghelp.dll
462     CString s1;
463     if (SymInitialize(GetCurrentProcess(), NULL, TRUE))
464     {
465         printf("Init dbghelp ok.\n");
466     }
467
468     dump_callstack(lpEP->ContextRecord, s1);
469
470     if (SymCleanup(GetCurrentProcess()))
471     {
472         printf("Cleanup dbghelp ok.\n");
473     }
474
475     return EXCEPTION_EXECUTE_HANDLER;
476 }
477
478 void Trans_Tunc(unsigned int n, EXCEPTION_POINTERS* pExp)
479 {
480     //    pExp->ExceptionRecord.
481     //    throw SE_Exception(n);
482     CString s1;
483     if (SymInitialize(GetCurrentProcess(), NULL, TRUE))
484     {
485         printf("Init dbghelp ok.\n");
486         //        s1=_T("Init dbghelp ok.\r\n");
487     }
488
489     dump_callstack(pExp->ContextRecord, s1);
490
491     if (SymCleanup(GetCurrentProcess()))
492     {
493         printf("Cleanup dbghelp ok.\n");
494         //        s1.Append(_T("Cleanup dbghelp ok.\n"));
495     }
496     throw SE_Exception(n, pExp->ExceptionRecord->ExceptionAddress, s1);
497 }
498
499 int DisplayException(CString File, int Line, CString Func, CString Sentence, SE_Exception &e)
500 {
501     CString Serror;
502     CString s1;
503     s1.Format(_T("程序发生SE异常 代码 %08X 地址 %p \r\nFile: %s \r\nLine: %d \r\nFunc %s \r\n语句 %s \r\n 信息\r\n %s \r\n"), e.getSeNumber(), e.getAddress(), File, Line, Func, Sentence, e.getInfoStr());;
504     PopupMessage(s1);
505     return 0;
506 }
507 int DisplayException(CString File, int Line, CString Func, CString Sentence, CException *e)
508 {
509     CString Serror;
510     CString s1;
511     e->GetErrorMessage(Serror.GetBuffer(256), 256);
512     Serror.ReleaseBuffer();
513     s1.Format(_T("程序发生C++异常 %s 在File: %s Line: %d Func %s Sentence %s \r\n"), Serror, File, Line, Func, Sentence);
514     PopupMessage(s1);
515     return 0;
516 }
517 int DisplayException(CString File, int Line, CString Func, CString Sentence)
518 {
519     CString s1;
520     s1.Format(_T("程序发生未知错误 File: %s Line: %d Func %s Sentence %s \r\n"), File, Line, Func, Sentence);
521     PopupMessage(s1);
522     return 0;
523 }
524
525
526 int LoadMyConfig()
527 {
528     CString ConfigFilePathName;
529     ConfigFilePathName = _T("./Settings.ini");
530     int j = MyCfg1.LoadFromFile(ConfigFilePathName);
531     return j;
532 }
533
534 int SaveMyConfig()
535 {
536     CString ConfigFilePathName;
537     ConfigFilePathName = _T("./Settings.ini");
538     int j = MyCfg1.SaveToFile(ConfigFilePathName);
539     return j;
540 }
541
542
543 //得到COMx的名字
544 //namebuf:用于存放名字的缓冲区
545 //bufsize:缓冲区大小
546 //comx:要查找的COM编号.例如:COM1,COM2,COM3....
547 //返回值:0,成功找到了.
548 //       1,失败.
549 int get_com_name(CString comx, CString &namebuf)
550 {
551     HDEVINFO hdinfo;
552     int res = 0;
553     SP_DEVINFO_DATA   hddevinfo = { sizeof(SP_DEVINFO_DATA) };
554     hdinfo = SetupDiGetClassDevs(&GUID_DEVCLASS_PORTS, 0, 0, DIGCF_PRESENT);//获取PORTS类别的已安装设备信息
555     if (hdinfo != INVALID_HANDLE_VALUE)//获取成功
556     {
557         for (int i = 0; SetupDiEnumDeviceInfo(hdinfo, i, &hddevinfo); i++)//轮询所有已安装设备
558         {
559             SetupDiGetDeviceRegistryProperty(hdinfo, &hddevinfo, SPDRP_FRIENDLYNAME, 0, (PBYTE)(namebuf.GetBuffer(2048)), 2048, 0);//获得单个装置的详细资料
560             namebuf.ReleaseBuffer();
561             if (namebuf.Find(comx) != -1) {
562                 res = 1; break;
563             }
564             //char *t;
565             //t = strstr(namebuf, comx);
566             //if (t)
567             //{
568             //    t--;
569             //    *t = '\0';//添加结束符,作用就是把"(COMX)"这段字符去掉
570             //    res = 0;
571             //    break;//成功找到了COMx的名字
572             //}
573         }
574     }
575     return res;
576 }
577
6ff05a 578 CString intToString(int num, int digit)
0ed438 579 {
Q 580     static CString Str1;
418cb3 581     if (digit != 0) {
Q 582         CString str2;
583         str2.Format(_T("%%%dd"), digit);
584         Str1.Format(str2, num);
585
586     }else {
587         Str1.Format(_T("%d"), num);
588     }
589
0ed438 590     int k = Str1.GetLength();
Q 591     int j = (k - 1) / 3;    //逗号个数
592     int l = k - j * 3; //起始位置
61deef 593     if (Str1[l-1] < '0' || Str1[l-1] > '9') { l += 3; j -= 1; }
0ed438 594     for (int i = l; i < k + j; i += 4)
Q 595     {
596         Str1.Insert(i, _T(","));
597     }
598
599     return Str1;
600 }
6ff05a 601 CString fixToString(int num, int digit, int fracdigit)
Q 602 {
603     static CString Str1;
604     if (digit != 0) {
605         CString str2;
606         str2.Format(_T("%%%dd"), digit);
607         Str1.Format(str2, num);
0ed438 608
6ff05a 609     }
Q 610     else {
611         Str1.Format(_T("%d"), num);
612     }
613
614     int k = Str1.GetLength();
615     int j = (k - 1 - fracdigit) / 3;    //逗号个数
616     int l = k - fracdigit - j * 3; //起始位置
617     for (int i = l; i < k -fracdigit + j; i += 4)
618     {
619         Str1.Insert(i, _T(","));
620     }
621     if (fracdigit>0) Str1.Insert(k - fracdigit + j, '.');
622     return Str1;
623 }
0ed438 624 CString & intToBinString(int num, int digits)
Q 625 {
626     static CString Str1;
627     Str1.Empty();
628     int mask = 1 << (digits - 1);
629
630     for (int i = 0; i < digits; i++)
631     {
632         if (num&mask) Str1.Append(_T("*"));
633         else Str1.Append(_T("."));
634         mask >>= 1;
635     }
636     return Str1;
61deef 637 }
Q 638
639 CString DeviceTypeToStr(int DeviceTypeVer)
640 {
641     // TODO: 在此处添加实现代码.
642
643     static CString DeviceName;
644     DeviceName.Empty();
645     CString s1, s2;
646     UCHAR DeviceType, DeviceVer;
647     DeviceType = (DeviceTypeVer >> 8) & 0xff;
648     DeviceVer = DeviceTypeVer & 0xff;
649     s1.Format(_T("%02X"), DeviceType);
650
651     if (DeviceList["FAMILY"].Exist(s1))
652     {
653         DeviceName = DeviceList["FAMiLY"][s1];
654         s2.Format(_T("%02X"), DeviceVer);
655         Hash h1 = DeviceList[s1];
656         if (DeviceList[s1].Exist(s2))
657         {
658             DeviceName.Append(_T(", "));
659             DeviceName.Append(DeviceList[s1][s2]);
660         }
661         else
662         {
663             //DeviceName.Append(_T(", "));
664             DeviceName.AppendFormat(_T("(%02X)"), DeviceVer);
665         }
666     }
667     else { DeviceName.Format(_T("Device %02X(%02X)"), DeviceType, DeviceVer); }
668
669     return DeviceName;
670 }
671