我有一个Win32 API应用程序 在Visual Studio中进行调试期间,我发现我的应用程序内存使用量正在增加。我对Visual Studio的经验不足以了解更多信息。
但我发现的是,当我在其中一个文本框元素中写入内容时,内存使用量会增加更多。我也认为这个问题与ZeroMemory
有关,因为当我在10秒内制作堆的快照时,我得到一些合理的东西和160,000个字符,大小为0字节,在260秒时4.500.000一段时间后程序崩溃了。
我没有任何垃圾邮件功能ZeroMemory
。
我正在谈论的文本框是mw_txtOutput
,但我认为其他文章也受到影响而不是那么多:
main.cpp
// Logging Macros needs Log console to be defined
#define LOG_INFO(x) { console.WriteToLog("<td><b><font color=\"#0079F2\">[INFO]:</font></b></td><td> %s </td><td>(<i>%s</i>, Line <i>%d</i>, Function <i>%s</i>)</td>", (x), __FILENAME__, __LINE__, __FUNCSIG__); logToTextBox(mw_txtOutput, x); }
#define LOG_WARNING(x) { console.WriteToLog("<td><b><font color=\"#E4E600\">[WARNING]:</font></b></td><td> %s </td><td>(<i>%s</i>, Line <i>%d</i>, Function <i>%s</i>)</td>", (x), __FILENAME__, __LINE__, __FUNCSIG__); logToTextBox(mw_txtOutput, x); }
#define LOG_ERROR(x) { console.WriteToLog("<td><b><font color=\"#E68A00\">[ERROR]:</font></b></td><td> %s </td><td>(<i>%s</i>, Line <i>%d</i>, Function <i>%s</i>)</td>", (x), __FILENAME__, __LINE__, __FUNCSIG__); logToTextBox(mw_txtOutput, x); }
#define LOG_CRITICAL(x) { console.WriteToLog("<td><b><font color=\"#E60000\">[CRITICAL]:</font></b></td><td> %s </td><td>(<i>%s</i>, Line <i>%d</i>, Function <i>%s</i>)</td>", (x), __FILENAME__, __LINE__, __FUNCSIG__); logToTextBox(mw_txtOutput, x); }
// Defines for all window elements
#define BUTTON_SEND 100
#define BUTTON_FINISH 101
#include "Log.h"
#include "misc.h"
#include <tchar.h>
using namespace std;
struct windowsize { int width1, height1, width2, height2; };
windowsize txtOutputSize;
HINSTANCE hInst;
HWND mw, sw;
HWND mw_txtOutput, mw_txtInput, mw_btnSend;
HWND sw_txtuserPublicKey, sw_txtpubKeyLable, sw_txtprivateKeyContext, sw_txtprivKeyLable, sw_txtprivKeyPassword, sw_btnFinish;
bool window1closed, endprog;
LRESULT CALLBACK WndProc(HWND mw, UINT Msg, WPARAM wParam, LPARAM lParam) {
HDC hdc;
PAINTSTRUCT ps;
LPCSTR userPublicKey = "Name of the public Key";
LPCSTR pubKeyLable = "Label of the public Key";
LPCSTR privateKeyContext = "Private Key Context";
LPCSTR privKeyLable = "Label of the private Key";
LPCSTR privKeyPassword = "Password of the private Key";
int len = SendMessage(mw_txtInput, WM_GETTEXTLENGTH, 0, 0);
LPCSTR lpBuffer = new char[len];
switch (Msg) {
case WM_CREATE:
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case BUTTON_SEND:
SendMessage(mw_txtInput, WM_GETTEXT, (WPARAM)len + 1, (LPARAM)lpBuffer);
if(len >= 1) {
SetWindowText(mw_txtInput, _T(""));
MessageBox(NULL, lpBuffer, "Message", MB_OK);
}
break;
case BUTTON_FINISH:
MessageBox(NULL, "test", "test", MB_OK);
DestroyWindow(sw);
PostQuitMessage(0);
break;
}
break;
case WM_PAINT:
hdc = BeginPaint(sw, &ps);
TextOut(hdc, 5, 5, userPublicKey, strlen(userPublicKey));
TextOut(hdc, 5, 55, pubKeyLable, strlen(pubKeyLable));
TextOut(hdc, 5, 105, privateKeyContext, strlen(privateKeyContext));
TextOut(hdc, 5, 155, privKeyLable, strlen(privKeyLable));
TextOut(hdc, 5, 205, privKeyPassword, strlen(privKeyPassword));
EndPaint(sw, &ps);
break;
case WM_CLOSE:
window1closed = true;
DestroyWindow(mw);
break;
case WM_DESTROY:
window1closed = true;
PostQuitMessage(0);
break;
default:
return DefWindowProc(mw, Msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {
Log console;
if (!console.InitLog()) {
MessageBox(
NULL,
(LPCSTR)"Log Initialization failed!",
(LPCSTR)"Fatal Error",
MB_TOPMOST | MB_ICONERROR | MB_RETRYCANCEL | MB_DEFBUTTON1
);
exit(EXIT_FAILURE);
}
endprog = false;
LPCSTR szWindowClass = "win32app";
WNDCLASSEX wc;
MSG Msg;
RECT rect;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
wc.lpszMenuName = NULL;
wc.lpszClassName = szWindowClass;
if (!RegisterClassEx(&wc)) {
LOG_CRITICAL("Window Registration failed");
return 0;
}
hInst = hInstance;
mw = CreateWindowA(szWindowClass, TEXT("echat"), (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX), CW_USEDEFAULT, CW_USEDEFAULT, 900, 550, NULL, NULL, hInstance, NULL);
if (mw == NULL) {
LOG_CRITICAL("Main Window Creation failed");
return 0;
}
if (GetClientRect(mw, &rect)) {
txtOutputSize.width1 = rect.right - rect.left;
txtOutputSize.height1 = rect.bottom - rect.top;
}
mw_txtOutput = CreateWindowEx(
WS_EX_CLIENTEDGE,
TEXT("Edit"),
NULL,
WS_CHILD | WS_VISIBLE | ES_READONLY | ES_MULTILINE | WS_VSCROLL,
5, 5,
txtOutputSize.width1 - 10, txtOutputSize.height1 - 100 - 15,
mw,
NULL,
NULL,
NULL
);
mw_txtInput = CreateWindowEx(
WS_EX_CLIENTEDGE,
TEXT("Edit"),
"",
WS_CHILD | WS_VISIBLE | ES_AUTOVSCROLL | ES_MULTILINE | ES_LEFT,
5, txtOutputSize.height1 - 5 - 100,
txtOutputSize.width1 - 100, 100,
mw,
NULL,
NULL,
NULL
);
mw_btnSend = CreateWindowEx(NULL,
"BUTTON",
"Send",
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
txtOutputSize.width1 - 90,
txtOutputSize.height1 - 5 - 100,
txtOutputSize.width1 - (txtOutputSize.width1 - 100) - 15,
txtOutputSize.height1 - (txtOutputSize.height1 - 100) - 5,
mw,
(HMENU)BUTTON_SEND,
GetModuleHandle(NULL),
NULL);
ShowWindow(mw, nShowCmd);
UpdateWindow(mw);
// Setup Window
WNDCLASSEX sw_c;
RECT sw_rect;
sw_c.cbSize = sizeof(WNDCLASSEX);
sw_c.style = 0;
sw_c.lpfnWndProc = WndProc;
sw_c.cbClsExtra = 0;
sw_c.cbWndExtra = 0;
sw_c.hInstance = hInstance;
sw_c.hIcon = LoadIcon(NULL, IDI_APPLICATION);
sw_c.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
sw_c.hCursor = LoadCursor(NULL, IDC_ARROW);
sw_c.hbrBackground = (HBRUSH)(COLOR_WINDOW);
sw_c.lpszMenuName = NULL;
sw_c.lpszClassName = "Setup";
if (!RegisterClassEx(&sw_c)) {
LOG_CRITICAL("Setup Window Registration failed");
return 0;
}
sw = CreateWindowA(
szWindowClass,
TEXT("Setup"),
(WS_OVERLAPPED | WS_CAPTION)
, CW_USEDEFAULT, CW_USEDEFAULT,
500, 400,
NULL,
NULL,
hInstance,
NULL);
if (sw == NULL) {
LOG_CRITICAL("Setup Window Creation failed");
return 0;
}
if (GetClientRect(sw, &sw_rect)) {
txtOutputSize.width2 = sw_rect.right - sw_rect.left;
txtOutputSize.height2 = sw_rect.bottom - sw_rect.top;
}
sw_btnFinish = CreateWindowEx(
NULL,
"BUTTON",
"Finish",
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
430,
330,
50,
25,
sw,
(HMENU)BUTTON_FINISH,
GetModuleHandle(NULL),
NULL);
sw_txtuserPublicKey = CreateWindowEx(
WS_EX_CLIENTEDGE,
TEXT("Edit"),
NULL,
WS_CHILD | WS_VISIBLE,
5, 25,
475, 25,
sw,
NULL,
NULL,
NULL
);
sw_txtpubKeyLable = CreateWindowEx(
WS_EX_CLIENTEDGE,
TEXT("Edit"),
NULL,
WS_CHILD | WS_VISIBLE,
5, 75,
475, 25,
sw,
NULL,
NULL,
NULL
);
sw_txtprivateKeyContext = CreateWindowEx(
WS_EX_CLIENTEDGE,
TEXT("Edit"),
NULL,
WS_CHILD | WS_VISIBLE,
5, 125,
475, 25,
sw,
NULL,
NULL,
NULL
);
sw_txtprivKeyLable = CreateWindowEx(
WS_EX_CLIENTEDGE,
TEXT("Edit"),
NULL,
WS_CHILD | WS_VISIBLE,
5, 175,
475, 25,
sw,
NULL,
NULL,
NULL
);
sw_txtprivKeyPassword = CreateWindowEx(
WS_EX_CLIENTEDGE,
TEXT("Edit"),
NULL,
WS_CHILD | WS_VISIBLE | ES_PASSWORD,
5, 225,
475, 25,
sw,
NULL,
NULL,
NULL
);
// initialize NONCLIENTMETRICS structure
NONCLIENTMETRICS ncm;
ncm.cbSize = sizeof(ncm);
// obtain non-client metrics
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0);
// create the new font
HFONT hNewFont = CreateFontIndirect(&ncm.lfMessageFont);
// set the new font
SendMessage(mw_txtInput, WM_SETFONT, (WPARAM)hNewFont, 0);
SendMessage(mw_txtOutput, WM_SETFONT, (WPARAM)hNewFont, 0);
SendMessage(mw_btnSend, WM_SETFONT, (WPARAM)hNewFont, 0);
SendMessage(sw_btnFinish, WM_SETFONT, (WPARAM)hNewFont, 0);
SendMessage(sw_txtpubKeyLable, WM_SETFONT, (WPARAM)hNewFont, 0);
SendMessage(sw_txtprivKeyLable, WM_SETFONT, (WPARAM)hNewFont, 0);
SendMessage(sw_txtprivateKeyContext, WM_SETFONT, (WPARAM)hNewFont, 0);
SendMessage(sw_txtprivKeyPassword, WM_SETFONT, (WPARAM)hNewFont, 0);
SendMessage(sw_txtuserPublicKey, WM_SETFONT, (WPARAM)hNewFont, 0);
ShowWindow(sw, nShowCmd);
UpdateWindow(sw);
while (endprog == false) {
if (GetMessage(&Msg, NULL, 0, 0) > 0) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
if (window1closed) {
endprog = true;
}
}
return Msg.wParam;
}
Log.cpp
#include "Log.h"
#include "misc.h"
#define LOG_INFO(x) { Log::WriteToLog("<td><b><font color=\"#0079F2\">[INFO]:</font></b></td><td> %s </td><td>(<i>%s</i>, Line <i>%d</i>, Function <i>%s</i>)</td>", (x), __FILENAME__, __LINE__, __FUNCSIG__); }
#define LOG_WARNING(x) { Log::WriteToLog("<td><b><font color=\"#E4E600\">[WARNING]:</font></b></td><td> %s </td><td>(<i>%s</i>, Line <i>%d</i>, Function <i>%s</i>)</td>", (x), __FILENAME__, __LINE__, __FUNCSIG__); }
#define LOG_ERROR(x) { Log::WriteToLog("<td><b><font color=\"#E68A00\">[ERROR]:</font></b></td><td> %s </td><td>(<i>%s</i>, Line <i>%d</i>, Function <i>%s</i>)</td>", (x), __FILENAME__, __LINE__, __FUNCSIG__); }
#define LOG_CRITICAL(x) { Log::WriteToLog("<td><b><font color=\"#E60000\">[CRITICAL]:</font></b></td><td> %s </td><td>(<i>%s</i>, Line <i>%d</i>, Function <i>%s</i>)</td>", (x), __FILENAME__, __LINE__, __FUNCSIG__); }
using namespace std;
Log::Log() {
}
Log::~Log() {
ExitLog();
}
bool Log::InitLog() {
string time_string = getCTime("%Y-%m-%d_%H-%M");
logFile.open(time_string + ".log.html", fstream::out);
if (!logFile.is_open()) { return false; }
logFile <<
"<!DOCTYPE html>" << endl <<
"<html>" << endl <<
"<head>" << endl <<
"<title>echat Log: " + time_string + "</title>" << endl <<
"</head>" << endl <<
"<body>" << endl <<
"<font face=\"Consolas\" size=\"2\">" << endl <<
"<table>" << endl;
isRunning = true;
LOG_INFO("Logging Started")
return true;
}
bool Log::ExitLog() {
LOG_INFO("Logging Stopped")
logFile <<
"</table></font>" << endl <<
"<!--echat Log End-->" << endl <<
"</body>" << endl <<
"</html>";
logFile.close();
isRunning = false;
return false;
}
void Log::log_loop() {
while (isRunning) {
isRunning = false;
LOG_INFO("Leaving..")
}
}
bool Log::WriteToLog(char* pcFormat, ...) {
char acText[1024];
char acNewText[2048];
va_list VAList;
int iCursor = 0;
va_start(VAList, pcFormat);
vsprintf(acText, pcFormat, VAList);
va_end(VAList);
ZeroMemory(acNewText, 2048 * sizeof(char));
for (int iChar = 0; iChar < (int)strlen(acText); iChar++) {
if (acText[iChar] == '\n') {
acNewText[iCursor++] = '<';
acNewText[iCursor++] = 'b';
acNewText[iCursor++] = 'r';
acNewText[iCursor++] = '>';
} else {
acNewText[iCursor] = acText[iChar];
iCursor++;
}
}
logFile << "<tr>" << acNewText << "</tr>" << endl;
return true;
}
misc.cpp
#include "Misc.h"
void addToTextBox(HWND txtBox, string txt) {
int len = SendMessage(txtBox, WM_GETTEXTLENGTH, 0, 0);
LPCSTR lpBuffer = new char[len];
SendMessage(txtBox, WM_GETTEXT, (WPARAM)len + 1, (LPARAM)lpBuffer);
txt = lpBuffer + txt + TEXT("\r\n");
lpBuffer = txt.c_str();
SetWindowText(txtBox, lpBuffer);
SendMessage(txtBox, WM_VSCROLL, SB_BOTTOM, 0L);
}
void logToTextBox(HWND txtBox, string txt) {
int len = SendMessage(txtBox, WM_GETTEXTLENGTH, 0, 0);
LPCSTR lpBuffer = new char[len];
string timestamp = "[" + getCTime("%H:%M:%S") + "]";
SendMessage(txtBox, WM_GETTEXT, (WPARAM)len + 1, (LPARAM)lpBuffer);
txt = lpBuffer + timestamp + ' ' + txt + TEXT("\r\n");
lpBuffer = txt.c_str();
SetWindowText(txtBox, lpBuffer);
SendMessage(txtBox, WM_VSCROLL, SB_BOTTOM, 0L);
}
string getCTime(string format) { // "%Y-%m-%d_%H-%M" = 1900-12-01_23-59 "%H:%M:%S" = 23:59:59
stringstream buffer;
time_t time = chrono::system_clock::to_time_t(chrono::system_clock::now());
buffer << put_time(&tm(*localtime(&time)), format.c_str());
return buffer.str();
}