前面几篇,已经将所有基本的工具函数写完,这一篇,主要是将所有的功能串起来,使界面和功能进行交互。
双击首次搜索按钮,在生成的函数中加入以下代码:
逻辑很简单
void CModifierDlg::OnBnClickedButtonFirst()
{
// TODO: 在此添加控件通知处理程序代码
if (m_dwProcessId == 0) {
AfxMessageBox(_T("请选择进程!"));
OnBnClickedButtonProgress(); // 若未选择进程,则打开进程列表
}
if (m_dwProcessId == 0) {
AfxMessageBox(_T("用户未选择进程!"));
return;
}
m_bGoon = true; // 开启回调
m_listAddressTemp.DeleteAllItems();
//UpdateData(TRUE);
// 获取界面参数
CString valueTemp;
GetDlgItemText(IDC_EDIT_SEARCH_VALUE, valueTemp);
if (valueTemp.IsEmpty()) {
AfxMessageBox(_T("请输入搜索的值"));
return;
}
CString start, end;
GetDlgItemText(IDC_EDIT_LIMIT_START, start);
GetDlgItemText(IDC_EDIT_LIMIT_END, end);
_TCHAR* szEnd = NULL;
DWORD dwLimitBegin = _tcstol(start.GetString(), &szEnd, 0x10);
DWORD dwLimitEnd = _tcstol(end.GetString(), &szEnd, 0x10);
GetDlgItem(IDC_BUTTON_FIRST)->EnableWindow(FALSE); // 使首次搜索按钮失效
// 根据选择的不同数据类型,进行不同方式的查找
int iIdx = m_comboxValueType.GetCurSel();
bool bFind = false;
switch (iIdx) {
case 0: { // 1字节
TCHAR* szEndPtr = nullptr;
unsigned long ul = _tcstoul(valueTemp.GetString(), &szEndPtr, 10);
BYTE bb = (BYTE)(ul & 0x000000FF);
bFind = m_pFinder->FindFirstEx(m_dwProcessId, dwLimitBegin, dwLimitEnd, bb);
break;
}
case 1: { // 2字节
TCHAR* szEndPtr = nullptr;
unsigned long ul = _tcstoul(valueTemp.GetString(), &szEndPtr, 10);
SHORT bb = (SHORT)(ul & 0x0000FFFF);
bFind = m_pFinder->FindFirstEx(m_dwProcessId, dwLimitBegin, dwLimitEnd, bb);
break;
}
case 2: { // 4字节
TCHAR* szEndPtr = nullptr;
unsigned long ul = _tcstoul(valueTemp.GetString(), &szEndPtr, 10);
DWORD bb = (DWORD)(ul & 0xFFFFFFFF);
bFind = m_pFinder->FindFirstEx(m_dwProcessId, dwLimitBegin, dwLimitEnd, bb);
break;
}
case 3: { // float
TCHAR* szEndPtr = nullptr;
float f = _tcstof(valueTemp.GetString(), &szEndPtr);
bFind = m_pFinder->FindFirstEx(m_dwProcessId, dwLimitBegin, dwLimitEnd, f);
break;
}
case 4: { // double
TCHAR* szEndPtr = nullptr;
double d = _tcstod(valueTemp.GetString(), &szEndPtr);
bFind = m_pFinder->FindFirstEx(m_dwProcessId, dwLimitBegin, dwLimitEnd, d);
break;
}
default:
break;
}
if (!bFind) {
// 恢复按钮 可用状态
GetDlgItem(IDC_BUTTON_FIRST)->EnableWindow(TRUE);
// 继续搜索标置(false)
m_bGoon = false;
UpdateData(FALSE);
return;
}
const std::list<DWORD>& lst = m_pFinder->GetResults();
int index = 1024; //最多显示1024结果
for (auto addr : lst) {
if (index-- <= 0) {
break;
}
int index = m_listAddressTemp.InsertItem(0, _T(""));
CString s;
s.Format(_T("%08X"), addr);
m_listAddressTemp.SetItemText(index, 0, s);
}
// 进度条清0
m_pProgress.SetPos(0);
// 恢复按钮 可用状态
GetDlgItem(IDC_BUTTON_FIRST)->EnableWindow(TRUE);
// 继续搜索标置(false)
m_bGoon = false;
//UpdateData(FALSE);
return;
}
双击再次搜索按钮,在生成的函数中加入以下代码
逻辑和首次搜索基本一致
void CModifierDlg::OnBnClickedButtonNext()
{
// TODO: 在此添加控件通知处理程序代码
m_bGoon = true;
// 目标值
CString valueTemp;
GetDlgItemText(IDC_EDIT_SEARCH_VALUE, valueTemp);
if (valueTemp.IsEmpty()) {
AfxMessageBox(_T("请输入目标值"));
UpdateData(FALSE);
m_bGoon = false;
return;
}
GetDlgItem(IDC_BUTTON_NEXT)->EnableWindow(FALSE);
m_listAddressTemp.DeleteAllItems();
int iIdx = m_comboxValueType.GetCurSel();
bool bFind = false;
switch (iIdx) {
case 0: { // 1字节
TCHAR* szEndPtr = nullptr;
unsigned long ul = _tcstoul(valueTemp.GetString(), &szEndPtr, 10);
BYTE bb = (BYTE)(ul & 0x000000FF);
bFind = m_pFinder->FindNextEx(bb);
break;
}
case 1: { // 2字节
TCHAR* szEndPtr = nullptr;
unsigned long ul = _tcstoul(valueTemp.GetString(), &szEndPtr, 10);
SHORT bb = (SHORT)(ul & 0x0000FFFF);
bFind = m_pFinder->FindNextEx(bb);
break;
}
case 2: { // 4字节
TCHAR* szEndPtr = nullptr;
unsigned long ul = _tcstoul(valueTemp.GetString(), &szEndPtr, 10);
DWORD bb = (DWORD)(ul & 0xFFFFFFFF);
bFind = m_pFinder->FindNextEx(bb);
break;
}
case 3: { // float
TCHAR* szEndPtr = nullptr;
float f = _tcstof(valueTemp.GetString(), &szEndPtr);
bFind = m_pFinder->FindNextEx(f);
break;
}
case 4: { // double
TCHAR* szEndPtr = nullptr;
double d = _tcstod(valueTemp.GetString(), &szEndPtr);
bFind = m_pFinder->FindNextEx(d);
break;
}
default:
break;
}
if (!bFind) {
// 恢复按钮 可用状态
GetDlgItem(IDC_BUTTON_NEXT)->EnableWindow(TRUE);
// 继续搜索标置(false)
m_bGoon = false;
UpdateData(FALSE);
return;
}
const std::list<DWORD>& lst = m_pFinder->GetResults();
int index = 1024; //最多显示1024结果
for (auto addr : lst) {
if (index-- <= 0) {
break;
}
int index = m_listAddressTemp.InsertItem(0, _T(""));
CString s;
s.Format(_T("%08X"), addr);
m_listAddressTemp.SetItemText(index, 0, s);
}
// 进度条清0
m_pProgress.SetPos(0);
// 恢复按钮 可用状态
GetDlgItem(IDC_BUTTON_NEXT)->EnableWindow(TRUE);
m_bGoon = false;
UpdateData(FALSE);
}
双击停止搜索按钮,加入以下代码
以首次搜索为例:
由于m_bGoon被作为一个回调的变量,此变量一旦为false,则回调函数返回false,则搜索直接结束
在生成的函数中加入以下代码:
以上的代码逻辑很简单:
第一个listctrl双击选中的地址,应在第二个listctrl控件上显示该地址的值以及类型等其他信息
第二个listctrl双击应在软件的右侧修改参数这里,将值、类型、地址显示到edit控件上
好了,到这里基本功能就写完了,
使用该程序可以修改任意的本地程序的数值类型的参数
比如某游戏的阳光数目,通信程序发送的数据量,某游戏的命数