简体   繁体   中英

what is the simplest way to create edit box in c++

i need to create edit box in c++ without using mfc.....
only win32

CreateWindow("EDIT", ...); . You can use CreateWindowEx if you prefer, but it's not necessary. To use it, you'll also normally want to have your window respond to WM_FOCUS by calling SetFocus to set the focus on the edit control. You'll typically also want to respond to WM_MOVE (or is it WM_SIZE - I can't remember) by resizing the edit control to fit the client area of the parent window.

Of course you can also create a dialog ( DialogBox or DialogBoxEx ) containing an edit control. This avoids having to manually set the focus and such.

So, here's a simple demo program. This creates a main window, and fills its client area with an edit control. It can open and save files, do cut/copy/paste of the data in the control, and select a font in which to display the data in the control. It has an accelerator table, so it knows about the usual keyboard shortcuts for most of those (eg, ctrl-x = cut, ctrl-c = copy, ctrl-v = paste).

First, the main source code:

// notepad.cpp
#include <windows.h>
#include "notepad.h"
#include <string.h>
#include <string>
#include <fstream>
#include <sstream>

HINSTANCE hInst;
HWND    hwnd;

static const HMENU edit_id = HMENU(100);
static HWND hwndEdit;

void Invalidate(HWND window) {
    RECT rect;
    GetClientRect(window, &rect);
    InvalidateRect(window, &rect, TRUE);
}

class file {
    std::string filename;
    char buffer[FILENAME_MAX];

    void write_file() {
        size_t size = SendMessage(hwndEdit, WM_GETTEXTLENGTH, 0, 0);
        std::string buffer(size+1, '\0');
        SendMessage(hwndEdit, WM_GETTEXT, size + 1, (LPARAM)&buffer[0]);
        std::ofstream out(filename);
        out.write(&buffer[0], size);
    }

    long long get_size(std::string const& filename) {
        WIN32_FIND_DATA data;
        auto h = FindFirstFile(filename.c_str(), &data);
        long long size = data.nFileSizeHigh;
        size <<= 32;
        size |= data.nFileSizeLow;
        return size;
    }

    void read_file() {
        std::ifstream in(filename);
        std::string buffer;
        long long size = get_size(filename);
        if (size > 1024 * 1024) {
            MessageBox(hwnd, "File too large", "", MB_OK);
            return;
        }
        buffer.resize(size+1);
        in.read(&buffer[0], size);
        std::string::size_type pos = 0;
        unsigned count = 0;
        while ((pos = buffer.find('\n', pos)) != std::string::npos) {
            buffer.replace(pos, 1, "\r\n");
            pos += 2;
            ++count;
        }
        SendMessage(hwndEdit, WM_SETTEXT, 0, (LPARAM)buffer.c_str());
    }

public:
    file() : buffer("\0\0") {}
    bool open() {
        if (SendMessage(hwndEdit, EM_GETMODIFY, 0, 0)) {
            if (MessageBox(hwnd, "Open without saving current text?", "Buffer Modified", MB_OKCANCEL) == IDCANCEL)
                return false;
        }
        OPENFILENAMEA spec{};
        spec.lStructSize = sizeof(spec);
        spec.hwndOwner = hwnd;
        spec.lpstrFile = buffer;
        spec.nMaxFile = sizeof(buffer);
        spec.Flags = OFN_ENABLESIZING | OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_SHAREAWARE | OFN_FILEMUSTEXIST;

        if (GetOpenFileName(&spec)) {
            filename = spec.lpstrFile;
            read_file();
            return true;
        }
        return false;
    }

    bool save() {
        if (filename.empty())
            return save_as();
        write_file();
        SendMessage(hwndEdit, EM_SETMODIFY, 0, 0);
        return true;
    }

    bool save_as() {
        OPENFILENAMEA spec{};
        spec.lStructSize = sizeof(spec);
        spec.hwndOwner = hwnd;
        spec.lpstrFile = buffer;
        spec.nMaxFile = sizeof(buffer);
        spec.Flags = OFN_OVERWRITEPROMPT | OFN_ENABLESIZING | OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_SHAREAWARE;

        if (GetSaveFileName(&spec)) {
            filename = spec.lpstrFile;
            write_file();
            SendMessage(hwndEdit, EM_SETMODIFY, 0, 0);
            return true;
        }
        return false;
    }
} file;

class font {
    HFONT current;
    LOGFONT log_font;
    CHOOSEFONT spec;

