Win32 API VS C++;文本框内容到字符串

Posted

技术标签:

【中文标题】Win32 API VS C++;文本框内容到字符串【英文标题】:Win32 API VS C++; Text Box Content to String 【发布时间】:2015-04-29 17:55:48 【问题描述】:

我是 Win32 应用程序编程新手。我编写了一个文本框,用户可以在其中输入文本。问题是我不知道如何将框的输入变成字符串,这是处理输入所必需的。出于测试目的,我尝试通过输出文本框给出输入的文本,无论如何我都必须对其进行编程。

谷歌搜索,我发现GetWindowTextA(hInput, input, length); 应该可以解决问题。但是,我不确定如何使用这种方法将输入输入到变量中。

所以,我的问题是,如何将用户输入到文本框中的文本转换为字符串?

万一这很重要:我没有使用 Visual Studio 的免费版本,因为我可以通过我的大学免费访问 Microsoft 软件。目前我正在使用 Visual Studio 2015 Ultimate Preview。提前回答这个问题,这对我的大学、工作或任何商业而言都不是家庭作业或其他工作。我自学了 C++,它已成为我最喜欢的编程语言,我希望能够用它编写图形界面。

这里是 Visual Studio 的标准代码,做了一些修改,最值得注意的是添加了两个文本框和一个按钮(目前什么都不做,对这个问题不重要):

包含、全局、前向声明

#include "stdafx.h"
#include "WilliTeX.h"
#include <iostream>;

using namespace std;

#define MAX_LOADSTRING 100

//custom defines
#define TEXT_INPUT_BOX 1
#define TEXT_OUTPUT_BOX 2
#define BUTTON 3

HWND hInput;
HWND hOutput;
HWND hButton;

int length;
LPSTR input;

// Global Variables:
HINSTANCE hInst;                                // current instance
TCHAR szTitle[MAX_LOADSTRING];                  // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];            // the main window class name


// Forward declarations of functions included in this code module:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

_tWinMain

int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPTSTR    lpCmdLine,
                     _In_ int       nCmdShow)

    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    MSG msg;
    HACCEL hAccelTable;

    // Initialize global strings
    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadString(hInstance, IDC_WILLITEX, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    // Perform application initialization:
    if (!InitInstance (hInstance, nCmdShow))
    
        return FALSE;
    

    hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WILLITEX));

    // Main message loop:
    while (GetMessage(&msg, NULL, 0, 0))
    
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        
    

    return (int) msg.wParam;

MyRegisterClass

//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
ATOM MyRegisterClass(HINSTANCE hInstance)

    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WILLITEX));
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_WILLITEX);
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassEx(&wcex);

其余代码

//
//   FUNCTION: InitInstance(HINSTANCE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)

   HWND hWnd;

   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   
      return FALSE;
   

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;


//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND  - process the application menu
//  WM_PAINT    - Paint the main window
//  WM_DESTROY  - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    
    case WM_CREATE:
    
        //This is the input box, where the user enters the text
        hInput = CreateWindowExA(WS_EX_CLIENTEDGE,
            "EDIT",
            "",
            WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL,
            50, //moving left/right the box
            10, //moving up/down the box
            1300, //length
            350, //height
            hWnd,
            (HMENU)TEXT_INPUT_BOX,
            GetModuleHandle(NULL),
            NULL);

        //This is the output text box, that will display the convertion
        hInput = CreateWindowExA(WS_EX_CLIENTEDGE,
            "Edit", 
            "test",
            WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL,
            50, //moving left/right the box
            200, //moving up/down the box
            1300, //length
            450, //height
            hWnd, 
            (HMENU)TEXT_INPUT_BOX,
            GetModuleHandle(NULL),
            NULL);

        hButton = CreateWindowExA(NULL,
            "BUTTON",
            "OK",
            WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
            3, //moving left/right
            10, //moving up/down
            48, //length
            50, //height
            hWnd,
            (HMENU) BUTTON,
            GetModuleHandle(NULL),
            NULL);

        break;
    
    case WM_COMMAND:
        wmId    = LOWORD(wParam);
        wmEvent = HIWORD(wParam);

        switch (LOWORD(wParam)) 
            //refreshing the output box whenever the user is giving an input
        case TEXT_INPUT_BOX:
        
            length = GetWindowTextLengthA(hInput);
            GetWindowTextA(hInput, input, length);

            hInput = CreateWindowExA(WS_EX_CLIENTEDGE,
                "Edit",
                input,
                WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL,
                50, //moving left/right the box
                200, //moving up/down the box
                1300, //length
                450, //height
                hWnd,
                (HMENU)TEXT_INPUT_BOX,
                GetModuleHandle(NULL),
                NULL);

            break;
        

        case BUTTON:
        
            break;
        
        

        // Parse the menu selections:
        switch (wmId)
        
        case IDM_ABOUT:
            DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        
        break;
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        // TODO: Add any drawing code here...
        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    
    return 0;


// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)

    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        
        break;
    
    return (INT_PTR)FALSE;

附:我知道使用命名空间标准;是不好的编码习惯,但对于这个学习计划,我真的不在乎。

【问题讨论】:

【参考方案1】:

当您收到消息时,您似乎正在创建输入文本框(再次)。那没有意义。并且您的 GetWindowTextA 调用正在使用您尚未定义的变量“输入”。为该变量分配一个字符数组。

【讨论】:

LPSTR 输入;我已经全局定义了这个变量,因为我最初在不止一个地方使用它。问题是变量输入不包含用户输入或其他错误。如果我这样做:input = "Test",那么只要我开始在文本框 1 中输入内容,第二个文本框就会显示“Test”。 LPSTR 输入定义了一个指针。这并没有为其分配任何内存指向。您必须有一些内存才能传递给 Windows。如果是全局的,则以 char input[1024]; 开头 使用 char input[1024] 的效果是我在单词 test 的下一个字母之后删除了一个字母,但我什么也没写。除此之外, char* 也可以吗?我讨厌必须使用(普通)数组,因为这意味着我必须猜测输入会持续多长时间,尤其是很可能会出现长输入。 除了我当前的实现之外,是否有一些方法可以让我将文本框的内容存储在变量中,最好是字符串或字符*? 不会自动这样。您需要使用WM_GETTEXTLENGTH 消息或GetWindowTextLength() 函数获取编辑控件中文本的长度,分配一个足够大的缓冲区来存储该文本,然后调用GetWindowText() 来获取窗口文本。还有什么原因您使用函数和消息的 ANSI (A) 变体,而不是 Unicode (W) 变体?

以上是关于Win32 API VS C++;文本框内容到字符串的主要内容,如果未能解决你的问题,请参考以下文章

按下回车按钮时如何使用 C++ Win32 API 调用按钮?

如何设置win32 api c++按钮背景颜色和文本颜色?

在Win32(c ++)中的另一个进程中写入文本框

Win32 中仅接受文本框(编辑控件)中的字符和空格

c++ win32编辑框光标不闪烁

如何使用visual studio 2017编写一个C++程序