网站缩略图尺寸,热血传奇,外贸网站建设信息,开发公司网签房信息免责声明#xff1a;内容仅供学习参考#xff0c;请合法利用知识#xff0c;禁止进行违法犯罪活动#xff01;
如果看不懂、不知道现在做的什么#xff0c;那就跟着做完看效果
内容参考于#xff1a;易道云信息技术研究院VIP课
上一个内容#xff1a;28.数据推测结果…免责声明内容仅供学习参考请合法利用知识禁止进行违法犯罪活动
如果看不懂、不知道现在做的什么那就跟着做完看效果
内容参考于易道云信息技术研究院VIP课
上一个内容28.数据推测结果用提示框的形式显示
码云地址master 分支https://gitee.com/dye_your_fingers/titan
码云版本号1e568175a741f03990b7df078aa6e2bc138bfb2d
代码下载地址在 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的分享 以 28.数据推测结果用提示框的形式显示它的代码为基础进行修改
效果图 CWndData.h文件的修改新加 TimeToTxt函数
#pragma once// CWndData 对话框class CWndData : public CDialogEx
{DECLARE_DYNAMIC(CWndData)public:CWndData(CWnd* pParent nullptr); // 标准构造函数virtual ~CWndData();// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD IDD_DIALOG1 };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持DECLARE_MESSAGE_MAP()
public:CEdit m_Edit;HWND hTips{};virtual BOOL OnInitDialog();void loops(HWND, UINT, CWndData* _this, DWORD);void ShowTips();CString lastTxt;CString TimeToTxt(time_t* _tm);// 事件类型转字符串
};CWndData.cpp文件的修改新加 TimeToTxt函数修改了 ShowTips函数tips变量声明位置
// CWndData.cpp: 实现文件
//#include pch.h
#include DataAnly.h
#include CWndData.h
#include afxdialogex.h// CWndData 对话框IMPLEMENT_DYNAMIC(CWndData, CDialogEx)CWndData::CWndData(CWnd* pParent /*nullptr*/): CDialogEx(IDD_DIALOG1, pParent)
{}CWndData::~CWndData()
{
}void CWndData::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);DDX_Control(pDX, IDC_EDIT1, m_Edit);
}BOOL CWndData::OnInitDialog()
{/*为了处理数据方便我要给定时器一个成员函数然后成员函数它不满足 TIMERPROC 这个类型编译器也不让我们强制转换所以要用一个联合体封装一下联合体里的变量都共用一个内存内存大小由联合体里最大的变量决定*/union {TIMERPROC _address;void (CWndData::* _classProc)(HWND, UINT, CWndData*, DWORD);}v;v._classProc CWndData::loops;CDialogEx::OnInitDialog();//hTips 0;/*定时器执行的函数stdcall让它调用的函数是类的成员函数定时器调用的时候可能不会有this也就是ecx的值不是类对象地址所以这里要手动的把this传递过去这样可以方便在函数里对数据进行操作*/ ::SetTimer(m_hWnd, (UINT_PTR)this, 100, v._address);return TRUE;
}void CWndData::loops(HWND, UINT, CWndData* _this, DWORD)
{int nstart 0;// 选中的内容起始下标int nend 0; // 选中的内容结束下标_this-m_Edit.GetSel(nstart, nend); // 获取选中的文字int ncount nend - nstart;if (ncount 1) {CString txt;CString tmp;_this-m_Edit.GetWindowText(txt); // 获取编辑框里的内容tmp txt.Mid(nstart, ncount);tmp.Replace(L , L); // 把空格替换成空字符if (_this-lastTxt ! tmp) {int lenth tmp.GetLength();if (lenth % 2 0) { // 必须是2的倍数如果不是就说明没有选择全_this-lastTxt tmp;_this-ShowTips();}}}
}TOOLINFO tips; // 提示框结构体void CWndData::ShowTips()
{tips.cbSize sizeof(tips);// 固定写法也就是必须这样写必须有这一句unsigned char ExDataBuff[0x1000]{};int ilenth lastTxt.GetLength() / 2; // 字符串是用2字节显示一个内容if (ilenth0) {}CString tmp;for (int i 0; i ilenth; i) {tmp lastTxt.Mid(i*2, 2);// 这里的Mid函数的意思是从i*2下标位置往后取2个字符// wcstol函数降字符串转成long类型这里将字符转成16进制的long类型ExDataBuff[i] (unsigned char)wcstol(tmp, NULL, 16);}wchar_t* wBuff (wchar_t*)ExDataBuff;CStringA Buff (char*)ExDataBuff;time_t* _time;long long* llRead;double* dbRead;int* ntRead;float* fRead;short* stRead;CString txtUnicode, txtAscii,txttm, txtll, txtdb, txtnt, txtfloat, txtst,tmpR;txtUnicode.Format(L%s, wBuff);txtAscii Buff;// tmp.Format(L\r\nUTF16:%s\r\nAscII:%s, wBuff, aBuff.GetBuffer());for (INT i 0; i ilenth; i){// 推测8字节数据if ((ilenth - i 7)(i%80)) {llRead (long long*)ExDataBuff[i];dbRead (double*)ExDataBuff[i];_time (time_t*)ExDataBuff[i];tmpR.Format(L[%i64d], llRead[0]);txtll tmpR;tmpR.Format(L[%1f], dbRead[0]);txtdb tmpR;tmpR.Format(L[%s], TimeToTxt(_time));txttm tmpR;}// 推测4字节数据if ((ilenth - i 3) (i % 4 0)) {fRead (float*)ExDataBuff[i];ntRead (int*)ExDataBuff[i];tmpR.Format(L[%d], ntRead[0]);txtnt tmpR;tmpR.Format(L[%f], fRead[0]);txtfloat tmpR;}// 推测2字节数据if ((ilenth - i 1) (i % 2 0)) {stRead (short*)ExDataBuff[i];tmpR.Format(L[%d], stRead[0]);txtst tmpR;}}if (txttm ! )tmp tmp L\r\n[time] txttm;if (txtll ! )tmp tmp L\r\n[int64] txtll;if (txtdb ! )tmp tmp L\r\n[double] txtdb;if (txtfloat ! )tmp tmp L\r\n[float] txtfloat;if (txtnt ! )tmp tmp L\r\n[int] txtnt;if (txtst ! )tmp tmp L\r\n[short] txtst;tmp L;int imax txtUnicode.GetLength();if (imax 0) {tmp tmp L\r\n[Utf16]: txtUnicode;imax 8;}int icount txtAscii.GetLength();if (icount 0) {tmp tmp L\r\n[Ascii]: txtAscii;icount 8;if (icount imax) {imax icount;}}icount txttm.GetLength();if (icount 0) {tmp tmp L\r\n[time]: txttm;icount 7;if (icount imax) {imax icount;}}icount txtll.GetLength();if (icount 0) {tmp tmp L\r\n[int64]: txtll;icount 8;if (icount imax) {imax icount;}}icount txtdb.GetLength();if (icount 0) {tmp tmp L\r\n[double]: txtdb;icount 9;if (icount imax) {imax icount;}}icount txtfloat.GetLength();if (icount 0) {tmp tmp L\r\n[float]: txtfloat;icount 8;if (icount imax) {imax icount;}}icount txtnt.GetLength();if (icount 0) {tmp tmp L\r\n[int]: txtnt;icount 6;if (icount imax) {imax icount;}}icount txtst.GetLength();if (icount 0) {tmp tmp L\r\n[short]: txtst;icount 8;if (icount imax) {imax icount;}}CString _head(, imax);_head _head tmp;tips.lpszText _head.GetBuffer();// 设置提示框的内容DWORD lPoint GetMessagePos();// 获取鼠标位置GetMessagePos函数返回值是一个DWORD类型高位是x坐标低位是y坐标if (!hTips) {/*CreateWindow函数的参数说明第一个参数是窗口注册的类名是一个字符串现在写的 TOOLTIPS_CLASS 是一个提示框的类名由Windows提供的公共控件由Windows对它们进行 RegisterClass 或 RegisterClassEx操作所以这里可以直接执行CreateWindow操作第二个参数是窗口名称就是窗口左上角的文字由于是提示框用来显示描述的提示框所以写的NULL第三个参数是正在创建的窗口的样式详情看MSDNMSDN是微软文档去MSDN里搜索 CreateWindowW或者CreateWindowA第四个参数是窗口初始水平位置也就是x坐标第五个参数是窗口垂直位置也就是y坐标第六个参数是窗口的宽度第七个参数是窗口的高度第八个参数是所创建的窗口的父窗口或所有者窗口的句柄也就是用来给它指定父窗口第九个参数菜单的句柄没有菜单所以写0第十个参数是要与窗口关联的模块实例的句柄这里传递的是AfxGetInstanceHandle函数它会返回当前程序的句柄第十一个参数是给窗口传递的数据是一个结构体详情去MSDN看返回值是创建好的窗口句柄*/hTips CreateWindow(TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,0,0,0,0,m_Edit.m_hWnd,0,AfxGetInstanceHandle(), 0);if (hTips) {// 修改窗口修改的目的是为了防止提示框被其它窗口遮盖要确保这个提示框要在最顶层::SetWindowPos(hTips, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);/*给提示框发送 TTM_ADDTOOL 消息展示TOOLINFO里的lpszText它的内容详细去MSDN搜索 TTM_ADDTOOL 查看详细介绍SendMessage的第三个参数和第四个参数可以看做成是 TTM_ADDTOOL 宏的第一个参数和第二个参数也就是把 TTM_ADDTOOL它当作函数看待忽略SendMessage这样的思路去看MSDNTTM_ADDTOOL消息处理Windows已经做好了只需要按照MSDN文档写的说明去传参就好效果就是设置第二行-第N行的数据*/::SendMessage(hTips, TTM_ADDTOOL, (WPARAM)1, (LPARAM)tips);/*发送 TTM_SETTITLE 消息提示框会设置图标和标题第四个参数是图标详情去MSDN搜索 TTM_SETTITLEMSDN里面介绍了发送 TTM_SETTITLE 消息时SendMessage函数第三个参数与第四个参数是什么SendMessage的第三个参数和第四个参数可以看做成是 TTM_SETTITLE 宏的第一个参数和第二个参数TTM_SETTITLE消息处理Windows已经做好了只需要按照MSDN文档写的说明去传参就好效果就是设置第一行的内容*/::SendMessage(hTips, TTM_SETTITLE, 0, (LPARAM)L可能的内容);}}if (hTips) {// GetWindowRect(tips.rect);// 设置提示框提示的文本或者说是修改文本::SendMessage(hTips, TTM_UPDATETIPTEXT, (WPARAM)FALSE, (LPARAM)tips);/*设置提示框的坐标详细信息去MSDN搜索 TTM_TRACKPOSITION扩展MAKELONG宏可以设置高位数据与低位数据使用例子MAKELONG(500, 50) 500就是高位数据50就是低位数据MAKELONG宏返回一个DWORD类型4字节的数字它的第一个参数是这个4字节数字高位2字节的数据第二个参数是低位2字节的数据效果就是设置显示位置*/::SendMessage(hTips, TTM_TRACKPOSITION, (WPARAM)FALSE, lPoint);/*显示窗口详细说明还是去MSDNMSDN操作方式还是搜索 TTM_TRACKACTIVATE说明的看法与上面三个一样TTM_SETTITLE、TTM_ADDTOOL、HWND_TOPMOST*/::SendMessage(hTips, TTM_TRACKACTIVATE, (WPARAM)TRUE, (LPARAM)tips);}
}CString CWndData::TimeToTxt(time_t* _tm)
{CString rt;struct tm newtiem {};localtime_s(newtiem, _tm); // 获取时间rt.Format(L%.4d-%.2d-%.2d %.2d:%.2d:%.2d, newtiem.tm_year 1900, newtiem.tm_mon 1, newtiem.tm_mday, newtiem.tm_hour, newtiem.tm_min, newtiem.tm_sec);return rt;
}BEGIN_MESSAGE_MAP(CWndData, CDialogEx)
END_MESSAGE_MAP()// CWndData 消息处理程序