huidong

首页 | 会员登录 | 关于争取 2022 寒假做出汇东网 Ver3.0.0 !
搜索文章


该文章已有更新:http://huidong.xyz/index.php?mode=2&id=343 


easyx在2021.1.12加入了对_getwch()读取中文的支持

这样,确实可以开始做输入框了。做一个完整的输入框控件的方法我已经想出来了,但是现在先做个简易版。

这个输入框支持换行,退格,中英文输入,IME锁定(暂时没跟随)。

贴代码:

#include <stdio.h>
#include <easyx.h>
#include <string>
#include <conio.h>
#include <time.h>
using namespace std;

#include <imm.h>
#pragma comment(lib, "imm32.lib")

WNDPROC OldProc;

LRESULT CALLBACK NewProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_IME_COMPOSITION:
    {
        HIMC hIMC = ImmGetContext(GetHWnd());    // 获取HIMC
        if (hIMC)
        {
            // Set composition window position near caret position
            POINT point;
            GetCaretPos(&point);//获取输入光标位置,存入point结构体

            COMPOSITIONFORM Composition;
            Composition.dwStyle = CFS_POINT;
            Composition.ptCurrentPos.x = 100;
            Composition.ptCurrentPos.y = 100;
            ImmSetCompositionWindow(hIMC, &Composition);//设置

            ImmReleaseContext(GetHWnd(), hIMC);//释放
        }
    }
    default:
        return CallWindowProc(OldProc, hWnd, message, wParam, lParam);
    }
}

int main()
{
    initgraph(640,480);
    setbkcolor(WHITE);
    settextcolor(BLACK);
    BeginBatchDraw();
    cleardevice();
    FlushBatchDraw();

    OldProc = (WNDPROC)GetWindowLong(GetHWnd(), GWL_WNDPROC);
    SetWindowLong(GetHWnd(), GWL_WNDPROC, (LONG)NewProc);

    RECT rct = { 0,0,getwidth(),getheight() };

    wstring strText = L"";

    int nTimeTag = 0;

    int width = 0;
    int height = 0;

    while (true)
    {
        int nTimeUnit = clock() / 800;

        if(_kbhit())
        {
            wchar_t word = _getwch();
            
            if (word == L'\b')
            {
                if (strText.length())
                {
                    strText = strText.substr(0, strText.size() - 1);
                }
            }
            else
            {
                strText += word;
            }
        }
        
        cleardevice();
        drawtext((strText + L"_").c_str(), &rct, DT_LEFT | DT_TOP);
        FlushBatchDraw();
    }

    EndBatchDraw();
    closegraph();
    return 0;
}

使用easyx库(比2021.1.12新的版本),可以直接编译运行


运行后直接打字,可以获取中文。


其中一个亮点就是:IME在窗口内,虽然没有加入IME跟随光标的功能,但是锁定了IME的位置。

这一点的实现方式是:拦截EasyX窗口原生的WndProc函数,通过自己的WndProc函数拦截WM_IME_COMPOSITION消息,再在这里调用IMM库函数来修改IME的位置。

部分代码:

LRESULT CALLBACK NewProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_IME_COMPOSITION:
    {
        HIMC hIMC = ImmGetContext(GetHWnd());    // 获取HIMC
        if (hIMC)
        {
            // Set composition window position near caret position
            POINT point;
            GetCaretPos(&point);//获取输入光标位置,存入point结构体

            COMPOSITIONFORM Composition;
            Composition.dwStyle = CFS_POINT;
            Composition.ptCurrentPos.x = 100;
            Composition.ptCurrentPos.y = 100;
            ImmSetCompositionWindow(hIMC, &Composition);//设置

            ImmReleaseContext(GetHWnd(), hIMC);//释放
        }
    }
    default:
        return CallWindowProc(OldProc, hWnd, message, wParam, lParam);
    }
}


其中设置的Composition.ptCurrentPos.x = 100;Composition.ptCurrentPos.y = 100;指定了IME的位置在【窗口区】的(100, 100)位置。


参考:

https://tieba.baidu.com/p/6014139638?pid=123764910327&cid=0#123764910327 (从中借鉴了拦截EasyX原生的WndProc函数的方法)

https://blog.csdn.net/zzstack/article/details/50999177?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-6.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-6.control (如何修改IME位置,实现IME跟随)



返回首页


Copyright (C) 2018-2022 huidong