文本框填充内存

时间:2016-02-08 16:53:22

标签: c++ visual-studio winapi

我有一个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();
}

0 个答案:

没有答案