    bool choose() {
        spec.lStructSize = sizeof(spec);
        spec.hwndOwner = hwnd;
        spec.lpLogFont = &log_font;
        spec.Flags = CF_INITTOLOGFONTSTRUCT | CF_FORCEFONTEXIST | CF_SCREENFONTS;
        return ChooseFont(&spec);
    }
public:
    font()
        : current(NULL)
        , log_font{}
        , spec{}
    {}

    bool select() {
        if (!choose())
            return false;
        current = CreateFontIndirect(&log_font);
        SendMessage(hwndEdit, WM_SETFONT, *reinterpret_cast<WPARAM *>(&current), TRUE);
        return true;
    }
} font;

LRESULT CALLBACK MainWndProc(HWND hwnd,
                             UINT message,
                             WPARAM wparam,
                             LPARAM lparam)
{
    PAINTSTRUCT ps;
    HDC dc;
    RECT rect;
    int i;

    switch (message) {
        case WM_PAINT:
            dc = BeginPaint(hwnd, &ps);
            EndPaint(hwnd, &ps);
            return 0;

        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;

        case WM_CREATE:
            hwndEdit = CreateWindowEx(
                0, 
                "EDIT",
                NULL,
                WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN,
                0, 0, 0, 0,
                hwnd,
                edit_id,
                hInst,
                NULL);
            if (hwndEdit == nullptr)
                return -1;
            return 0;

        case WM_SIZE: {
            int width = LOWORD(lparam);
            int height = HIWORD(lparam);

            MoveWindow(hwndEdit, 0, 0, width, height, TRUE);
            break;
        }

        case WM_SETFOCUS:
            SetFocus(hwndEdit);
            break;

        case WM_COMMAND :
            switch(LOWORD(wparam)) {
                case ID_EXIT:
                    if (wparam == ID_EXIT)
                        PostMessage(hwnd, WM_DESTROY, 0, 0);
                    break;
                case ID_FILE_OPEN:
                    if (file.open())
                        return 0;
                    break;
                case ID_FILE_SAVE:
                    if (file.save())
                        return 0;
                    break;
                case ID_FILE_SAVEAS:
                    if (file.save_as())
                        return 0;
                    break;
                case ID_EDIT_UNDO:
                    if (SendMessage(hwndEdit, EM_CANUNDO, 0, 0))
                        SendMessage(hwndEdit, WM_UNDO, 0, 0);
                    return 0;
                case ID_EDIT_SELECT_ALL:
                    SendMessage(hwndEdit, EM_SETSEL, 0, -1);
                    return 0;               
                case ID_EDIT_CUT:
                    SendMessage(hwndEdit, WM_CUT, 0, 0);
                    break;
                case ID_EDIT_COPY:
                    SendMessage(hwndEdit, WM_COPY, 0, 0);
                    break;
                case ID_EDIT_PASTE:
                    SendMessage(hwndEdit, WM_PASTE, 0, 0);
                    break;
                case ID_VIEW_FONT:
                    return font.select();
                default: {
                    return DefWindowProc(hwnd, message, wparam, lparam);
                }
            }
    }
    return DefWindowProc(hwnd, message, wparam, lparam);
}

BOOL Init(HINSTANCE hInstance, int nCmdShow)
{
    WNDCLASSEX wc;


    hInst = hInstance; 

    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.hIconSm       = (HICON)LoadImage(hInstance, 
                                 MAKEINTRESOURCE(IDI_APPICON),
                                 IMAGE_ICON,
                                 16, 16,
                                 0);
    wc.style         = CS_HREDRAW | CS_VREDRAW; 

    wc.lpfnWndProc   = (WNDPROC)MainWndProc;    
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPICON));
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszMenuName  = "MAINMENU";
    wc.lpszClassName = title;

    if (!RegisterClassEx(&wc))
           return FALSE;

    hwnd = CreateWindow(title, 
                        title, 
                        WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
                        CW_USEDEFAULT, 0,
                        CW_USEDEFAULT, 0,
                        NULL,
                        NULL,
                        hInstance,
                        NULL);  

    if (!hwnd) {
        return FALSE;
    }
    ShowWindow(hwnd, SW_SHOWNORMAL);
    UpdateWindow(hwnd);

    return TRUE;
}

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance, 
                     LPSTR     lpCmdLine, 
                     int       nCmdShow)
{
    MSG msg;
    HACCEL AccelTable;

    if (!Init(hInstance, nCmdShow))
        return FALSE;

    AccelTable = LoadAccelerators(hInstance, "SHORTCUTS");

    while (GetMessage(&msg, NULL, 0, 0))
        if (!TranslateAccelerator(hwnd, AccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg); 
        }
    return msg.wParam;
}

