23.网络游戏逆向分析与漏洞攻防-网络通信数据包分析工具-实现配置工具数据结构
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!
如果看不懂、不知道现在做的什么,那就跟着做完看效果
内容参考于:易道云信息技术研究院VIP课
上一个内容:22.加载配置文件到分析工具界面
码云地址(master 分支):https://gitee.com/dye_your_fingers/titan
码云版本号:1cd891b119c2c98906d566de0786a10d8f477b35
代码下载地址,在 titan 目录下,文件名为:titan-实现配置工具数据结构.zip
链接:https://pan.baidu.com/s/1W-JpUcGOWbSJmMdmtMzYZg
提取码:q9n5
--来自百度网盘超级会员V4的分享
HOOK引擎,文件名为:黑兔sdk升级版.zip
链接:https://pan.baidu.com/s/1IB-Zs6hi3yU8LC2f-8hIEw
提取码:78h8
--来自百度网盘超级会员V4的分享
以 22.加载配置文件到分析工具界面 它的代码为基础进行修改
现在通过之前的内容,配置文件读写搞好了,接下来就是把配置文件跟工具联系起来,所以就需要设计一个数据结构
添加类:
![]()
添加了两个类,MSG_DEC和DATA_DEC
![]()
上面说,创建了两个类,但是由于它们的重复引用导致编译不通过,然后就把DATA_DEC类型给删了
新加MSG_DEC.h
#pragma once
class DATA_DEC;
typedef class MSG_DEC // 消息定义列表里的数据
{
public:wchar_t txtName[0xFF];// 消息名称wchar_t txtDefine[0xFF]; // 宏定义int Type; // 类型bool IsTxt; // 是否写到文件DATA_DEC* Datas; // 数据定义列表里的数据// DataCount 是指的数据定义列表里的个数,也就是Datas它的个数,如果不懂就看使用的位置unsigned DataCount; ~MSG_DEC();
}*_PMSG;typedef class DATA_DEC // 数据定义列表的结构体
{
public:_PMSG Msg; // 消息类型int Id; // 编号列wchar_t Name[0xFF]; // 名称列COLORREF BackColor; // 背景颜色COLORREF FontColor; // 字体颜色bool IsUi; // 显示列bool IsTxt; // 输出列bool IsTxtAlone; // 单独输出列bool Used;
}*PDATA;
新加MSG_DEC.cpp
#include "pch.h"
#include "MSG_DEC.h"MSG_DEC::~MSG_DEC()
{if (Datas) delete[] Datas;
}
extern_all.cpp文件的修改:新加 DefConfigIni变量、MAX_MSG变量、_MsgPtr变量、TxtToType函数、TxtToBool函数、TxtToColor函数
#include "pch.h"
#include "extern_all.h"
CString AppPath; // 用来记录当前程序的目录
CString ConfigPath; // 用来记录当前程序配置文件的目录
CString DataPath; // 用来记录当前程序日志的目录unsigned MAX_MSG = 0; // 消息定义列表数据结构要搞成一个数组,这个是数组的大小
_PMSG _MsgPtr = nullptr; // 数组指针CString txtNameArys[3]{ L"数据包", L"文字-ASCII", L"文字-UTF-16" };CString DefConfigIni;// L"F:\\代码存放地\\c\\titan\\Release\\DataAnly\\Config"; // 默认加载路径void SetListView(CListCtrl* lst)
{auto lStyle = GetWindowLongPtr(lst->m_hWnd, GWL_STYLE); // 获取窗口样式lStyle |= LVS_REPORT; // 设置为报表模式SetWindowLongPtr(lst->m_hWnd, GWL_STYLE, lStyle);// 给窗口设置样式auto dStyle = lst->GetExtendedStyle(); // 获取扩展样式dStyle |= LVS_EX_FULLROWSELECT; // 设置选择时选择一行dStyle |= LVS_EX_GRIDLINES; // 画网格线lst->SetExtendedStyle(dStyle); // 设置扩展样式
}int TxtToType(CString txt) {for (int i = 0; i < 3; i++){if (txt == txtNameArys[i]) {return i;}}return -1;
}
bool TxtToBool(CString txt) {return txt == L"是";
}
COLORREF TxtToColor(CString txt) {return wcstol(txt, NULL, 16);
}
extern_all.h文件的修改:新加 DefConfigIni变量、MAX_MSG变量、_MsgPtr变量、TxtToType函数、TxtToBool函数、TxtToColor函数
#pragma once
#include "MSG_DEC.h"extern void SetListView(CListCtrl* lst);
extern CString AppPath; // 用来记录当前程序的目录
extern CString ConfigPath; // 用来记录当前程序配置文件的目录
extern CString DataPath; // 用来记录当前程序日志的目录extern unsigned MAX_MSG; // 消息定义列表数据结构要搞成一个数组,这个是数组的大小
extern _PMSG _MsgPtr; // 数组指针extern int TxtToType(CString txt);
extern bool TxtToBool(CString txt);
extern COLORREF TxtToColor(CString txt);extern CString DefConfigIni; // 默认加载路径
DataAnlyDlg.cpp文件的修改:新加 LoadConfig函数,修改了 OnBnClickedButton4函数(配置按钮点击事件处理函数)
// DataAnlyDlg.cpp: 实现文件
//#include "pch.h"
#include "framework.h"
#include "DataAnly.h"
#include "DataAnlyDlg.h"
#include "afxdialogex.h"
#include "extern_all.h"#ifdef _DEBUG
#define new DEBUG_NEW
#endif// 用于应用程序“关于”菜单项的 CAboutDlg 对话框class CAboutDlg : public CDialogEx
{
public:CAboutDlg();// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_ABOUTBOX };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持// 实现
protected:DECLARE_MESSAGE_MAP()
};CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);
}BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()// CDataAnlyDlg 对话框CDataAnlyDlg::CDataAnlyDlg(CWnd* pParent /*=nullptr*/): CDialogEx(IDD_DATAANLY_DIALOG, pParent), Pause(FALSE)
{m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}void CDataAnlyDlg::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);DDX_Control(pDX, IDC_LIST1, lstView);DDX_Check(pDX, IDC_CHECK1, Pause);
}BEGIN_MESSAGE_MAP(CDataAnlyDlg, CDialogEx)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDOK, &CDataAnlyDlg::OnBnClickedOk)ON_WM_COPYDATA()ON_BN_CLICKED(IDC_CHECK1, &CDataAnlyDlg::OnBnClickedCheck1)ON_BN_CLICKED(IDC_BUTTON1, &CDataAnlyDlg::OnBnClickedButton1)ON_BN_CLICKED(IDC_BUTTON4, &CDataAnlyDlg::OnBnClickedButton4)
END_MESSAGE_MAP()// CDataAnlyDlg 消息处理程序BOOL CDataAnlyDlg::OnInitDialog()
{CDialogEx::OnInitDialog();// 将“关于...”菜单项添加到系统菜单中。// IDM_ABOUTBOX 必须在系统命令范围内。ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != nullptr){BOOL bNameValid;CString strAboutMenu;bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);ASSERT(bNameValid);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}}// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动// 执行此操作SetIcon(m_hIcon, TRUE); // 设置大图标SetIcon(m_hIcon, FALSE); // 设置小图标// ShowWindow(SW_MAXIMIZE); // 设置最大号启动// TODO: 在此添加额外的初始化代码SetListView(&lstView);wchar_t buff[0xFF];/*获取当前程序名,这个名字是全路径,不只有程序名字(就是.exe文件的名字)它还可以获取别人的名字详细看微软的MSDN里的说明(百度搜索 “GetModuleFileName msdn” 关键字,就可以搜索出微软MSDN的说明)*/ GetModuleFileName(0, buff, sizeof(buff));int i;for (i = 0xFF - 1; buff[i] != L'\\'; i--);buff[++i] = 0;AppPath.Format(L"%s", buff);// AfxMessageBox(AppPath);ConfigPath = AppPath + L"Config\\";DataPath = AppPath + L"Datas\\";DefConfigIni = ConfigPath + L"titan.ini";LoadConfig(DefConfigIni);/*lstView.InsertColumn(0, L"消息类型", 0, 70);lstView.InsertColumn(1, L"数据类型", 0, 70);lstView.InsertColumn(2, L"内容", 0, 700);lstView.InsertColumn(3, L"长度", 0, 50);lstView.InsertColumn(4, L"时间", 0, 130);这几行代码意思是设置表头*/lstView.InsertColumn(0, L"消息类型", 0, 70);lstView.InsertColumn(1, L"数据类型", 0, 70);lstView.InsertColumn(2, L"内容", 0, 700);lstView.InsertColumn(3, L"长度", 0, 50);lstView.InsertColumn(4, L"时间", 0, 130);wndSet.Create(IDD_SET);return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}void CDataAnlyDlg::OnSysCommand(UINT nID, LPARAM lParam)
{if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialogEx::OnSysCommand(nID, lParam);}
}// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。void CDataAnlyDlg::OnPaint()
{if (IsIconic()){CPaintDC dc(this); // 用于绘制的设备上下文SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);// 使图标在工作区矩形中居中int cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;// 绘制图标dc.DrawIcon(x, y, m_hIcon);}else{CDialogEx::OnPaint();}
}//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CDataAnlyDlg::OnQueryDragIcon()
{return static_cast<HCURSOR>(m_hIcon);
}void CDataAnlyDlg::OnBnClickedOk()
{wchar_t buff[]{ L"我爱阿民" };COPYDATASTRUCT copydata{};/*这里的0表示字符串0具体是什么要看 WM_COPYDATA消息处理函数怎样写的*/copydata.dwData = 0;copydata.cbData = sizeof(buff);copydata.lpData = buff;SendMessage(WM_COPYDATA, 0, (LPARAM)©data);
}BOOL CDataAnlyDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* p)
{UpdateData(true);if (Pause)return CDialogEx::OnCopyData(pWnd, p);PCOPYDATA pdata = (PCOPYDATA)p->lpData;struct tm newtiem {};localtime_s(&newtiem, &pdata->ltime); // 获取时间int type = p->dwData;CString _result;CString _time;_time.Format(L"%.2d-%.2d-%.2d %.2d:%.2d:%.2d", newtiem.tm_year + 1900, newtiem.tm_mon, newtiem.tm_mday, newtiem.tm_hour, newtiem.tm_min, newtiem.tm_sec);if (MsgType[type]) {// 转换为buffunsigned char* buff = (unsigned char*)pdata->buff;CString _tmp;for (int i = 0; i < pdata->len;i++) {_tmp.Format(L"%.2X", buff[i]);_result = _result + L" " + _tmp;}}else {// 显示文本_result.Format(L"%s", pdata->buff);}lstView.InsertItem(0, MsgName[type]);lstView.SetItemText(0, 2, _result);lstView.SetItemText(0, 4, _time);CString wlen;wlen.Format(L"%d", pdata->len);lstView.SetItemText(0, 3, wlen);wlen.Format(L"%X", pdata->MsgType);lstView.SetItemText(0, 1, wlen);return CDialogEx::OnCopyData(pWnd, p);
}void CDataAnlyDlg::OnBnClickedCheck1()
{
}void CDataAnlyDlg::OnBnClickedButton1()
{lstView.DeleteAllItems();
}void CDataAnlyDlg::OnBnClickedButton4()
{wndSet.ShowWindow(TRUE);wndSet.LoadConfig(DefConfigIni, L"titan");
}void CDataAnlyDlg::LoadConfig(CString inifile) {/*从配置文件中读取一个数据,意思是从main下的count读取一个数字int类型的数字GetPrivateProfileInt用来获取.ini文件里的内容,最后的Int表示读取的数据类型Int就表示读取int类型,String表示读取String类型,也就是一个字符串GetPrivateProfileString(L"main", L"title", L"", buff, 0xFF, inifile);里的L""是默认值GetPrivateProfileInt(L"main", L"count", 0, inifile);里的0是默认值默认值的意思,如果读取不到数据就把默认值返回给我们*/int icount = GetPrivateProfileInt(L"main", L"count", 0, inifile);if (_MsgPtr) delete[] _MsgPtr;if (icount < 1) return;MAX_MSG = icount;_MsgPtr = new MSG_DEC[icount];wchar_t buff[0xFF];GetPrivateProfileString(L"main", L"title", L"", buff, 0xFF, inifile);this->SetWindowText(buff);/*CString App;CString AppData;CString _Name;它是用来初始化字符串的,利用 Foramt 函数把从.ini文件里获取的数据全部转成字符串*/CString App;CString AppData;CString _Name;for (int i = 0; i < icount; i++){App.Format(L"Message_%d", i);GetPrivateProfileString(App, L"name", L"", _MsgPtr[i].txtName, 0xFF, inifile);_Name.Format(L"%s", _MsgPtr[i].txtName);GetPrivateProfileString(App, L"define", L"", _MsgPtr[i].txtDefine, 0xFF, inifile);GetPrivateProfileString(App, L"type", L"", buff, 0xFF, inifile);_MsgPtr[i].Type = TxtToType(buff);GetPrivateProfileString(App, L"istxt", L"", buff, 0xFF, inifile);_MsgPtr[i].IsTxt = TxtToBool(buff);;int lcount = GetPrivateProfileInt(App, L"count", 0, inifile);_MsgPtr[i].Datas = new DATA_DEC[lcount];_MsgPtr[i].DataCount = lcount;for (int j = 0; j < lcount; j++){AppData.Format(L"%s_%d", _Name.GetBuffer(), j);DATA_DEC dataDec = _MsgPtr[i].Datas[j];dataDec.Msg = &(_MsgPtr[i]);GetPrivateProfileString(AppData, L"id", L"0", buff, 0xFF, inifile);dataDec.Id = _wtoi(buff);GetPrivateProfileString(AppData, L"name", L"0", dataDec.Name, 0xFF, inifile);GetPrivateProfileString(AppData, L"backcolor", L"0", buff, 0xFF, inifile);dataDec.BackColor = TxtToColor(buff);GetPrivateProfileString(AppData, L"fontcolor", L"0", buff, 0xFF, inifile);dataDec.FontColor = TxtToColor(buff);GetPrivateProfileString(AppData, L"isui", L"0", buff, 0xFF, inifile);dataDec.IsUi = TxtToBool(buff);GetPrivateProfileString(AppData, L"istxt", L"0", buff, 0xFF, inifile);dataDec.IsTxt = TxtToBool(buff);GetPrivateProfileString(AppData, L"istxtalone", L"0", buff, 0xFF, inifile);dataDec.IsTxtAlone = TxtToBool(buff);}}
}
DataAnlyDlg.h文件的修改:新加 LoadConfig函数,修改了 OnBnClickedButton4函数(配置按钮点击事件处理函数)
// DataAnlyDlg.h: 头文件
//#pragma once
#include "CSet.h"
#include "MSG_DEC.h"typedef struct COPY_DATA {time_t ltime; // 时间unsigned MsgType; // 数据类型unsigned len; // 数据长度char buff[0x2000]; // 数据
}*PCOPYDATA;// CDataAnlyDlg 对话框
class CDataAnlyDlg : public CDialogEx
{
// 构造
public:CDataAnlyDlg(CWnd* pParent = nullptr); // 标准构造函数// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_DATAANLY_DIALOG };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持// 实现
protected:HICON m_hIcon;// 生成的消息映射函数virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();DECLARE_MESSAGE_MAP()
public:CListCtrl lstView;afx_msg void OnBnClickedOk();afx_msg BOOL OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct);bool MsgType[5]{ // 意思看使用它的代码true, true, false, false, false};wchar_t MsgName[5][0xFF]{// 意思看使用它的代码L"发送",L"接收",L"发送解析",L"接收解析",L"日志"};/*0 发送数据1 接收数据2 发送数据解析3 接收数据解析4 日志*/BOOL Pause;afx_msg void OnBnClickedCheck1();afx_msg void OnBnClickedButton1();CSet wndSet;afx_msg void OnBnClickedButton4();void CDataAnlyDlg::LoadConfig(CString inifile);
};
CSet.h文件的修改:新加 LoadConfig函数
#pragma once
#include "CSetMsg.h"
#include "CSetData.h"// CSet 对话框class CSet : public CDialogEx
{DECLARE_DYNAMIC(CSet)public:CSet(CWnd* pParent = nullptr); // 标准构造函数virtual ~CSet();// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_SET };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 生成的消息映射函数virtual BOOL OnInitDialog();DECLARE_MESSAGE_MAP()
public:CListCtrl lstMsgType;CListCtrl lstDataType;afx_msg void OnBnClickedOk();afx_msg void OnBnClickedCancel();afx_msg void OnNMRClickList1(NMHDR* pNMHDR, LRESULT* pResult);afx_msg void OnNMRClickList2(NMHDR* pNMHDR, LRESULT* pResult);afx_msg void OnAddMsgType();
public:CSetMsg wndMsgSet;CSetData wndDataSet;CString txtBool[2]{ L"否", L"是" };int nMsgSel; // 消息定义列表选中行索引int nDataSel; // 数据定义列表选中行索引afx_msg void OnSetMsg(); // lstMsgType 添加数据afx_msg void OnDelMsg(); // lstMsgType 列表数据删除afx_msg void OnAddDataType(); // 选中 lstMsgType 列表里的一个数据,根据这个数据添加一个 lstDataType列表数据afx_msg void OnSetDataType(); // lstDataType 列表数据修改afx_msg void OnDelData(); // lstDataType 列表数据删除// 判断 lstMsgType 列表是否有重复的bool IsExitMsg(CString& _name);// 判断 lstDataType 列表里的内容是否有重复的bool IsExitData(CString& _name, CString& _id);// 判断 lstDataType 列表里的内容是否有重复的 修改里要排除自身所以才有的这个函数bool IsExitData(CString& _name, CString& _id, int index);CString txtName;CString txtTitle;afx_msg void OnClose();void LoadConfig(CString inifile, CString _name);
};
CSet.cpp文件的修改:新加 LoadConfig函数
// CSet.cpp: 实现文件
//#include "pch.h"
#include "DataAnly.h"
#include "CSet.h"
#include "afxdialogex.h"
#include "extern_all.h"// CSet 对话框IMPLEMENT_DYNAMIC(CSet, CDialogEx)CSet::CSet(CWnd* pParent /*=nullptr*/): CDialogEx(IDD_SET, pParent), txtName(_T("")), txtTitle(_T(""))
{}CSet::~CSet()
{
}void CSet::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);DDX_Control(pDX, IDC_LIST1, lstMsgType);DDX_Control(pDX, IDC_LIST2, lstDataType);DDX_Text(pDX, IDC_EDIT1, txtName);DDX_Text(pDX, IDC_EDIT2, txtTitle);
}BOOL CSet::OnInitDialog()
{CDialogEx::OnInitDialog();SetListView(&lstMsgType);SetListView(&lstDataType);lstMsgType.InsertColumn(0, L"名称", 0, 100);lstMsgType.InsertColumn(1, L"宏定义", 0, 100);lstMsgType.InsertColumn(2, L"类型", 0, 100); // 数据和文本,文本直接显示,数据有点复杂看之后实现位置lstMsgType.InsertColumn(3, L"输出到文件", 0, 100);lstDataType.InsertColumn(0, L"消息类型", 0, 100);lstDataType.InsertColumn(1, L"编号", 0, 100);lstDataType.InsertColumn(2, L"名称", 0, 100);lstDataType.InsertColumn(3, L"背景颜色", 0, 100);lstDataType.InsertColumn(4, L"字体颜色", 0, 100);lstDataType.InsertColumn(5, L"显示", 0, 100);lstDataType.InsertColumn(6, L"输出", 0, 100);lstDataType.InsertColumn(7, L"单独输出", 0, 100);return TRUE;
}BEGIN_MESSAGE_MAP(CSet, CDialogEx)ON_BN_CLICKED(IDOK, &CSet::OnBnClickedOk)ON_BN_CLICKED(IDCANCEL, &CSet::OnBnClickedCancel)ON_NOTIFY(NM_RCLICK, IDC_LIST1, &CSet::OnNMRClickList1)ON_NOTIFY(NM_RCLICK, IDC_LIST2, &CSet::OnNMRClickList2)ON_COMMAND(ID_32771, &CSet::OnAddMsgType)ON_COMMAND(ID_32772, &CSet::OnSetMsg)ON_COMMAND(ID_32773, &CSet::OnDelMsg)ON_COMMAND(ID_32777, &CSet::OnAddDataType)ON_COMMAND(ID_32775, &CSet::OnSetDataType)ON_COMMAND(ID_32776, &CSet::OnDelData)ON_WM_CLOSE()
END_MESSAGE_MAP()// CSet 消息处理程序// 保存按钮点击事件处理函数
void CSet::OnBnClickedOk()
{// TODO: 在此添加控件通知处理程序代码// CDialogEx::OnOK();UpdateData(TRUE);int icount = lstMsgType.GetItemCount();if (txtName == L"") {return;}CString inifile = ConfigPath + txtName + ".ini";CString txt;CString App;CString _Name;CString AppData;txt.Format(L"%d", icount);/*.ini是微软搞的配置文件(Windows系统配置文件所采用的结构(存储格式)).ini文件它有结构详细的结构看当前程序给生成的.ini文件内容WritePrivateProfileString是用来给.ini文件写数据的WritePrivateProfileString它是给.ini文件写一个字符串*/WritePrivateProfileString(L"main", L"count", txt, inifile);WritePrivateProfileString(L"main", L"title", txtTitle, inifile);for (int i = 0; i < icount; i++){_Name = lstMsgType.GetItemText(i, 0);App.Format(L"Message_%d", i);// 消息定义列表的名称列的内容WritePrivateProfileString(App, L"name", _Name, inifile);// 消息定义列表的宏定义列的内容WritePrivateProfileString(App, L"define", lstMsgType.GetItemText(i, 1), inifile);// 消息定义列表的类型列的内容WritePrivateProfileString(App, L"type", lstMsgType.GetItemText(i, 2), inifile);// 消息定义列表的输出到文件列的内容WritePrivateProfileString(App, L"istxt", lstMsgType.GetItemText(i, 3), inifile);int datacount = 0;for (int j = 0; j < lstDataType.GetItemCount(); j++){if (lstDataType.GetItemText(j, 0) == _Name) {AppData.Format(L"%s_%d", _Name, datacount++);// 数据定义列表的编号列的内容 WritePrivateProfileString(AppData, L"id", lstDataType.GetItemText(j,1), inifile);// 数据定义列表的名称列的内容 WritePrivateProfileString(AppData, L"name", lstDataType.GetItemText(j,2), inifile);// 数据定义列表的背景颜色列的内容 WritePrivateProfileString(AppData, L"backcolor", lstDataType.GetItemText(j,3), inifile);// 数据定义列表的字体颜色列的内容 WritePrivateProfileString(AppData, L"fontcolor", lstDataType.GetItemText(j,4), inifile);// 数据定义列表的显示列的内容 WritePrivateProfileString(AppData, L"isui", lstDataType.GetItemText(j,5), inifile);// 数据定义列表的输出列的内容 WritePrivateProfileString(AppData, L"istxt", lstDataType.GetItemText(j,6), inifile);// 数据定义列表的单独输出列的内容 WritePrivateProfileString(AppData, L"istxtalone", lstDataType.GetItemText(j,7), inifile);}}txt.Format(L"%d", datacount);WritePrivateProfileString(App, L"count", txt, inifile);}
}void CSet::OnBnClickedCancel()
{// CDialogEx::OnCancel();// 声明一个文件选择对话框里的筛选TCHAR szFilters[] = _T("数据分析配置(*.ini)|*.ini||");// 创建一个文件选择对话框CFileDialog dialog(TRUE, NULL, NULL, 6, szFilters);// 设置文件选择对话框打开之后默认地址dialog.m_ofn.lpstrInitialDir = ConfigPath;if (dialog.DoModal() == IDOK) {// 获取选择的文件的目录,获取的是绝对路径CString inifile = dialog.GetPathName();LoadConfig(inifile, dialog.GetFileTitle());}
}void CSet::OnNMRClickList1(NMHDR* pNMHDR, LRESULT* pResult)
{LPNMITEMACTIVATE p = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);// TODO: 在此添加控件通知处理程序代码*pResult = 0;nMsgSel = p->iItem;/*GetMessagePos函数可以,获取光标位置返回值低16位是x,高16位是y*/DWORD dwPos = GetMessagePos();CPoint point(LOWORD(dwPos), HIWORD(dwPos));CMenu menu;menu.LoadMenuW(IDR_MENU1);// 根据菜单窗口id获取一个菜单窗口对象CMenu* pop = menu.GetSubMenu(0);// 获取第一个菜单,也就是现在的消息设置这个菜单// 在指定位置显示浮动弹出菜单,并跟踪弹出菜单上项的选择情况。pop->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON, point.x, point.y, this);
}void CSet::OnNMRClickList2(NMHDR* pNMHDR, LRESULT* pResult)
{LPNMITEMACTIVATE p = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);// TODO: 在此添加控件通知处理程序代码*pResult = 0;nDataSel = p->iItem;/*GetMessagePos函数可以,获取光标位置返回值低16位是x,高16位是y
*/DWORD dwPos = GetMessagePos();CPoint point(LOWORD(dwPos), HIWORD(dwPos));CMenu menu;menu.LoadMenuW(IDR_MENU1);// 根据菜单窗口id获取一个菜单窗口对象CMenu* pop = menu.GetSubMenu(1);// 获取第一个菜单,也就是现在的消息设置这个菜单// 在指定位置显示浮动弹出菜单,并跟踪弹出菜单上项的选择情况。pop->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
}void CSet::OnAddMsgType()
{if (wndMsgSet.DoModal() == IDOK) {int icount = lstMsgType.GetItemCount();for (int i = 0; i < icount; i++){if (lstMsgType.GetItemText(i, 0) == wndMsgSet.txtName) {AfxMessageBox(L"消息名已存在!");return;}if (lstMsgType.GetItemText(i, 1) == wndMsgSet.txtDefine) {AfxMessageBox(L"宏定义已存在!");return;}}lstMsgType.InsertItem(icount, wndMsgSet.txtName);lstMsgType.SetItemText(icount, 1, wndMsgSet.txtDefine);lstMsgType.SetItemText(icount, 2, wndMsgSet.txtTypeName);lstMsgType.SetItemText(icount, 3, txtBool[wndMsgSet.IsTxt]);}
}void CSet::OnSetMsg()
{if (nMsgSel > -1) {wndMsgSet.SetDatas(lstMsgType.GetItemText(nMsgSel, 0), lstMsgType.GetItemText(nMsgSel, 1), lstMsgType.GetItemText(nMsgSel, 2), lstMsgType.GetItemText(nMsgSel, 3)==L"是");if (wndMsgSet.DoModal() == IDOK) {int icount = lstMsgType.GetItemCount();for (int i = 0; i < icount; i++){if (lstMsgType.GetItemText(i, 0) == wndMsgSet.txtName) {if (i != nMsgSel) {AfxMessageBox(L"消息名已存在!");return;}}if (lstMsgType.GetItemText(i, 1) == wndMsgSet.txtDefine) {if (i != nMsgSel) {AfxMessageBox(L"宏定义已存在!");return;}}}lstMsgType.SetItemText(nMsgSel, 0, wndMsgSet.txtName);lstMsgType.SetItemText(nMsgSel, 1, wndMsgSet.txtDefine);lstMsgType.SetItemText(nMsgSel, 2, wndMsgSet.txtTypeName);lstMsgType.SetItemText(nMsgSel, 3, txtBool[wndMsgSet.IsTxt]);}}
}void CSet::OnDelMsg()
{if (nMsgSel > -1) {lstMsgType.DeleteItem(nMsgSel);}
}void CSet::OnAddDataType()
{if (nMsgSel > -1) {// 给消息数据窗口里消息名称输入框赋值wndDataSet.txtName = lstMsgType.GetItemText(nMsgSel, 0);if (wndDataSet.DoModal() == IDOK) {if (!IsExitMsg(wndDataSet.txtName)) {AfxMessageBox(L"消息不存在,可能已经被删除!");return;}if (IsExitData(wndDataSet.txtName, wndDataSet.txtId)) {AfxMessageBox(L"消息对应的数据编号已经存在!");return;}int icount = lstDataType.GetItemCount();lstDataType.InsertItem(icount, wndDataSet.txtName);lstDataType.SetItemText(icount,1, wndDataSet.txtId);lstDataType.SetItemText(icount,2, wndDataSet.txtDataName);lstDataType.SetItemText(icount,3, wndDataSet.txtBackColor);lstDataType.SetItemText(icount,4, wndDataSet.txtFontColor);lstDataType.SetItemText(icount,5, txtBool[wndDataSet.IsShowUI]);lstDataType.SetItemText(icount,6, txtBool[wndDataSet.IsTxt]);lstDataType.SetItemText(icount,7, txtBool[wndDataSet.IsTxtAlone]);}}
}void CSet::OnSetDataType()
{if (nDataSel > -1) {wndDataSet.txtName = lstDataType.GetItemText(nDataSel, 0),wndDataSet.txtId = lstDataType.GetItemText(nDataSel, 1),wndDataSet.txtDataName = lstDataType.GetItemText(nDataSel, 2),wndDataSet.txtBackColor = lstDataType.GetItemText(nDataSel, 3),wndDataSet.txtFontColor = lstDataType.GetItemText(nDataSel, 4),wndDataSet.IsShowUI = lstDataType.GetItemText(nDataSel, 5) == L"是";wndDataSet.IsTxt = lstDataType.GetItemText(nDataSel, 6) == L"是";wndDataSet.IsTxtAlone = lstDataType.GetItemText(nDataSel, 7) == L"是";if (wndDataSet.DoModal() == IDOK) {int icount = nDataSel;if (!IsExitMsg(wndDataSet.txtName)) {AfxMessageBox(L"消息不存在,可能已经被删除!");lstDataType.DeleteItem(nDataSel);return;}if (IsExitData(wndDataSet.txtName, wndDataSet.txtId, icount)) {AfxMessageBox(L"消息对应的数据编号已经存在!");return;}lstDataType.SetItemText(icount, 0, wndDataSet.txtName);lstDataType.SetItemText(icount, 1, wndDataSet.txtId);lstDataType.SetItemText(icount, 2, wndDataSet.txtDataName);lstDataType.SetItemText(icount, 3, wndDataSet.txtBackColor);lstDataType.SetItemText(icount, 4, wndDataSet.txtFontColor);lstDataType.SetItemText(icount, 5, txtBool[wndDataSet.IsShowUI]);lstDataType.SetItemText(icount, 6, txtBool[wndDataSet.IsTxt]);lstDataType.SetItemText(icount, 7, txtBool[wndDataSet.IsTxtAlone]);}}
}void CSet::OnDelData()
{if (nDataSel > -1) {lstDataType.DeleteItem(nDataSel);}
}bool CSet::IsExitMsg(CString& _name)
{for (int i = 0; i < lstMsgType.GetItemCount(); i++){if (lstMsgType.GetItemText(i, 0) == _name) {return true;}}return false;
}bool CSet::IsExitData(CString& _name, CString& _id)
{for (int i = 0; i < lstDataType.GetItemCount(); i++){if ((lstDataType.GetItemText(i, 0) == _name)&&(lstDataType.GetItemText(i, 1) == _id)) {return true;}}return false;
}bool CSet::IsExitData(CString& _name, CString& _id, int index)
{for (int i = 0; i < lstDataType.GetItemCount(); i++){if ((lstDataType.GetItemText(i, 0) == _name) && (lstDataType.GetItemText(i, 1) == _id)&&(index != i)) {return true;}}return false;
}void CSet::OnClose()
{// TODO: 在此添加消息处理程序代码和/或调用默认值CDialogEx::OnCancel();
}void CSet::LoadConfig(CString inifile, CString _name)
{lstDataType.DeleteAllItems(); // 清空数据定义列表lstMsgType.DeleteAllItems(); // 清空消息定义列表// 获取选择的文件的文件名txtName = _name;/*从配置文件中读取一个数据,意思是从main下的count读取一个数字int类型的数字GetPrivateProfileInt用来获取.ini文件里的内容,最后的Int表示读取的数据类型Int就表示读取int类型,String表示读取String类型,也就是一个字符串GetPrivateProfileString(L"main", L"title", L"", buff, 0xFF, inifile);里的L""是默认值GetPrivateProfileInt(L"main", L"count", 0, inifile);里的0是默认值默认值的意思,如果读取不到数据就把默认值返回给我们*/int icount = GetPrivateProfileInt(L"main", L"count", 0, inifile);wchar_t buff[0xFF];GetPrivateProfileString(L"main", L"title", L"", buff, 0xFF, inifile);txtTitle = buff;/*CString App;CString AppData;CString _Name;它是用来初始化字符串的,利用 Foramt 函数把从.ini文件里获取的数据全部转成字符串*/CString App;CString AppData;CString _Name;for (int i = 0; i < icount; i++){App.Format(L"Message_%d", i);GetPrivateProfileString(App, L"name", L"", buff, 0xFF, inifile);_Name.Format(L"%s", buff);lstMsgType.InsertItem(i, buff);GetPrivateProfileString(App, L"define", L"", buff, 0xFF, inifile);lstMsgType.SetItemText(i, 1, buff);GetPrivateProfileString(App, L"type", L"", buff, 0xFF, inifile);lstMsgType.SetItemText(i, 2, buff);GetPrivateProfileString(App, L"istxt", L"", buff, 0xFF, inifile);lstMsgType.SetItemText(i, 3, buff);int lcount = GetPrivateProfileInt(App, L"count", 0, inifile);int datacount = lstDataType.GetItemCount();for (int j = 0; j < lcount; j++){AppData.Format(L"%s_%d", _Name.GetBuffer(), j);lstDataType.InsertItem(datacount, _Name);GetPrivateProfileString(AppData, L"id", L"0", buff, 0xFF, inifile);lstDataType.SetItemText(datacount, 1, buff);GetPrivateProfileString(AppData, L"name", L"0", buff, 0xFF, inifile);lstDataType.SetItemText(datacount, 2, buff);GetPrivateProfileString(AppData, L"backcolor", L"0", buff, 0xFF, inifile);lstDataType.SetItemText(datacount, 3, buff);GetPrivateProfileString(AppData, L"fontcolor", L"0", buff, 0xFF, inifile);lstDataType.SetItemText(datacount, 4, buff);GetPrivateProfileString(AppData, L"isui", L"0", buff, 0xFF, inifile);lstDataType.SetItemText(datacount, 5, buff);GetPrivateProfileString(AppData, L"istxt", L"0", buff, 0xFF, inifile);lstDataType.SetItemText(datacount, 6, buff);GetPrivateProfileString(AppData, L"istxtalone", L"0", buff, 0xFF, inifile);lstDataType.SetItemText(datacount, 7, buff);}}UpdateData(FALSE);
}
相关文章:

23.网络游戏逆向分析与漏洞攻防-网络通信数据包分析工具-实现配置工具数据结构
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 如果看不懂、不知道现在做的什么,那就跟着做完看效果 内容参考于:易道云信息技术研究院VIP课 上一个内容:22.加载配置文件…...

STM32CubeMX学习笔记20——SD卡FATFS文件系统
1. FATFS文件系统简介 文件系统是操作系统用于明确存储设备或分区上的文件的方法和数据结构(即在存储设备上组织文件的方法)。操作系统中负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统;不带文件系统的SD卡仅能…...

Facebook商城号为什么被封?如何防封?
由于Facebook商城的高利润空间,越来越多的跨境电商商家注意到它的存在。Facebook作为全球最大、用户量最大的社媒平台,同时也孕育了一个巨大的商业生态,包括广告投放、商城交易等。依托背后的大流量,Facebook商城起号较快…...

【教程】APP备案全攻略:确保你的应用合规上线
【教程】APP备案全攻略:确保你的应用合规上线 摘要 本文详细介绍了中国大陆地区互联网信息服务提供者(AP)进行APP备案的流程、要求和注意事项。包括备案对象、备案方式、备案内容、备案流程等方面的详细说明,帮助开发者顺利完成…...
Vue入门2
v-model 原理:v-model本质上是一个语法糖。例如应用于输入框,就是value属性和input事件的合写。 作用:提供数据的双向绑定 数据变,视图跟着变 :value视图变,数据跟着变 input 注意:$event用于在模板中&…...

简介:CMMI软件能力成熟度集成模型
前言 CMMI是英文Capability Maturity Model Integration的缩写。 CMMI认证简称软件能力成熟度集成模型,是鉴定企业在开发流程化和质量管理上的国际通行标准,全球软件生产标准大都以此为基点,并都努力争取成为CMMI认证队伍中的一分子。 对一个…...
mysql的其他问题
1.MySQL数据库作发布系统的存储,一天五万条以上的增量,预计运维三年,怎么优化? a. 设计良好的数据库结构,允许部分数据冗余,尽量避免join查询,提高效率。 b. 选择合适的表字段数据类型和存储引擎…...

数据结构---复杂度(2)
1.斐波那契数列的时间复杂度问题 每一行分别是2^0---2^1---2^2-----2^3-------------------------------------------2^(n-2) 利用错位相减法,可以得到结果是,2^(n-1)-1,其实还是要减去右下角的灰色部分,我们可以拿简单的数字进行举例子&…...
【设计模式】设计原则和常见的23种经典设计模式
设计模式 1. 设计原则(记忆口诀:SOLID)【记忆口诀:单开里依接迪合(单开礼仪接地和)】 (1)单一职责原则(Single Responsibility Principle, SRP) ÿ…...

Spring Cloud Gateway自定义断言
问题:Spring Cloud Gateway自带的断言(Predicate)不满足业务怎么办?可以自定义断言! 先看Spring Cloud Gateway是如何实现断言的 Gateway中断言的整体架构如下: public abstract class AbstractRoutePred…...

智能测径仪在胶管行业的应用
关键字:胶管外径尺寸测量,胶管检测仪器,胶管外径检测,高温胶管外径检测,软硬胶管检测, 智能测径仪在家胶管行业中的应用主要体现在对胶管外径的精确测量和控制上。在胶管生产过程中,外径的大小直…...

vue自定义主题皮肤方案
方案一:CSS变量换肤(推荐) 利用css定义变量的方法,用var在全局定义颜色变量(需将变量提升到全局即伪类选择器 :root)然后利用js操作css变量,document.getElementsByTagName(‘body’)[0].style…...
iOS中使用schema协议调用APP和使用iframe打开APP的例子
大家好我是咕噜美乐蒂,很高兴又和大家见面了! 当调用自定义 URL scheme 或使用 iframe 打开应用程序时,可以采取以下详细步骤: 使用自定义 URL scheme 协议调用应用程序 1.首先,确认目标应用程序已经注册了自定义 U…...

2024.3.11
提示并输入一个字符串,统计该字符中大写、小写字母个数、数字个数、空格个数以及其他字符个数 #include <iostream> #include<string> using namespace std;int main() {cout << "please input a string:" << endl;string str;g…...
Web服务器需要警惕的一些安全隐患
Web服务器需要警惕的一些安全隐患有哪些,今天德迅云安全就带您来了解下。熟悉了解了就知道怎么规避风险。不过无论是什么漏洞,都体现着安全是一个整体的真理,考虑Web服务器的安全性,必须要考虑到与之相配合的操作系统。 1.物理路径…...

MinGW-w64的下载与安装
文章目录 1 下载2 安装3 配置环境变量4 验证 1 下载 官网地址:https://www.mingw-w64.org/github地址:https://github.com/niXman/mingw-builds-binaries/releases windows下载 跳转github下载 版本号选择:13.2.0是GCC的版本号;…...
docker使用笔记
查看本机上所有镜像 docker images打包项目(打包完成后自动载入镜像) The command docker build -t search-server . you provided is a standard way to build a Docker image. The -t flag tags the resulting image, and search-server is the tag …...

新规正式发布 | 百度深度参编《生成式人工智能服务安全基本要求》
2024年2月29日,全国网络安全标准化技术委员会( TC260 )正式发布《生成式人工智能服务安全基本要求》(以下简称《基本要求》)。《基本要求》规定了生成式人工智能服务在安全方面的基本要求,包括语料安全、模…...
2024年AI辅助研发的趋势和影响
摘要:随着人工智能技术的迅猛发展,2024年AI辅助研发正成为科技界和工业界的瞩目焦点。本文将探讨AI辅助研发在各个领域的应用和影响,并展望2024年AI辅助研发的趋势。 引言 随着人工智能技术的不断进步,AI辅助研发正逐渐渗透到各…...
2k_Day1:今天是设计模式的大白话1
大白话: 原则有一点很难做到,就是定义好的类,只能加不能改(开放-关闭原则) 1.工厂模式就是,比如你定了一个汽车接口,然后小车、中车、大车都继承这个接口,这时,定一个汽…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...

【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...

Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...