c++ - 为什么抓取窗口标题的代码会导致应用程序崩溃?

标签 c++ winapi

我是 C++ 的新手,但我制作了一个控制台应用程序,该应用程序会一直等待,直到它检测到具有特定标题的窗口,然后执行一些代码。只要它检测到一个窗口,它就工作得很好。但是,我注意到如果应用程序正在运行并且窗口没有出现,那么在 4 分 20 秒(大约)后它会崩溃。

崩溃信息只是说 APPCRASH 归因于 ntdll.dll

我在代码中放置了断点,并将其缩小到导致崩溃的这段代码。

// GRAB WINDOW TITLE AND PUT IT IN "lpszTitle"
int nLen = GetWindowTextLength(hWnd);
LPSTR lpszTitle = new CHAR[nLen + 1];
GetWindowText(hWnd, lpszTitle, nLen);

此代码后跟一个“if”语句,当窗口标题与某个字符串匹配时执行主代码。

在此之前,这段代码只是在 while(1) 循环等待中运行。

下面是更完整的代码 list 。

#pragma once
#undef UNICODE
#include <windows.h>
#include <iostream>
#include <string>
#include <sstream>
#include <tchar.h>
#include <cassert>
#include <cstdio>
#include <stdlib.h>
#include <mmsystem.h>
#include <time.h>


// Example of the __stdcall keyword  
#define WINAPI __stdcall

using namespace std;

HMODULE hLib;
BOOL CALLBACK SearchProc(HWND hWnd, LPARAM lParam)
{

// THIS FUNCTION SEARCHES ALL OPEN WINDOWS
// UNTIL IT FINDS ONE WITH "DX" IN IT'S TITLE
// IT THEN GRABS THE MEMORY ADDRESS REFERENCED
// BELOW WHICH CONTAINS THE "TOTALOUT" VARIABLE
// FOR THE FRUIT MACHINE




// INITIALISE VARIABLES FOR USE IN THIS FUNCTION
DWORD address = 0x96e0a4;
long currentMachinePaidOutTotal = 0;
long unsortedTotalcurrentMachinePaidOutTotal = 0;
long calculatedWinnings = 0;    
long oldAmountMachinePaidOut = 0;
bool initialiseOldAmountMachinePaidOut = false;
bool slowMachine = false;
bool payoutFiverOneShot = false;
string currentWindowName = "";
DWORD pid;

// GRAB WINDOW TITLE AND PUT IT IN "lpszTitle"
int nLen = GetWindowTextLength(hWnd);
LPSTR lpszTitle = new CHAR[nLen + 1];
GetWindowText(hWnd, lpszTitle, nLen);


// LET'S CHECK IF WINDOW HAS "DX" IN TITLE
if (strstr(lpszTitle, "DX") && !strstr(lpszTitle, "=")) {
    cout << "\nFound window with name: " << lpszTitle << "\n";
    currentWindowName = lpszTitle;

    // Found "DX" in the title of the window
    // CONTINUE WITH CODE IN HERE....

    return TRUE;
}
else {
    // NO WINDOW WITH "DX" IN THE TITLE OPEN YET
}

return TRUE;
}



int main(int argc, char *argv[])
{

hLib = LoadLibrary("cash.dll");
assert(hLib != NULL); // pass !!


while (1)
{
    EnumWindows(SearchProc, NULL);
}
return 0;
}

知道为什么会导致崩溃吗?

如果您需要查看更多代码或获取更多信息,请发表评论。为了简洁明了,我特意只包含了“有问题”的代码。

最佳答案

你用 new 分配了 lpszTitle 而没有释放它。根据 while 循环运行的频率,您可能会很快耗尽内存。尝试在函数结束前添加一个 delete[] lpszTitle

一些其他花絮:

  1. 您似乎将 BOOLbool 混合使用。我建议使用 bool,因为它是标准的 C++。

  2. 手动内存分配是老派的 C++。试用 smart pointers .

  3. 为什么不使用 std::string (或 @IInspectable 在评论中建议的 std::wstring)而不是 char[]

  4. 在使用时声明变量,而不是全部在函数的开头(您可能来自 fortran?)。

  5. Why is "using namespace std" considered bad practice?

但是,我建议您将最终代码发布到 https://codereview.stackexchange.com以获得更多更好的输入。

关于c++ - 为什么抓取窗口标题的代码会导致应用程序崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45390354/

相关文章:

C++:如何在使用 libcurl 的 Windows 中运行可执行文件?

c# - 获取多个 FileInfo 的更快方法?

c++ - Windows C++框架推荐

c++ - 预期和实际打印结果不符

c++ - FindFirstFile、FindNextFile API 是否不可靠?

c++ - 从技术角度来看,为什么 shared_from_this 不能在构造函数中使用?

c++ - Matlab rescale 命令的 Eigen 等价物

c++ - 带有节点迭代器的链表构造函数给出无效指针的错误

c++ - 指向基类和私有(private)继承的指针

c - 从 WinHttp 获取请求的实际总 header 大小