The, the header:

// notepad.h
#define ID_EXIT                             100
#define ID_FILE_OPEN                        101
#define ID_FILE_SAVE                        102
#define ID_FILE_SAVEAS                      103

#define ID_EDIT_CUT                         201
#define ID_EDIT_COPY                        202
#define ID_EDIT_PASTE                       203
#define ID_EDIT_UNDO                        204
#define ID_EDIT_FIND                        211
#define ID_EDIT_FIND_NEXT                   212
#define ID_EDIT_REPLACE                     213
#define ID_EDIT_SELECT_ALL                  214

#define ID_VIEW_WRAP                        301
#define ID_VIEW_FONT                        302

#define IDI_APPICON                         400

static char title[]     = "Minimum Window";

Note: the header includes defines for a few commands (find/find-next/replace) that aren't implemented in the program.

Then you need a resource file, on this general order:

// notepad.rc
#include "notepad.h"

MAINMENU MENU
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "Open\tCtrl+O",                ID_FILE_OPEN
        MENUITEM "Save\tCtrl+S",                ID_FILE_SAVE
        MENUITEM "Save As",                     ID_FILE_SAVEAS
        MENUITEM "E&xit",                       ID_EXIT
    END
    POPUP "&Edit"
    BEGIN
        MENUITEM "Undo\tCtrl+Z",                ID_EDIT_UNDO
        MENUITEM "Cut\tCtrl+X",                 ID_EDIT_CUT
        MENUITEM "Copy\tCtrl+C",                ID_EDIT_COPY
        MENUITEM "Paste\tCtrl+V",               ID_EDIT_PASTE
        MENUITEM SEPARATOR
        MENUITEM "Find...\tCtrl+F",             ID_EDIT_FIND
        MENUITEM "Find Next",                   ID_EDIT_FIND_NEXT
        MENUITEM "Replace...\tCtrl+H",          ID_EDIT_REPLACE
        MENUITEM "Select All\tCtrl+A",          ID_EDIT_SELECT_ALL
    END
    POPUP "Format"
    BEGIN
        MENUITEM "&Font",                       ID_VIEW_FONT
    END
END

SHORTCUTS ACCELERATORS
BEGIN
    "^O",           ID_FILE_OPEN,           ASCII   
    "^S",           ID_FILE_SAVE,           ASCII   
    "^A",           ID_EDIT_SELECT_ALL,     ASCII   
    "^Z",           ID_EDIT_UNDO,           ASCII   
    "^X",           ID_EDIT_CUT,            ASCII   
    "^C",           ID_EDIT_COPY,           ASCII   
    "^V",           ID_EDIT_PASTE,          ASCII   
END

Although not strictly necessary, a Makefile to build it comes in handy:

notepad.exe: notepad.obj notepad.res
    link notepad.obj user32.lib gdi32.lib comdlg32.lib notepad.res

notepad.res: notepad.rc
    rc -r notepad.rc

notepad.obj: notepad.cpp
    cl -c notepad.cpp

clean:
    del *.res
    del *.obj

So, if you save those into a directory, open a command prompt for Microsoft's compiler, and type nmake in that directory, it should build a notepad.exe , which will be a mildly stripped down version of the normal Windows notepad. It's missing find/replace, printing, and a couple of other things, but at least has enough to give a decent starting point for how to create and use an edit control.

Oh--one other note. This is mostly quickly hacked together from bits and pieces of old code, with a little bit of new duct tape (so to speak) to hold them together. It is not, by any means, exemplary of the best possible coding practices throughout (to put it nicely).

HWND CreateTextBox(CONST INT iX, CONST INT iY, CONST UINT uWidth, CONST UINT uHeight, HWND hWnd, CONST UINT uId, HINSTANCE hInstance)
{
   HWND hWndRet = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("Edit"), NULL, WS_CHILD, iX, iY, (signed)uWidth, (signed)uHeight, hWnd, (HMENU)uId, hInstance, NULL);
   SetBkColor(GetDC(hWndRet), RGB(255, 255, 255));
   return hWndRet;
}

Just a small function I use for creating default, blank text boxes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM