该文章已有更新: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跟随)