Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define WIN32_LEAN_AND_MEAN
- #include <Windows.h>
- #include <cstdio>
- #include <string>
- #include <vector>
- struct TextEdit
- {
- std::wstring buffer;
- int caret = 0;
- wchar_t const* Buffer()
- {
- return buffer.data();
- }
- int Length()
- {
- return buffer.size();
- }
- void NormalizeCaret()
- {
- if (caret < 0) {
- caret = 0;
- } else if (caret > Length()) {
- caret = buffer.size();
- }
- }
- void Insert(wchar_t ch)
- {
- NormalizeCaret();
- buffer.insert(caret, 1, ch);
- caret += 1;
- }
- void Insert(std::wstring const& str)
- {
- NormalizeCaret();
- if (!str.empty()) {
- buffer.insert(caret, str);
- caret += str.size();
- }
- }
- void EraseLeft()
- {
- NormalizeCaret();
- if (caret > 0) {
- buffer.erase(caret - 1);
- caret -= 1;
- }
- }
- void EraseRight()
- {
- NormalizeCaret();
- if (caret < Length()) {
- buffer.erase(caret);
- }
- }
- void MoveLeft()
- {
- if (caret > 0) {
- caret -= 1;
- }
- }
- void MoveRight()
- {
- if (caret < Length()) {
- caret += 1;
- }
- }
- void MoveHome()
- {
- caret = 0;
- }
- void MoveEnd()
- {
- caret = buffer.size();
- }
- };
- TextEdit Current;
- std::wstring CompositionText;
- int CompositionCaret;
- std::wstring GetCompositionWString(HIMC imc, DWORD index)
- {
- int len = ImmGetCompositionStringW(imc, index, nullptr, 0);
- if (len == 0) {
- return {};
- }
- std::wstring str(len / 2, '-');
- ImmGetCompositionStringW(imc, index, (wchar_t*)str.data(), len);
- return str;
- }
- void UpdateComposition(HWND hwnd)
- {
- printf("<\n");
- HIMC imc = ImmGetContext(hwnd);
- CompositionText = GetCompositionWString(imc, GCS_COMPSTR);
- CompositionCaret = ImmGetCompositionStringW(imc, GCS_CURSORPOS, nullptr, 0);
- std::wstring result = GetCompositionWString(imc, GCS_RESULTSTR);
- Current.Insert(result);
- ImmReleaseContext(hwnd, imc);
- printf(">\n");
- }
- void WindowPaint(HWND hwnd)
- {
- RECT clientrect;
- GetClientRect(hwnd, &clientrect);
- SIZE wndsize = { clientrect.right - clientrect.left, clientrect.bottom - clientrect.top };
- PAINTSTRUCT ps;
- HDC wnddc = BeginPaint(hwnd, &ps);
- HBITMAP bitmap = CreateCompatibleBitmap(wnddc, wndsize.cx, wndsize.cy);
- HDC dc = CreateCompatibleDC(wnddc);
- SelectObject(dc, bitmap);
- RECT wndrect = { 0, 0, wndsize.cx, wndsize.cy };
- HBRUSH brush = CreateSolidBrush(RGB(255, 255, 255));
- FillRect(dc, &wndrect, brush);
- TEXTMETRICW textmetric;
- GetTextMetricsW(dc, &textmetric);
- TextOutW(dc, 0, 0, Current.Buffer(), Current.Length());
- SIZE textsize;
- GetTextExtentPointW(dc, Current.Buffer(), Current.caret, &textsize);
- MoveToEx(dc, textsize.cx, 0, nullptr);
- LineTo(dc, textsize.cx, textmetric.tmHeight);
- TextOutW(dc, 0, textmetric.tmHeight, CompositionText.data(), CompositionText.size());
- GetTextExtentPointW(dc, CompositionText.data(), CompositionCaret, &textsize);
- MoveToEx(dc, textsize.cx, textmetric.tmHeight, nullptr);
- LineTo(dc, textsize.cx, textmetric.tmHeight * 2);
- BitBlt(wnddc, 0, 0, wndsize.cx, wndsize.cy, dc, 0, 0, SRCCOPY);
- DeleteObject(brush);
- DeleteDC(dc);
- DeleteObject(bitmap);
- EndPaint(hwnd, &ps);
- }
- void ImrQueryCharPosition(HWND hwnd, IMECHARPOSITION* chpos)
- {
- wprintf(L"WM_IME_REQUEST IMR_QUERYCHARPOSITION %i\n", chpos->dwCharPos);
- UpdateComposition(hwnd);
- RECT clientrect;
- GetClientRect(hwnd, &clientrect);
- HDC dc = GetDC(hwnd);
- TEXTMETRICW textmetric;
- GetTextMetricsW(dc, &textmetric);
- SIZE textsize;
- GetTextExtentPointW(dc, CompositionText.data(), chpos->dwCharPos, &textsize);
- POINT pt = { textsize.cx, textmetric.tmHeight };
- ClientToScreen(hwnd, &pt);
- chpos->pt = pt;
- chpos->cLineHeight = textmetric.tmHeight;
- POINT client1 = { 0, 0 };
- POINT client2 = { clientrect.right - clientrect.left, textmetric.tmHeight * 2 };
- ClientToScreen(hwnd, &client1);
- ClientToScreen(hwnd, &client2);
- chpos->rcDocument = { client1.x, client1.y, client2.x, client2.y };
- ReleaseDC(hwnd, dc);
- }
- LRESULT CALLBACK WindowProc(
- HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- switch (uMsg) {
- case WM_DESTROY:
- PostQuitMessage(0);
- return 0;
- case WM_CHAR:
- wprintf(L"WM_CHAR %#4x'%lc' %3i\n", wParam, (wchar_t)wParam, (lParam >> 16) & 0xff);
- if (wParam == 8) {
- Current.EraseLeft();
- } else if (wParam >= 32) {
- Current.Insert(wParam);
- }
- InvalidateRect(hwnd, nullptr, false);
- return 0;
- case WM_KEYDOWN:
- wprintf(L"WM_KEYDOWN %4i %3i\n",
- wParam, (lParam >> 16) & 0xff);
- if (wParam == VK_LEFT) {
- Current.MoveLeft();
- InvalidateRect(hwnd, nullptr, false);
- } else if (wParam == VK_RIGHT) {
- Current.MoveRight();
- InvalidateRect(hwnd, nullptr, false);
- } else if (wParam == VK_HOME || wParam == VK_PRIOR || wParam == VK_UP) {
- Current.MoveHome();
- InvalidateRect(hwnd, nullptr, false);
- } else if (wParam == VK_END || wParam == VK_NEXT || wParam == VK_DOWN) {
- Current.MoveEnd();
- InvalidateRect(hwnd, nullptr, false);
- } else if (wParam == VK_DELETE) {
- Current.EraseRight();
- InvalidateRect(hwnd, nullptr, false);
- }
- return DefWindowProcW(hwnd, uMsg, wParam, lParam);
- case WM_KEYUP:
- return DefWindowProcW(hwnd, uMsg, wParam, lParam);
- case WM_IME_SETCONTEXT:
- wprintf(L"WM_IME_SETCONTEXT %i\n",
- wParam);
- return DefWindowProcW(hwnd, uMsg, wParam, lParam);
- case WM_IME_STARTCOMPOSITION:
- UpdateComposition(hwnd);
- wprintf(L"WM_IME_STARTCOMPOSITION '%ls'\n",
- CompositionText.c_str());
- InvalidateRect(hwnd, nullptr, false);
- return 0;
- case WM_IME_COMPOSITION:
- UpdateComposition(hwnd);
- wprintf(L"WM_IME_COMPOSITION '%ls'\n",
- CompositionText.c_str());
- InvalidateRect(hwnd, nullptr, false);
- return 0;
- case WM_IME_COMPOSITIONFULL:
- UpdateComposition(hwnd);
- wprintf(L"WM_IME_COMPOSITIONFULL '%ls'\n",
- CompositionText.c_str());
- InvalidateRect(hwnd, nullptr, false);
- return 0;
- case WM_IME_ENDCOMPOSITION:
- CompositionText.clear();
- wprintf(L"WM_IME_ENDCOMPOSITION\n");
- InvalidateRect(hwnd, nullptr, false);
- return 0;
- case WM_IME_SELECT:
- wprintf(L"WM_IME_SELECT %i\n",
- wParam);
- return DefWindowProcW(hwnd, uMsg, wParam, lParam);
- case WM_IME_REQUEST:
- switch (wParam) {
- case IMR_CANDIDATEWINDOW:
- wprintf(L"WM_IME_REQUEST IMR_CANDIDATEWINDOW\n");
- return DefWindowProcW(hwnd, uMsg, wParam, lParam);
- case IMR_COMPOSITIONFONT:
- wprintf(L"WM_IME_REQUEST IMR_COMPOSITIONFONT\n");
- return DefWindowProcW(hwnd, uMsg, wParam, lParam);
- case IMR_COMPOSITIONWINDOW:
- wprintf(L"WM_IME_REQUEST IMR_COMPOSITIONWINDOW\n");
- return DefWindowProcW(hwnd, uMsg, wParam, lParam);
- case IMR_CONFIRMRECONVERTSTRING:
- wprintf(L"WM_IME_REQUEST IMR_CONFIRMRECONVERTSTRING\n");
- return DefWindowProcW(hwnd, uMsg, wParam, lParam);
- case IMR_DOCUMENTFEED:
- wprintf(L"WM_IME_REQUEST IMR_DOCUMENTFEED\n");
- return 0;
- case IMR_QUERYCHARPOSITION:
- ImrQueryCharPosition(hwnd, (IMECHARPOSITION*)lParam);
- return true;
- case IMR_RECONVERTSTRING:
- wprintf(L"WM_IME_REQUEST IMR_RECONVERTSTRING\n");
- return DefWindowProcW(hwnd, uMsg, wParam, lParam);
- default:
- wprintf(L"WM_IME_REQUEST %i\n", wParam);
- return DefWindowProcW(hwnd, uMsg, wParam, lParam);
- }
- case WM_IME_NOTIFY:
- switch (wParam) {
- case IMN_CHANGECANDIDATE:
- wprintf(L"WM_IME_NOTIFY IMN_CHANGECANDIDATE\n");
- return 0;
- case IMN_CLOSECANDIDATE:
- wprintf(L"WM_IME_NOTIFY IMN_CLOSECANDIDATE\n");
- return 0;
- case IMN_CLOSESTATUSWINDOW:
- wprintf(L"WM_IME_NOTIFY IMN_CLOSESTATUSWINDOW\n");
- return 0;
- case IMN_GUIDELINE:
- wprintf(L"WM_IME_NOTIFY IMN_GUIDELINE\n");
- return 0;
- case IMN_OPENCANDIDATE:
- wprintf(L"WM_IME_NOTIFY IMN_OPENCANDIDATE\n");
- return 0;
- case IMN_OPENSTATUSWINDOW:
- wprintf(L"WM_IME_NOTIFY IMN_OPENSTATUSWINDOW\n");
- return 0;
- case IMN_SETCANDIDATEPOS:
- wprintf(L"WM_IME_NOTIFY IMN_SETCANDIDATEPOS\n");
- return 0;
- case IMN_SETCOMPOSITIONFONT:
- wprintf(L"WM_IME_NOTIFY IMN_SETCOMPOSITIONFONT\n");
- return 0;
- case IMN_SETCOMPOSITIONWINDOW:
- wprintf(L"WM_IME_NOTIFY IMN_SETCOMPOSITIONWINDOW\n");
- return 0;
- case IMN_SETCONVERSIONMODE:
- wprintf(L"WM_IME_NOTIFY IMN_SETCONVERSIONMODE\n");
- return 0;
- case IMN_SETOPENSTATUS:
- wprintf(L"WM_IME_NOTIFY IMN_SETOPENSTATUS\n");
- return 0;
- case IMN_SETSENTENCEMODE:
- wprintf(L"WM_IME_NOTIFY IMN_SETSENTENCEMODE\n");
- return 0;
- case IMN_SETSTATUSWINDOWPOS:
- wprintf(L"WM_IME_NOTIFY IMN_SETSTATUSWINDOWPOS\n");
- return 0;
- default:
- wprintf(L"WM_IME_NOTIFY %i\n", wParam);
- return DefWindowProcW(hwnd, uMsg, wParam, lParam);
- }
- case WM_PAINT:
- wprintf(L"WM_PAINT\n");
- WindowPaint(hwnd);
- return 0;
- default:
- return DefWindowProcW(hwnd, uMsg, wParam, lParam);
- }
- }
- int CALLBACK WinMain(
- HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
- {
- AllocConsole();
- freopen("CONOUT$", "w", stdout);
- const DWORD WindowStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_BORDER | WS_MINIMIZEBOX;
- WNDCLASSW wndclass;
- wndclass.style = CS_VREDRAW | CS_HREDRAW;
- wndclass.lpfnWndProc = &WindowProc;
- wndclass.cbClsExtra = 8;
- wndclass.cbWndExtra = 0;
- wndclass.hInstance = hInstance;
- wndclass.hIcon = LoadIcon(0, IDI_APPLICATION);
- wndclass.hCursor = LoadCursor(0, IDC_ARROW);
- wndclass.hbrBackground = 0;
- wndclass.lpszMenuName = 0;
- wndclass.lpszClassName = L"MyWindowClass";
- RegisterClassW(&wndclass);
- RECT WindowRect = { 0, 0, 800, 600 };
- AdjustWindowRect(
- &WindowRect, WindowStyle, false);
- HWND hwnd = CreateWindowW(
- L"MyWindowClass",
- L"window",
- WindowStyle,
- 20,
- 20,
- WindowRect.right - WindowRect.left,
- WindowRect.bottom - WindowRect.top,
- 0,
- 0,
- hInstance,
- 0);
- ShowWindow(hwnd, SW_SHOW);
- UpdateWindow(hwnd);
- MSG message = { 0, 0, 0, 0 };
- while (GetMessageW(&message, hwnd, 0, 0) > 0) {
- printf("-");
- TranslateMessage(&message);
- DispatchMessageW(&message);
- }
- return 0;
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement