C++ Win32获取窗口文本缓冲区容量

0yg35tkg  于 2023-02-06  发布在  其他
关注(0)|答案(2)|浏览(190)

我正在学习用C++编写基本的Win32应用程序,并试图在按下按钮后将输入的文本从一个可编辑文本框传递到一个新窗口。

我注意到,在Visual Studio 2019中,这种传输的默认文本缓冲区容量是20个字符(我使用的是64位Windows 10)。当我尝试传递长度超过20个字符的字符串时,会抛出一个异常。

我想知道如何增加缓冲区容量,因为最终我希望能够将文件路径传递到文本输入窗口并打开该文件。
我的代码:

#include <windows.h>
#include <string>
#include <iostream>

//lresult callback prototype
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

//window handles
HWND hMainWindow;
HINSTANCE hMainInstance;

HWND hLblOutput;
HWND hTxtInput;
HWND hButton;

#define IDC_TEXTBOX 1000
#define IDC_BUTTON 1001

//call to winmain - equivalent of main for win32 environments
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    MSG msg = { 0 };
    WNDCLASS wc = { 0 };
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hInstance;
    wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
    wc.lpszClassName = TEXT("NiceWindowsApp");
    if (!RegisterClass(&wc))
        return 1;

    hMainWindow = CreateWindow(wc.lpszClassName, TEXT("My Windows Application"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 640, 480, 0, 0, hInstance, NULL);

    hMainInstance = wc.hInstance;

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}
//callback definition
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int offset = 0;
    switch (message) {

    case WM_CREATE:
        hMainWindow = hWnd;
        hTxtInput = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), TEXT("Type something here"),
            WS_VISIBLE | WS_CHILD | ES_LEFT, 50, 50, 400, 25, hWnd,
            (HMENU)IDC_TEXTBOX, hMainInstance, NULL);
        hButton = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("BUTTON"), TEXT("Press Me!"), WS_VISIBLE |   WS_CHILD | WM_COPY | ES_LEFT, 500, 30, 100, 60, hWnd,
            (HMENU)IDC_BUTTON, hMainInstance, NULL);
        break;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDC_BUTTON)
        {
            
            //CANNOT HANDLE MORE THAN 20 CHARACTERS!!!
            std::string input;
            GetWindowTextA(hTxtInput, reinterpret_cast<char*> ((char*)input.c_str()), 400);
    
            ++offset;

            hLblOutput = CreateWindowEx(WS_EX_STATICEDGE, TEXT("EDIT"), input.c_str(), WS_VISIBLE | WS_CHILD | ES_READONLY | ES_LEFT, 50, 200 + offset * 26, 800, 25, hWnd,
                (HMENU)IDC_TEXTBOX, hMainInstance, NULL);

        }

    default:
        return DefWindowProc(hWnd, message, wParam, lParam);

    }

    return 0;
}

我曾尝试将GetWindowTextA()中的第三个参数增加到各种数字,最大值为4000,但似乎没有帮助。

s5a0g9ez

s5a0g9ez1#

一个正确的方法是:

std::wstring text;        
text.resize(GetWindowTextLengthW(hTxtInput));
text.resize(GetWindowTextW(hTxtInput, text.data(), text.size() + 1));
ve7v8dk2

ve7v8dk22#

按以下方法解决:

#include <windows.h>
#include <string>
#include <iostream>


//lresult callback prototype
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);


//window handles
HWND hMainWindow;
HINSTANCE hMainInstance;

HWND hLblOutput;
HWND hTxtInput;
HWND hButton;

CHAR s_text_1[]{ "Some text.." };
CHAR s_text_2[]{ 0 };

#define IDC_TEXTBOX 1000
#define IDC_BUTTON 1001



