什么是C创建编辑框最简单的方法++

问题描述 投票:0回答:2

我需要建立在C编辑框中++不使用MFC ..... 唯一的win32

c++ visual-c++ winapi textarea
2个回答
2
投票

CreateWindow("EDIT", ...);。您可以使用CreateWindowEx如果你喜欢,但它是没有必要的。要使用它,你也通常会希望有你的窗口响应调用WM_FOCUS将焦点设置在编辑控制SetFocus。您通常还需要应对WM_MOVE(或者是WM_SIZE - 我不记得了),通过调整编辑控件,以适应父窗口的客户区。

当然,你也可以创建一个包含编辑控件对话框(DialogBoxDialogBoxEx)。这避免了手动设置聚焦和这样。

所以,这里有一个简单的演示程序。这将创建一个主窗口,并与编辑控件填充其客户区。它可以打开和保存文件,请在控制数据的剪切/复制/粘贴,并选择其中的控件来显示数据的字体。它的加速器表,所以它知道的通常的键盘快捷键最那些(例如,CTRL-X =切,CTRL-C =复制,CTRL-V =膏)。

首先,主源代码:

// 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;
}

的,标题:

// 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";

注意:标头包括用于一些命令(查找/找到-下一个/替换)未在该程序实现的定义。

然后,你需要一个资源文件,这个一般顺序:

// 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

虽然不是绝对必要,一个Makefile来构建它派上用场:

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

所以,如果你保存这些放到一个目录中,打开微软的编译器在命令提示符下,并在该目录中键入nmake,应该建立一个notepad.exe,这将是正常的Windows记事本的轻度精简版。它遗漏查找/替换,打印,和几个其他的事情,但至少已经足以让对如何创建和使用的编辑控制一个像样的起点。

哦 - 另外一个音符。这主要是迅速从位和旧代码千刀万剐在一起,用新的胶带一点点(这么说)来结合在一起。这是不以任何方式,示范贯穿最佳可能的编码实践(说得好听)。


1
投票
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;
}

只是一个小功能,我用来创建默认的空白文本框。

© www.soinside.com 2019 - 2024. All rights reserved.