EasyX 简易输入框补充——输入法跟随
[編輯] [转简体] (简体译文)
|
作者:huidong
| 分類:【編程】EasyX
[
10 瀏覽
0 評論
2 贊
3 踩
]
概要
正文
之前写了一个简易输入框:http://huidong.xyz/index.php?mode=2&id=261
昨天看到 BestAns 发布的文章(https://codebus.cn/bestans/textbox-sample )也是一个输入框
可惜还没有实现输入法跟随和鼠标交互操作,我只有周末一点时间,鼠标交互写起来比较耗时,所以先把输入法跟随实现了。
由于我之前写的那个输入框已经有了输入法锁定,现在只需要改成输入法跟随即可,还是比较简单的。
在尝试的过程中我还发现:当时六月份写这个输入框的时候用的是 easyx 2021.1.12,这个版本可以直接用 _getwch() 函数获取中文输入。
但是现在我换成了 EasyX 20210730,已经不支持用 _getwch() 了,必须用 ExMessage 相关函数获取 EM_CHAR 消息。
所以这里也改成了使用 peekmessage 函数来获取按键输入。需要注意的是,这个函数获取的换行消息只有 '\r' 而没有 '\n'。
代码:
#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; int x, y; 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 = x; Composition.ptCurrentPos.y = y; ImmSetCompositionWindow(hIMC, &Composition);//设置 ImmReleaseContext(GetHWnd(), hIMC);//释放 } } default: return CallWindowProc(OldProc, hWnd, message, wParam, lParam); } } int GetImmX(wstring str) { wstring line; for (int i = str.size() - 1; i >= 0; i--) { if (str[i] == L'\n') { break; } line += str[i]; } return textwidth(line.c_str()); } int GetImmY(wstring str) { RECT r = { 0 }; int h = drawtext(str.c_str(), &r, DT_NOCLIP | DT_LEFT | DT_TOP); h -= textheight('T'); return h >= 0 ? h : 0; } 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"EasyX " + (wstring)GetEasyXVer() + L"\n在此输入文字:"; int nTimeTag = 0; int width = 0; int height = 0; ExMessage msg; while (true) { int nTimeUnit = clock() / 800; if (peekmessage(&msg, EM_CHAR)) { wchar_t word = msg.ch; // 规范为 \n if(word == L'\r') { word = L'\n'; } if (word == L'\b') { if (strText.length()) { strText = strText.substr(0, strText.size() - 1); } } else { strText += word; } // 更新 Imm 位置 x = GetImmX(strText); y = GetImmY(strText); } cleardevice(); drawtext((strText + L"_").c_str(), &rct, DT_LEFT | DT_TOP); FlushBatchDraw(); } EndBatchDraw(); closegraph(); return 0; }
运行效果