仿照windows记事本实验

一个仿照windows系统的记事本(vs2022),顺便问个问题,怎么实现这个剪切功能?


#include <Windows.h>
#include <CommCtrl.h>
#include <fstream>
#include<string>
#include<vector>

#pragma comment(lib, "comctl32.lib")
static HWND hEdit;
static LOGFONT lf = { 0 };
#define CHAR_PER_LINE   1000
HFONT printt;
// 窗口类名和菜单ID
const CHAR g_szClassName[] = "MyNotepadWndClass";
const int IDM_FILE_OPEN = 1001;
const int IDM_FILE_SAVE = 1002;
const int IDM_FILE_EXIT = 1003;
const int IDM_FORMAT_FONT = 2001;
const int IDM_FORMAT_SIZE = 2002;
#define IDM_FILE_PRINT 2345
#define IDM_EDIT_COPY 23456
#define IDM_EDIT_CUT 986
#define IDM_EDIT_PASTE 5678
const int IDM_HELP_ABOUT = 9903;
// 控件ID
void SetAppAsDefaultForFileExtension(const char* fileExtension, const char* appName, const char* appPath) {
    // 创建注册表键值
    HKEY hKey = NULL;
    if (RegCreateKeyExA(HKEY_CURRENT_USER, "SOFTWARE\\Classes", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS)
    {
        // 设置文件扩展名关联
        HKEY hExtKey = NULL;
        if (RegCreateKeyExA(hKey, fileExtension, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hExtKey, NULL) == ERROR_SUCCESS)
        {
            RegSetValueExA(hExtKey, NULL, 0, REG_SZ, (const BYTE*)appName, strlen(appName) + 1);
            RegCloseKey(hExtKey);
        }

        // 设置应用程序关联
        HKEY hAppKey = NULL;
        if (RegCreateKeyExA(hKey, appName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hAppKey, NULL) == ERROR_SUCCESS)
        {
            HKEY hCommandKey = NULL;
            if (RegCreateKeyExA(hAppKey, "shell\\open\\command", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hCommandKey, NULL) == ERROR_SUCCESS)
            {
                std::string command = appPath;
                command.append(" \"%1\"");

                RegSetValueExA(hCommandKey, NULL, 0, REG_SZ, (const BYTE*)command.c_str(), command.length() + 1);
                RegCloseKey(hCommandKey);
            }

            RegCloseKey(hAppKey);
        }

        RegCloseKey(hKey);
    }
}
const int IDC_EDIT = 100;
WINUSERAPI int WINAPI Edit_GetText(_In_ HWND hWnd, _Out_writes_to_(cchTextMax, return) LPSTR lpchText, _In_ int cchTextMax);
WINUSERAPI BOOL WINAPI Edit_SetSel(_In_ HWND hWnd, _In_ int nStartChar, _In_ int nEndChar);

void DoFilePrint(HWND hwnd, HFONT font) {
    HDC hdc = GetDC(hwnd);
    DOCINFO di = { sizeof(DOCINFO), "Print Job" };

    if (StartDoc(hdc, &di) > 0) {
        TEXTMETRIC tm;
        GetTextMetrics(hdc, &tm);

        int lineHeight = tm.tmHeight + tm.tmExternalLeading;
        int pageCount = 0;

        // 获取编辑框的文本
        int textLength = GetWindowTextLength(hwnd);
        char* buffer = new char[textLength + 1];
        GetWindowText(hwnd, buffer, textLength + 1);

        RECT rect;
        GetClientRect(hwnd, &rect);

        int y = 0;

        // 分页打印
        for (int i = 0; i < textLength; i += rect.bottom / lineHeight) {
            int remainingChars = textLength - i;
            int charsToPrint = min(rect.bottom / lineHeight, remainingChars);

            // 创建一页的打印页面
            HDC printHdc = CreateCompatibleDC(hdc);
            HBITMAP printBmp = CreateCompatibleBitmap(hdc, rect.right, rect.bottom);
            SelectObject(printHdc, printBmp);
            SelectObject(printHdc, font);

            // 设置打印页面的背景色和文本颜色
            SetBkColor(printHdc, GetSysColor(COLOR_WINDOW));
            SetTextColor(printHdc, GetSysColor(COLOR_WINDOWTEXT));

            // 打印文本
            RECT printRect = { 0, 0, rect.right, lineHeight };
            DrawText(printHdc, buffer + i, charsToPrint, &printRect, DT_LEFT);

            // 打印页面
            BitBlt(hdc, 0, y, rect.right, rect.bottom, printHdc, 0, 0, SRCCOPY);

            // 清除打印页面资源
            DeleteDC(printHdc);
            DeleteObject(printBmp);

            y += rect.bottom;
            pageCount++;
        }

        // 结束打印任务
        EndDoc(hdc);

        delete[] buffer;
    }

    ReleaseDC(hwnd, hdc);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    
    static OPENFILENAME ofn;
    static char szFileName[MAX_PATH] = "";
    static CHOOSEFONT cf;
    

    switch (msg)
    {
    case WM_CREATE:
    {
        // 创建编辑框控件
        hEdit = CreateWindowEx(
            0,
            "EDIT",
            "",
            WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL,
            0, 0, 0, 0,
            hwnd,
            (HMENU)IDC_EDIT,
            GetModuleHandle(NULL),
            NULL
        );

        // 创建菜单
        HMENU hMenu, hSubMenu;
        hMenu = CreateMenu();
        hSubMenu = CreatePopupMenu();
        AppendMenu(hSubMenu, MF_STRING, IDM_FILE_OPEN, "打开(&O)");
        AppendMenu(hSubMenu, MF_STRING, IDM_FILE_SAVE, "保存(&S)");
        AppendMenu(hSubMenu, MF_STRING, IDM_FILE_PRINT, "打印(&P)");
        AppendMenu(hSubMenu, MF_SEPARATOR, 0, NULL);
        AppendMenu(hSubMenu, MF_STRING, IDM_FILE_EXIT, "退出(&X)");
        AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hSubMenu, "文件(&F)");

        // 增加格式菜单
        hSubMenu = CreatePopupMenu();
        AppendMenu(hSubMenu, MF_STRING, IDM_FORMAT_FONT, "字体(&F)");
        
        AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hSubMenu, "格式(&O)");
        hSubMenu = CreatePopupMenu();
        AppendMenu(hSubMenu, MF_STRING, IDM_EDIT_COPY, "复制");
        AppendMenu(hSubMenu, MF_STRING, IDM_EDIT_CUT, "剪切(暂时不可使用)");
        AppendMenu(hSubMenu, MF_STRING, IDM_EDIT_PASTE, "粘贴");
        AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hSubMenu, "编辑");
        hSubMenu = CreatePopupMenu();
        AppendMenu(hSubMenu, MF_STRING, IDM_HELP_ABOUT, "关于");
        AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hSubMenu, "帮助");
        SetMenu(hwnd, hMenu);

        // 初始化打开文件对话框
        ZeroMemory(&ofn, sizeof(ofn));
        ofn.lStructSize = sizeof(ofn);
        ofn.hwndOwner = hwnd;
        ofn.lpstrFilter = "文本文件(*.txt)\0*.txt\0所有文件(*.*)\0*.*\0";
        ofn.lpstrFile = szFileName;
        ofn.nMaxFile = MAX_PATH;
        ofn.lpstrDefExt = "txt";

        // 初始化字体选择对话框
        ZeroMemory(&cf, sizeof(cf));
        cf.lStructSize = sizeof(cf);
        cf.hwndOwner = hwnd;
        cf.lpLogFont = &lf;
        cf.Flags = CF_SCREENFONTS | CF_EFFECTS;

        
        INITCOMMONCONTROLSEX ic;
        ic.dwSize = sizeof(ic);
        ic.dwICC = ICC_STANDARD_CLASSES;
        InitCommonControlsEx(&ic);

        break;
    }

    case WM_SIZE:
    {
        // 调整编辑框尺寸
        RECT rcClient;
        GetClientRect(hwnd, &rcClient);
        SetWindowPos(hEdit, NULL, 0, 0, rcClient.right, rcClient.bottom, SWP_NOZORDER);
        break;
    }

    case WM_COMMAND:
    {
        switch (LOWORD(wParam))
        {
            // 处理打开文件命令
        case IDM_FILE_OPEN:
        {
            // 打开文件
            

            if (GetOpenFileName(&ofn) == TRUE)
            {
                std::ifstream file(ofn.lpstrFile, std::ios::binary);
                if (file.is_open())
                {
                    // 清空编辑框内容
                    SendMessage(hEdit, WM_SETTEXT, 0, (LPARAM)L"");

                    // 获取文件大小
                    file.seekg(0, std::ios::end);
                    std::streamsize fileSize = file.tellg();
                    file.seekg(0, std::ios::beg);

                    // 分配内存存储文件内容
                    std::vector<char> buffer(fileSize);
                    file.read(buffer.data(), fileSize);

                    // 关闭文件
                    file.close();

                    // 转换编码并显示文本
                    int requiredSize = MultiByteToWideChar(CP_UTF8, 0, buffer.data(), fileSize, nullptr, 0);
                    std::wstring text(requiredSize, L'\0');
                    MultiByteToWideChar(CP_UTF8, 0, buffer.data(), fileSize, &text[0], requiredSize);

                    SetWindowTextW(hEdit, text.c_str());
                }
            }
            break;
        }

        // 处理保存文件命令
        // 处理保存文件命令
        case IDM_FILE_SAVE:
        {
            if (GetSaveFileName(&ofn) == TRUE)
            {
                std::ofstream file(ofn.lpstrFile);
                if (file.is_open())
                {
                    // 将编辑框中的文本保存到文件
                    int nLength = GetWindowTextLength(hEdit);
                    char* pBuffer = new char[nLength + 1];
                    memset(pBuffer, 0, nLength + 1);
                    GetWindowText(hEdit, pBuffer, nLength + 1);
                    file << pBuffer;
                    file.close();
                    delete[] pBuffer;
                }
            }
            break;
        }
        case IDM_HELP_ABOUT: {
            MessageBox(hwnd, "记事本实验版1.3.3\n李想制作\n详情请见官网:\nwww.lixiangnotepad.com", "记事本实验版", MB_OK | MB_ICONINFORMATION);
            break;
        }

        // 处理退出命令
        case IDM_FILE_EXIT:
            DestroyWindow(hwnd);
            break;

            // 处理字体命令
     
        // 处理字号命令
        case IDM_FORMAT_FONT:
        {
            CHOOSEFONT cfSize;
            LOGFONT lfSize = { 0 };
            ZeroMemory(&cfSize, sizeof(cfSize));
            cfSize.lStructSize = sizeof(cfSize);
            cfSize.hwndOwner = hwnd;
            cfSize.lpLogFont = &lfSize;
            cfSize.Flags = CF_SCREENFONTS | CF_EFFECTS | CF_INITTOLOGFONTSTRUCT;
            cfSize.nSizeMin = 8;
            cfSize.nSizeMax = 72;
            if (ChooseFont(&cfSize) == TRUE)
            {
                // 设置编辑框字号
                int nFontSize; // 存储字体大小

// 获取字体大小
                HFONT hFont = CreateFontIndirect(&lfSize);
                printt = hFont;
                SendMessage(hEdit, WM_SETFONT, (WPARAM)hFont, TRUE);
            }
            break;
        }
       
        case IDM_EDIT_PASTE:
            SendMessage(hEdit, WM_PASTE, 0, 0);
            break;
        case IDM_EDIT_COPY: {
            SendMessage(hEdit, WM_COPY, 0, 0);
            break;
        }
        case IDM_FILE_PRINT: {
            DoFilePrint(hwnd, printt);
            break;
        }
        }
        break;
    }

    // 处理窗口关闭事件
    case WM_CLOSE:
        DestroyWindow(hwnd);
        break;

        // 处理窗口销毁事件
    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }

    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    // 1. 注册窗口类
    WNDCLASSEX wc;
    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.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    if (!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "窗口类注册失败!", "Error", MB_ICONERROR);
        return 0;
    }
    const char* appName = "MyNotepad";
    const char* appPath = "C:\\Path\\To\\Your\\Program.exe";

    // 设置默认打开TXT文件的程序
    SetAppAsDefaultForFileExtension(".txt", appName, appPath);
    // 2. 创建窗口
    HWND hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        g_szClassName,
        "My Notepad",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
        NULL, NULL, hInstance, NULL
    );

    if (hwnd == NULL)
    {
        MessageBox(NULL, "窗口创建失败!", "Error", MB_ICONERROR);
        return 0;
    }

    // 3. 显示窗口
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // 4. 消息循环
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值