//call to winmain - equivalent of main for win32 environments
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{

    MSG msg = { 0 };
    WNDCLASS wc = { 0 };
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hInstance;
    wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
    wc.lpszClassName = TEXT("NiceWindowsApp");
    if (!RegisterClass(&wc))
        return 1;

    hMainWindow = CreateWindow(wc.lpszClassName, TEXT("My Windows Application"), WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        0, 0, 640, 480, 0, 0, hInstance, NULL);

    hMainInstance = wc.hInstance;

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}
//callback definition
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int offset = 0;
    switch (message) {

    case WM_CREATE:
        hMainWindow = hWnd;
        hTxtInput = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), s_text_1,
            WS_VISIBLE | WS_CHILD | ES_LEFT, 50, 50, 400, 25, hWnd,
            (HMENU)IDC_TEXTBOX, hMainInstance, NULL);
        hButton = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("BUTTON"), TEXT("Press Me!"), WS_VISIBLE | WS_CHILD | WM_COPY | ES_LEFT, 500, 30, 100, 60, hWnd,
            (HMENU)IDC_BUTTON, hMainInstance, NULL);
        break;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDC_BUTTON)
        {
            
            //CANNOT HANDLE MORE THAN 20 CHARACTERS!!!
            std::wstring input;
            
            //GetWindowTextW(hTxtInput, reinterpret_cast<char*> ((char*)input.c_str()), 400);
            int lgth = GetWindowTextLength(hTxtInput);
            //GetWindowTextW(hTxtInput, reinterpret_cast<wchar_t*> ((wchar_t*)input.c_str()), lgth);
            //GetWindowTextA(hTxtInput, char[], 400);
            GetWindowText(hTxtInput, s_text_1, 255);
            

            
            ++offset;


            hLblOutput = CreateWindowEx(WS_EX_STATICEDGE, TEXT("EDIT"), s_text_1, WS_VISIBLE | WS_CHILD | ES_READONLY | ES_LEFT, 50, 200 + offset * 26, 800, 25, hWnd,
                (HMENU)IDC_TEXTBOX, hMainInstance, NULL);
            SetWindowText(hLblOutput, s_text_1);

            

        }


    default:
        return DefWindowProc(hWnd, message, wParam, lParam);

    }

    return 0;
}

谢谢大家的提示。
编辑:我现在意识到这个解决方案在技术上并不完美,可能会导致未定义的行为和/或内存泄漏。我将考虑其他答案和评论中提出的建议,并相应地调整代码。
编辑版本2.0(2023年2月4日):我最近的代码如下。希望它更健壮。

#include <windows.h>
#include <string>
#include <iostream>
//last update - 04.02.2023 as per StackOverflow thread recommendations.

//lresult callback prototype
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);


//window handles
HWND hMainWindow;
HINSTANCE hMainInstance;

HWND hLblOutput;
HWND hTxtInput;
HWND hButton;

CHAR s_text_1[]{ "Some text.." };

#define IDC_TEXTBOX 1000
#define IDC_BUTTON 1001



//call to winmain - equivalent of main for win32 environments
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{

    MSG msg = { 0 };
    WNDCLASS wc = { 0 };
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hInstance;
    wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
    wc.lpszClassName = TEXT("NiceWindowsApp");
    if (!RegisterClass(&wc))
        return 1;

    hMainWindow = CreateWindow(wc.lpszClassName, TEXT("My Windows Application"), WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        0, 0, 640, 480, 0, 0, hInstance, NULL);

    hMainInstance = wc.hInstance;

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}
//callback definition
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int offset = 0;
    switch (message) {

    case WM_CREATE:
        hMainWindow = hWnd;
        hTxtInput = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), s_text_1,
            WS_VISIBLE | WS_CHILD | ES_LEFT, 50, 50, 400, 25, hWnd,
            (HMENU)IDC_TEXTBOX, hMainInstance, NULL);
        hButton = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("BUTTON"), TEXT("Press Me!"), WS_VISIBLE | WS_CHILD | WM_COPY | ES_LEFT, 500, 30, 100, 60, hWnd,
            (HMENU)IDC_BUTTON, hMainInstance, NULL);
        break;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDC_BUTTON)
        {
            
            
            std::wstring input;
            
            //resize added as suggested

            input.resize(GetWindowTextLengthW(hTxtInput));  
            GetWindowTextW(hTxtInput, input.data(), input.size() + 1);
            
            ++offset;

            hLblOutput = CreateWindowEx(WS_EX_STATICEDGE, TEXT("EDIT"), s_text_1, WS_VISIBLE | WS_CHILD | ES_READONLY | ES_LEFT, 50, 200 + offset * 26, 800, 25, hWnd,
                (HMENU)IDC_TEXTBOX, hMainInstance, NULL);
            SetWindowTextW(hLblOutput, input.data());

        }


    default:
        return DefWindowProc(hWnd, message, wParam, lParam);

    }

    return 0;
}

相关问题