|
// MTerm1.cpp: 定义应用程序的类行为。
|
//
|
|
#include "pch.h"
|
#include "framework.h"
|
#include "afxwinappex.h"
|
#include "afxdialogex.h"
|
#include "MTerm1.h"
|
#include "MainFrm.h"
|
|
#include "ChildFrm.h"
|
#include "MTerm1Doc.h"
|
#include "MTerm1View.h"
|
#include "MTerm1LdsView.h"
|
#include "MTerm1BldView.h"
|
#include "MTerm1BnlView.h"
|
|
#include "MTerm1CoilView.h"
|
#include "MTerm1DataView.h"
|
|
#include "MTerm1TestView.h"
|
#include "MTerm1CtrlView.h"
|
#include "MTerm1ProgTxt.h"
|
|
|
|
#include "MTerm1CommDevView.h"
|
|
#ifdef _DEBUG
|
#define new DEBUG_NEW
|
#endif
|
|
#include <devguid.h>
|
#include <SetupAPI.h>
|
//#include "HvSerialPort.h"
|
//#include "CAnsiParser.h"
|
//#include "CDataParser1.h"
|
//#include "KLink.h"
|
|
#include <eh.h>
|
#include <dbghelp.h>
|
#pragma comment(lib,"dbghelp.lib")
|
#pragma comment(lib,"SetupAPI.lib")
|
#pragma comment(lib,"gdiplus.lib")
|
|
#include "../KLink1/KLink.h"
|
|
#pragma comment(lib,"KLink1.lib")
|
MHash MyCfg1;
|
Logger myLogger1;
|
MHash DeviceList;
|
|
// CMTerm1App
|
|
BEGIN_MESSAGE_MAP(CMTerm1App, CWinAppEx)
|
ON_COMMAND(ID_APP_ABOUT, &CMTerm1App::OnAppAbout)
|
// 基于文件的标准文档命令
|
// ON_COMMAND(ID_FILE_NEW, &CWinAppEx::OnFileNew)
|
ON_COMMAND(ID_FILE_NEW, &OnFileNew)
|
ON_COMMAND(ID_FILE_OPEN, &CWinAppEx::OnFileOpen)
|
// 标准打印设置命令
|
ON_COMMAND(ID_FILE_PRINT_SETUP, &CWinAppEx::OnFilePrintSetup)
|
// ON_COMMAND(ID_COMUNICATION_SET, &CMTerm1App::OnComunicationSet)
|
ON_COMMAND(ID_ENV_SET, &CMTerm1App::OnEnvSet)
|
END_MESSAGE_MAP()
|
|
|
// CMTerm1App 构造
|
|
CMTerm1App::CMTerm1App() noexcept
|
{
|
m_bHiColorIcons = TRUE;
|
// 支持重新启动管理器
|
m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_ALL_ASPECTS;
|
#ifdef _MANAGED
|
// 如果应用程序是利用公共语言运行时支持(/clr)构建的,则:
|
// 1) 必须有此附加设置,“重新启动管理器”支持才能正常工作。
|
// 2) 在您的项目中,您必须按照生成顺序向 System.Windows.Forms 添加引用。
|
System::Windows::Forms::Application::SetUnhandledExceptionMode(System::Windows::Forms::UnhandledExceptionMode::ThrowException);
|
#endif
|
|
// TODO: 将以下应用程序 ID 字符串替换为唯一的 ID 字符串;建议的字符串格式
|
//为 CompanyName.ProductName.SubProduct.VersionInformation
|
SetAppID(_T("MultiTerminal2.AppID.NoVersion"));
|
|
// TODO: 在此处添加构造代码,
|
// 将所有重要的初始化放置在 InitInstance 中
|
}
|
|
// 唯一的 CMTerm1App 对象
|
|
CMTerm1App theApp;
|
|
|
// CMTerm1App 初始化
|
|
BOOL CMTerm1App::InitInstance()
|
{
|
// 如果一个运行在 Windows XP 上的应用程序清单指定要
|
// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
|
//则需要 InitCommonControlsEx()。 否则,将无法创建窗口。
|
INITCOMMONCONTROLSEX InitCtrls;
|
InitCtrls.dwSize = sizeof(InitCtrls);
|
// 将它设置为包括所有要在应用程序中使用的
|
// 公共控件类。
|
InitCtrls.dwICC = ICC_WIN95_CLASSES;
|
InitCommonControlsEx(&InitCtrls);
|
|
CWinAppEx::InitInstance();
|
|
if (!AfxSocketInit())
|
{
|
AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
|
return FALSE;
|
}
|
|
// 初始化 OLE 库
|
if (!AfxOleInit())
|
{
|
AfxMessageBox(IDP_OLE_INIT_FAILED);
|
return FALSE;
|
}
|
|
AfxEnableControlContainer();
|
|
EnableTaskbarInteraction(FALSE);
|
|
// 使用 RichEdit 控件需要 AfxInitRichEdit2()
|
AfxInitRichEdit2();
|
|
// 标准初始化
|
// 如果未使用这些功能并希望减小
|
// 最终可执行文件的大小,则应移除下列
|
// 不需要的特定初始化例程
|
// 更改用于存储设置的注册表项
|
// TODO: 应适当修改该字符串,
|
// 例如修改为公司或组织名
|
SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
|
LoadStdProfileSettings(4); // 加载标准 INI 文件选项(包括 MRU)
|
|
DeviceList.LoadFromFile(_T("./DeviceList.Ini"));
|
// 注册应用程序的文档模板。 文档模板
|
// 将用作文档、框架窗口和视图之间的连接
|
// CMultiDocTemplate* pDocTemplate;
|
pDocTemplate = new CMultiDocTemplate(IDR_MTerm1TYPE,
|
RUNTIME_CLASS(CMTerm1Doc),
|
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
|
RUNTIME_CLASS(CMTerm1View));
|
if (!pDocTemplate)
|
return FALSE;
|
AddDocTemplate(pDocTemplate);
|
///*
|
// CMultiDocTemplate * m_pNewDocTemplate;
|
///*
|
m_pLdsViewTemplate = new CMultiDocTemplate(IDR_MTerm1TYPE,
|
RUNTIME_CLASS(CMTerm1Doc),
|
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
|
RUNTIME_CLASS(CMTerm1LdsView));
|
if (!m_pLdsViewTemplate)
|
return FALSE;
|
AddDocTemplate(m_pLdsViewTemplate);
|
|
m_pBldViewTemplate = new CMultiDocTemplate(IDR_MTerm1TYPE,
|
RUNTIME_CLASS(CMTerm1Doc),
|
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
|
RUNTIME_CLASS(CMTerm1BldView));
|
if (!m_pBldViewTemplate)
|
return FALSE;
|
AddDocTemplate(m_pBldViewTemplate);
|
|
m_pBnlViewTemplate = new CMultiDocTemplate(IDR_MTerm1TYPE,
|
RUNTIME_CLASS(CMTerm1Doc),
|
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
|
RUNTIME_CLASS(CMTerm1BnlView));
|
if (!m_pBnlViewTemplate)
|
return FALSE;
|
AddDocTemplate(m_pBnlViewTemplate);
|
/*
|
m_pCommDevViewTemplate = new CMultiDocTemplate(IDR_MTerm1TYPE,
|
RUNTIME_CLASS(CMTerm1Doc),
|
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
|
RUNTIME_CLASS(CMTerm1CommDevView));
|
if (!m_pCommDevViewTemplate)
|
return FALSE;
|
AddDocTemplate(m_pCommDevViewTemplate);
|
*/
|
/*
|
m_pCtrlViewTemplate = new CMultiDocTemplate(IDR_MTerm1TYPE,
|
RUNTIME_CLASS(CMTerm1Doc),
|
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
|
RUNTIME_CLASS(CMTerm1CtrlView));
|
if (!m_pCtrlViewTemplate)
|
return FALSE;
|
AddDocTemplate(m_pCtrlViewTemplate);
|
// */
|
/*
|
m_pProgViewTemplate = new CMultiDocTemplate(IDR_MTerm1TYPE,
|
RUNTIME_CLASS(CMTerm1Doc),
|
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
|
RUNTIME_CLASS(CMTerm1ProgTxt));
|
if (!m_pProgViewTemplate)
|
return FALSE;
|
AddDocTemplate(m_pProgViewTemplate);
|
*/
|
m_pCoilViewTemplate = new CMultiDocTemplate(IDR_MTerm1TYPE,
|
RUNTIME_CLASS(CMTerm1Doc),
|
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
|
RUNTIME_CLASS(CMTerm1CoilView));
|
if (!m_pCoilViewTemplate)
|
return FALSE;
|
AddDocTemplate(m_pCoilViewTemplate);
|
|
m_pDataViewTemplate = new CMultiDocTemplate(IDR_MTerm1TYPE,
|
RUNTIME_CLASS(CMTerm1Doc),
|
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
|
RUNTIME_CLASS(CMTerm1DataView));
|
if (!m_pDataViewTemplate)
|
return FALSE;
|
AddDocTemplate(m_pDataViewTemplate);
|
/*
|
m_pNewDocTemplate = new CMultiDocTemplate(IDR_MTerm1TYPE,
|
RUNTIME_CLASS(CMTerm1Doc),
|
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
|
RUNTIME_CLASS(CMTerm1TestView));
|
if (!m_pNewDocTemplate)
|
return FALSE;
|
AddDocTemplate(m_pNewDocTemplate);
|
|
//*/
|
// 创建主 MDI 框架窗口
|
CMainFrame* pMainFrame = new CMainFrame;
|
if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME))
|
{
|
delete pMainFrame;
|
return FALSE;
|
}
|
m_pMainWnd = pMainFrame;
|
|
|
// 分析标准 shell 命令、DDE、打开文件操作的命令行
|
CCommandLineInfo cmdInfo;
|
ParseCommandLine(cmdInfo);
|
|
if (cmdInfo.m_nShellCommand == CCommandLineInfo::FileNew)
|
cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;
|
|
// 调度在命令行中指定的命令。 如果
|
// 用 /RegServer、/Register、/Unregserver 或 /Unregister 启动应用程序,则返回 FALSE。
|
if (!ProcessShellCommand(cmdInfo))
|
return FALSE;
|
// 主窗口已初始化,因此显示它并对其进行更新
|
pMainFrame->ShowWindow(m_nCmdShow);
|
pMainFrame->UpdateWindow();
|
return TRUE;
|
}
|
|
int CMTerm1App::ExitInstance()
|
{
|
//TODO: 处理可能已添加的附加资源
|
AfxOleTerm(FALSE);
|
//this->CleanState();
|
|
return CWinAppEx::ExitInstance();
|
}
|
|
// CMTerm1App 消息处理程序
|
|
|
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
|
|
class CAboutDlg : public CDialogEx
|
{
|
public:
|
CAboutDlg() noexcept;
|
|
// 对话框数据
|
#ifdef AFX_DESIGN_TIME
|
enum { IDD = IDD_ABOUTBOX };
|
#endif
|
|
protected:
|
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
|
|
// 实现
|
protected:
|
DECLARE_MESSAGE_MAP()
|
};
|
|
CAboutDlg::CAboutDlg() noexcept : CDialogEx(IDD_ABOUTBOX)
|
{
|
}
|
|
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
|
{
|
CDialogEx::DoDataExchange(pDX);
|
}
|
|
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
|
END_MESSAGE_MAP()
|
|
// 用于运行对话框的应用程序命令
|
void CMTerm1App::OnAppAbout()
|
{
|
CAboutDlg aboutDlg;
|
aboutDlg.DoModal();
|
}
|
|
// CMTerm1App 消息处理程序
|
|
void CMTerm1App::OnFileNew()
|
{
|
// TODO: 在此添加命令处理程序代码
|
POSITION ps = m_pDocManager->GetFirstDocTemplatePosition();
|
CDocTemplate *pDocTemplate = m_pDocManager->GetNextDocTemplate(ps);
|
pDocTemplate->OpenDocumentFile(NULL);
|
}
|
|
|
|
void CMTerm1App::OnComunicationSet()
|
{
|
// TODO: 在此添加命令处理程序代码
|
}
|
|
|
void CMTerm1App::OnEnvSet()
|
{
|
// TODO: 在此添加命令处理程序代码
|
}
|
|
|
int SysLog(CString s, int channel)
|
{
|
myLogger1.LogTxt(s, channel);
|
return 1;
|
}
|
|
int DbgLog(CString s, int channel)
|
{
|
myLogger1.LogTxt(s, channel);
|
return 1;
|
}
|
|
int PopupMessage(CString Msg, int channel)
|
{
|
Msg.Trim(_T("\r\n"));
|
SysLog(_T("报警信息: ") + Msg + _T("\r\n"), channel);
|
return 0;
|
}
|
|
void DoEvents()
|
{
|
MSG msg;
|
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
{
|
DispatchMessage(&msg);
|
TranslateMessage(&msg);
|
}
|
}
|
|
void dump_callstack(PCONTEXT pcontext, CString & infostr)
|
{
|
#ifdef _WIN64
|
|
STACKFRAME64 sf;
|
memset(&sf, 0, sizeof(STACKFRAME64));
|
|
sf.AddrPC.Offset = pcontext->Rip;
|
//context->
|
sf.AddrPC.Mode = AddrModeFlat;
|
sf.AddrStack.Offset = pcontext->Rsp;
|
sf.AddrStack.Mode = AddrModeFlat;
|
sf.AddrFrame.Offset = pcontext->Rbp;
|
sf.AddrFrame.Mode = AddrModeFlat;
|
|
DWORD machineType = //IMAGE_FILE_MACHINE_I386;
|
IMAGE_FILE_MACHINE_AMD64;
|
#elif defined _WIN32
|
STACKFRAME sf;
|
memset(&sf, 0, sizeof(STACKFRAME));
|
|
sf.AddrPC.Offset = pcontext->Eip;
|
//context->
|
sf.AddrPC.Mode = AddrModeFlat;
|
sf.AddrStack.Offset = pcontext->Esp;
|
sf.AddrStack.Mode = AddrModeFlat;
|
sf.AddrFrame.Offset = pcontext->Ebp;
|
sf.AddrFrame.Mode = AddrModeFlat;
|
|
DWORD machineType = //IMAGE_FILE_MACHINE_I386;
|
IMAGE_FILE_MACHINE_AMD64;
|
#endif
|
HANDLE hProcess = GetCurrentProcess();
|
HANDLE hThread = GetCurrentThread();
|
|
for (;;)
|
{
|
if (!StackWalk(machineType, hProcess, hThread, &sf, pcontext, 0, SymFunctionTableAccess, SymGetModuleBase, 0))
|
{
|
break;
|
}
|
|
if (sf.AddrFrame.Offset == 0)
|
{
|
break;
|
}
|
BYTE symbolBuffer[sizeof(SYMBOL_INFO) + 1024];
|
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)symbolBuffer;
|
|
pSymbol->SizeOfStruct = sizeof(symbolBuffer);
|
pSymbol->MaxNameLen = 1024;
|
|
DWORD64 symDisplacement = 0;
|
if (SymFromAddr(hProcess, sf.AddrPC.Offset, 0, pSymbol))
|
{
|
printf("Function : %s\n", pSymbol->Name);
|
infostr.AppendFormat(_T("Function : %S \r\n"), pSymbol->Name);
|
}
|
else
|
{
|
printf("SymFromAdd failed!\n");
|
// infostr.AppendFormat(_T("SymFromAdd failed \r\n"),pSymbol->Name);
|
}
|
|
DWORD dwLineDisplacement;
|
#ifdef _WIN64
|
IMAGEHLP_LINEW64 lineInfoW = { sizeof(IMAGEHLP_LINEW64) };
|
if (SymGetLineFromAddrW(hProcess, sf.AddrPC.Offset, &dwLineDisplacement, &lineInfoW))
|
{
|
// printf( "[Source File : %s]\n", lineInfo.FileName );
|
// printf( "[Source Line : %u]\n", lineInfo.LineNumber );
|
CString s1(lineInfoW.FileName);
|
infostr.AppendFormat(_T("File %s Line %d\r\n"), s1.Mid(s1.ReverseFind(_T('\\')) + 1, 99), lineInfoW.LineNumber);
|
}
|
else
|
{
|
printf("SymGetLineFromAddr failed!\n");
|
// infostr.Append(_T("SymGetLineFromAddr failed!\r\n"));
|
}
|
#elif defined _WIN32
|
IMAGEHLP_LINE lineInfo = { sizeof(IMAGEHLP_LINE) };
|
if (SymGetLineFromAddr(hProcess, sf.AddrPC.Offset, &dwLineDisplacement, &lineInfo))
|
{
|
// printf( "[Source File : %s]\n", lineInfo.FileName );
|
// printf( "[Source Line : %u]\n", lineInfo.LineNumber );
|
CString s1(lineInfo.FileName);
|
infostr.AppendFormat(_T("File %s Line %d\r\n"), s1.Mid(s1.ReverseFind(_T('\\')) + 1, 99), lineInfo.LineNumber);
|
}
|
else
|
{
|
printf("SymGetLineFromAddr failed!\n");
|
// infostr.Append(_T("SymGetLineFromAddr failed!\r\n"));
|
}
|
#endif
|
|
}
|
}
|
DWORD excep_filter(LPEXCEPTION_POINTERS lpEP)
|
{
|
/**//// init dbghelp.dll
|
CString s1;
|
if (SymInitialize(GetCurrentProcess(), NULL, TRUE))
|
{
|
printf("Init dbghelp ok.\n");
|
}
|
|
dump_callstack(lpEP->ContextRecord, s1);
|
|
if (SymCleanup(GetCurrentProcess()))
|
{
|
printf("Cleanup dbghelp ok.\n");
|
}
|
|
return EXCEPTION_EXECUTE_HANDLER;
|
}
|
|
void Trans_Tunc(unsigned int n, EXCEPTION_POINTERS* pExp)
|
{
|
// pExp->ExceptionRecord.
|
// throw SE_Exception(n);
|
CString s1;
|
if (SymInitialize(GetCurrentProcess(), NULL, TRUE))
|
{
|
printf("Init dbghelp ok.\n");
|
// s1=_T("Init dbghelp ok.\r\n");
|
}
|
|
dump_callstack(pExp->ContextRecord, s1);
|
|
if (SymCleanup(GetCurrentProcess()))
|
{
|
printf("Cleanup dbghelp ok.\n");
|
// s1.Append(_T("Cleanup dbghelp ok.\n"));
|
}
|
throw SE_Exception(n, pExp->ExceptionRecord->ExceptionAddress, s1);
|
}
|
|
int DisplayException(CString File, int Line, CString Func, CString Sentence, SE_Exception &e)
|
{
|
CString Serror;
|
CString s1;
|
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());;
|
PopupMessage(s1);
|
return 0;
|
}
|
int DisplayException(CString File, int Line, CString Func, CString Sentence, CException *e)
|
{
|
CString Serror;
|
CString s1;
|
e->GetErrorMessage(Serror.GetBuffer(256), 256);
|
Serror.ReleaseBuffer();
|
s1.Format(_T("程序发生C++异常 %s 在File: %s Line: %d Func %s Sentence %s \r\n"), Serror, File, Line, Func, Sentence);
|
PopupMessage(s1);
|
return 0;
|
}
|
int DisplayException(CString File, int Line, CString Func, CString Sentence)
|
{
|
CString s1;
|
s1.Format(_T("程序发生未知错误 File: %s Line: %d Func %s Sentence %s \r\n"), File, Line, Func, Sentence);
|
PopupMessage(s1);
|
return 0;
|
}
|
|
|
int LoadMyConfig()
|
{
|
CString ConfigFilePathName;
|
ConfigFilePathName = _T("./Settings.ini");
|
int j = MyCfg1.LoadFromFile(ConfigFilePathName);
|
return j;
|
}
|
|
int SaveMyConfig()
|
{
|
CString ConfigFilePathName;
|
ConfigFilePathName = _T("./Settings.ini");
|
int j = MyCfg1.SaveToFile(ConfigFilePathName);
|
return j;
|
}
|
|
|
//得到COMx的名字
|
//namebuf:用于存放名字的缓冲区
|
//bufsize:缓冲区大小
|
//comx:要查找的COM编号.例如:COM1,COM2,COM3....
|
//返回值:0,成功找到了.
|
// 1,失败.
|
int get_com_name(CString comx, CString &namebuf)
|
{
|
HDEVINFO hdinfo;
|
int res = 0;
|
SP_DEVINFO_DATA hddevinfo = { sizeof(SP_DEVINFO_DATA) };
|
hdinfo = SetupDiGetClassDevs(&GUID_DEVCLASS_PORTS, 0, 0, DIGCF_PRESENT);//获取PORTS类别的已安装设备信息
|
if (hdinfo != INVALID_HANDLE_VALUE)//获取成功
|
{
|
for (int i = 0; SetupDiEnumDeviceInfo(hdinfo, i, &hddevinfo); i++)//轮询所有已安装设备
|
{
|
SetupDiGetDeviceRegistryProperty(hdinfo, &hddevinfo, SPDRP_FRIENDLYNAME, 0, (PBYTE)(namebuf.GetBuffer(2048)), 2048, 0);//获得单个装置的详细资料
|
namebuf.ReleaseBuffer();
|
if (namebuf.Find(comx) != -1) {
|
res = 1; break;
|
}
|
//char *t;
|
//t = strstr(namebuf, comx);
|
//if (t)
|
//{
|
// t--;
|
// *t = '\0';//添加结束符,作用就是把"(COMX)"这段字符去掉
|
// res = 0;
|
// break;//成功找到了COMx的名字
|
//}
|
}
|
}
|
return res;
|
}
|
|
CString intToString(int num, int digit)
|
{
|
static CString Str1;
|
if (digit != 0) {
|
CString str2;
|
str2.Format(_T("%%%dd"), digit);
|
Str1.Format(str2, num);
|
|
}else {
|
Str1.Format(_T("%d"), num);
|
}
|
|
int k = Str1.GetLength();
|
int j = (k - 1) / 3; //逗号个数
|
int l = k - j * 3; //起始位置
|
if (Str1[l-1] < '0' || Str1[l-1] > '9') { l += 3; j -= 1; }
|
for (int i = l; i < k + j; i += 4)
|
{
|
Str1.Insert(i, _T(","));
|
}
|
|
return Str1;
|
}
|
CString fixToString(int num, int digit, int fracdigit)
|
{
|
static CString Str1;
|
if (digit != 0) {
|
CString str2;
|
str2.Format(_T("%%%dd"), digit);
|
Str1.Format(str2, num);
|
|
}
|
else {
|
Str1.Format(_T("%d"), num);
|
}
|
|
int k = Str1.GetLength();
|
int j = (k - 1 - fracdigit) / 3; //逗号个数
|
int l = k - fracdigit - j * 3; //起始位置
|
for (int i = l; i < k -fracdigit + j; i += 4)
|
{
|
Str1.Insert(i, _T(","));
|
}
|
if (fracdigit>0) Str1.Insert(k - fracdigit + j, '.');
|
return Str1;
|
}
|
CString & intToBinString(int num, int digits)
|
{
|
static CString Str1;
|
Str1.Empty();
|
int mask = 1 << (digits - 1);
|
|
for (int i = 0; i < digits; i++)
|
{
|
if (num&mask) Str1.Append(_T("*"));
|
else Str1.Append(_T("."));
|
mask >>= 1;
|
}
|
return Str1;
|
}
|
|
CString DeviceTypeToStr(int DeviceTypeVer)
|
{
|
// TODO: 在此处添加实现代码.
|
|
static CString DeviceName;
|
DeviceName.Empty();
|
CString s1, s2;
|
UCHAR DeviceType, DeviceVer;
|
DeviceType = (DeviceTypeVer >> 8) & 0xff;
|
DeviceVer = DeviceTypeVer & 0xff;
|
s1.Format(_T("%02X"), DeviceType);
|
|
if (DeviceList["FAMILY"].Exist(s1))
|
{
|
DeviceName = DeviceList["FAMiLY"][s1];
|
s2.Format(_T("%02X"), DeviceVer);
|
Hash h1 = DeviceList[s1];
|
if (DeviceList[s1].Exist(s2))
|
{
|
DeviceName.Append(_T(", "));
|
DeviceName.Append(DeviceList[s1][s2]);
|
}
|
else
|
{
|
//DeviceName.Append(_T(", "));
|
DeviceName.AppendFormat(_T("(%02X)"), DeviceVer);
|
}
|
}
|
else { DeviceName.Format(_T("Device %02X(%02X)"), DeviceType, DeviceVer); }
|
|
return DeviceName;
|
}
|
|