Advertisement
Delfigamer

stupid windows

Apr 16th, 2020
650
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.43 KB | None | 0 0
  1. #define WIN32_LEAN_AND_MEAN
  2.  
  3. #include <Windows.h>
  4. #include <cstdio>
  5. #include <string>
  6. #include <vector>
  7.  
  8. struct TextEdit
  9. {
  10.     std::wstring buffer;
  11.     int caret = 0;
  12.  
  13.     wchar_t const* Buffer()
  14.     {
  15.         return buffer.data();
  16.     }
  17.  
  18.     int Length()
  19.     {
  20.         return buffer.size();
  21.     }
  22.  
  23.     void NormalizeCaret()
  24.     {
  25.         if (caret < 0) {
  26.             caret = 0;
  27.         } else if (caret > Length()) {
  28.             caret = buffer.size();
  29.         }
  30.     }
  31.  
  32.     void Insert(wchar_t ch)
  33.     {
  34.         NormalizeCaret();
  35.         buffer.insert(caret, 1, ch);
  36.         caret += 1;
  37.     }
  38.  
  39.     void Insert(std::wstring const& str)
  40.     {
  41.         NormalizeCaret();
  42.         if (!str.empty()) {
  43.             buffer.insert(caret, str);
  44.             caret += str.size();
  45.         }
  46.     }
  47.  
  48.     void EraseLeft()
  49.     {
  50.         NormalizeCaret();
  51.         if (caret > 0) {
  52.             buffer.erase(caret - 1);
  53.             caret -= 1;
  54.         }
  55.     }
  56.  
  57.     void EraseRight()
  58.     {
  59.         NormalizeCaret();
  60.         if (caret < Length()) {
  61.             buffer.erase(caret);
  62.         }
  63.     }
  64.  
  65.     void MoveLeft()
  66.     {
  67.         if (caret > 0) {
  68.             caret -= 1;
  69.         }
  70.     }
  71.  
  72.     void MoveRight()
  73.     {
  74.         if (caret < Length()) {
  75.             caret += 1;
  76.         }
  77.     }
  78.  
  79.     void MoveHome()
  80.     {
  81.         caret = 0;
  82.     }
  83.  
  84.     void MoveEnd()
  85.     {
  86.         caret = buffer.size();
  87.     }
  88. };
  89.  
  90. TextEdit Current;
  91. std::wstring CompositionText;
  92. int CompositionCaret;
  93.  
  94. std::wstring GetCompositionWString(HIMC imc, DWORD index)
  95. {
  96.     int len = ImmGetCompositionStringW(imc, index, nullptr, 0);
  97.     if (len == 0) {
  98.         return {};
  99.     }
  100.     std::wstring str(len / 2, '-');
  101.     ImmGetCompositionStringW(imc, index, (wchar_t*)str.data(), len);
  102.     return str;
  103. }
  104.  
  105. void UpdateComposition(HWND hwnd)
  106. {
  107.     printf("<\n");
  108.     HIMC imc = ImmGetContext(hwnd);
  109.     CompositionText = GetCompositionWString(imc, GCS_COMPSTR);
  110.     CompositionCaret = ImmGetCompositionStringW(imc, GCS_CURSORPOS, nullptr, 0);
  111.     std::wstring result = GetCompositionWString(imc, GCS_RESULTSTR);
  112.     Current.Insert(result);
  113.     ImmReleaseContext(hwnd, imc);
  114.     printf(">\n");
  115. }
  116.  
  117. void WindowPaint(HWND hwnd)
  118. {
  119.     RECT clientrect;
  120.     GetClientRect(hwnd, &clientrect);
  121.     SIZE wndsize = { clientrect.right - clientrect.left, clientrect.bottom - clientrect.top };
  122.  
  123.     PAINTSTRUCT ps;
  124.     HDC wnddc = BeginPaint(hwnd, &ps);
  125.     HBITMAP bitmap = CreateCompatibleBitmap(wnddc, wndsize.cx, wndsize.cy);
  126.     HDC dc = CreateCompatibleDC(wnddc);
  127.     SelectObject(dc, bitmap);
  128.  
  129.     RECT wndrect = { 0, 0, wndsize.cx, wndsize.cy };
  130.     HBRUSH brush = CreateSolidBrush(RGB(255, 255, 255));
  131.     FillRect(dc, &wndrect, brush);
  132.  
  133.     TEXTMETRICW textmetric;
  134.     GetTextMetricsW(dc, &textmetric);
  135.  
  136.     TextOutW(dc, 0, 0, Current.Buffer(), Current.Length());
  137.  
  138.     SIZE textsize;
  139.     GetTextExtentPointW(dc, Current.Buffer(), Current.caret, &textsize);
  140.     MoveToEx(dc, textsize.cx, 0, nullptr);
  141.     LineTo(dc, textsize.cx, textmetric.tmHeight);
  142.  
  143.     TextOutW(dc, 0, textmetric.tmHeight, CompositionText.data(), CompositionText.size());
  144.  
  145.     GetTextExtentPointW(dc, CompositionText.data(), CompositionCaret, &textsize);
  146.     MoveToEx(dc, textsize.cx, textmetric.tmHeight, nullptr);
  147.     LineTo(dc, textsize.cx, textmetric.tmHeight * 2);
  148.  
  149.     BitBlt(wnddc, 0, 0, wndsize.cx, wndsize.cy, dc, 0, 0, SRCCOPY);
  150.     DeleteObject(brush);
  151.     DeleteDC(dc);
  152.     DeleteObject(bitmap);
  153.     EndPaint(hwnd, &ps);
  154. }
  155.  
  156. void ImrQueryCharPosition(HWND hwnd, IMECHARPOSITION* chpos)
  157. {
  158.     wprintf(L"WM_IME_REQUEST IMR_QUERYCHARPOSITION %i\n", chpos->dwCharPos);
  159.     UpdateComposition(hwnd);
  160.     RECT clientrect;
  161.     GetClientRect(hwnd, &clientrect);
  162.     HDC dc = GetDC(hwnd);
  163.     TEXTMETRICW textmetric;
  164.     GetTextMetricsW(dc, &textmetric);
  165.     SIZE textsize;
  166.     GetTextExtentPointW(dc, CompositionText.data(), chpos->dwCharPos, &textsize);
  167.     POINT pt = { textsize.cx, textmetric.tmHeight };
  168.     ClientToScreen(hwnd, &pt);
  169.     chpos->pt = pt;
  170.     chpos->cLineHeight = textmetric.tmHeight;
  171.     POINT client1 = { 0, 0 };
  172.     POINT client2 = { clientrect.right - clientrect.left, textmetric.tmHeight * 2 };
  173.     ClientToScreen(hwnd, &client1);
  174.     ClientToScreen(hwnd, &client2);
  175.     chpos->rcDocument = { client1.x, client1.y, client2.x, client2.y };
  176.     ReleaseDC(hwnd, dc);
  177. }
  178.  
  179. LRESULT CALLBACK WindowProc(
  180.     HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  181. {
  182.     switch (uMsg) {
  183.     case WM_DESTROY:
  184.         PostQuitMessage(0);
  185.         return 0;
  186.     case WM_CHAR:
  187.         wprintf(L"WM_CHAR %#4x'%lc' %3i\n", wParam, (wchar_t)wParam, (lParam >> 16) & 0xff);
  188.         if (wParam == 8) {
  189.             Current.EraseLeft();
  190.         } else if (wParam >= 32) {
  191.             Current.Insert(wParam);
  192.         }
  193.         InvalidateRect(hwnd, nullptr, false);
  194.         return 0;
  195.     case WM_KEYDOWN:
  196.         wprintf(L"WM_KEYDOWN    %4i %3i\n",
  197.             wParam, (lParam >> 16) & 0xff);
  198.         if (wParam == VK_LEFT) {
  199.             Current.MoveLeft();
  200.             InvalidateRect(hwnd, nullptr, false);
  201.         } else if (wParam == VK_RIGHT) {
  202.             Current.MoveRight();
  203.             InvalidateRect(hwnd, nullptr, false);
  204.         } else if (wParam == VK_HOME || wParam == VK_PRIOR || wParam == VK_UP) {
  205.             Current.MoveHome();
  206.             InvalidateRect(hwnd, nullptr, false);
  207.         } else if (wParam == VK_END || wParam == VK_NEXT || wParam == VK_DOWN) {
  208.             Current.MoveEnd();
  209.             InvalidateRect(hwnd, nullptr, false);
  210.         } else if (wParam == VK_DELETE) {
  211.             Current.EraseRight();
  212.             InvalidateRect(hwnd, nullptr, false);
  213.         }
  214.         return DefWindowProcW(hwnd, uMsg, wParam, lParam);
  215.     case WM_KEYUP:
  216.         return DefWindowProcW(hwnd, uMsg, wParam, lParam);
  217.     case WM_IME_SETCONTEXT:
  218.         wprintf(L"WM_IME_SETCONTEXT %i\n",
  219.             wParam);
  220.         return DefWindowProcW(hwnd, uMsg, wParam, lParam);
  221.     case WM_IME_STARTCOMPOSITION:
  222.         UpdateComposition(hwnd);
  223.         wprintf(L"WM_IME_STARTCOMPOSITION '%ls'\n",
  224.             CompositionText.c_str());
  225.         InvalidateRect(hwnd, nullptr, false);
  226.         return 0;
  227.     case WM_IME_COMPOSITION:
  228.         UpdateComposition(hwnd);
  229.         wprintf(L"WM_IME_COMPOSITION '%ls'\n",
  230.             CompositionText.c_str());
  231.         InvalidateRect(hwnd, nullptr, false);
  232.         return 0;
  233.     case WM_IME_COMPOSITIONFULL:
  234.         UpdateComposition(hwnd);
  235.         wprintf(L"WM_IME_COMPOSITIONFULL '%ls'\n",
  236.             CompositionText.c_str());
  237.         InvalidateRect(hwnd, nullptr, false);
  238.         return 0;
  239.     case WM_IME_ENDCOMPOSITION:
  240.         CompositionText.clear();
  241.         wprintf(L"WM_IME_ENDCOMPOSITION\n");
  242.         InvalidateRect(hwnd, nullptr, false);
  243.         return 0;
  244.     case WM_IME_SELECT:
  245.         wprintf(L"WM_IME_SELECT %i\n",
  246.             wParam);
  247.         return DefWindowProcW(hwnd, uMsg, wParam, lParam);
  248.     case WM_IME_REQUEST:
  249.         switch (wParam) {
  250.         case IMR_CANDIDATEWINDOW:
  251.             wprintf(L"WM_IME_REQUEST IMR_CANDIDATEWINDOW\n");
  252.             return DefWindowProcW(hwnd, uMsg, wParam, lParam);
  253.         case IMR_COMPOSITIONFONT:
  254.             wprintf(L"WM_IME_REQUEST IMR_COMPOSITIONFONT\n");
  255.             return DefWindowProcW(hwnd, uMsg, wParam, lParam);
  256.         case IMR_COMPOSITIONWINDOW:
  257.             wprintf(L"WM_IME_REQUEST IMR_COMPOSITIONWINDOW\n");
  258.             return DefWindowProcW(hwnd, uMsg, wParam, lParam);
  259.         case IMR_CONFIRMRECONVERTSTRING:
  260.             wprintf(L"WM_IME_REQUEST IMR_CONFIRMRECONVERTSTRING\n");
  261.             return DefWindowProcW(hwnd, uMsg, wParam, lParam);
  262.         case IMR_DOCUMENTFEED:
  263.             wprintf(L"WM_IME_REQUEST IMR_DOCUMENTFEED\n");
  264.             return 0;
  265.         case IMR_QUERYCHARPOSITION:
  266.             ImrQueryCharPosition(hwnd, (IMECHARPOSITION*)lParam);
  267.             return true;
  268.         case IMR_RECONVERTSTRING:
  269.             wprintf(L"WM_IME_REQUEST IMR_RECONVERTSTRING\n");
  270.             return DefWindowProcW(hwnd, uMsg, wParam, lParam);
  271.         default:
  272.             wprintf(L"WM_IME_REQUEST %i\n", wParam);
  273.             return DefWindowProcW(hwnd, uMsg, wParam, lParam);
  274.         }
  275.     case WM_IME_NOTIFY:
  276.         switch (wParam) {
  277.         case IMN_CHANGECANDIDATE:
  278.             wprintf(L"WM_IME_NOTIFY IMN_CHANGECANDIDATE\n");
  279.             return 0;
  280.         case IMN_CLOSECANDIDATE:
  281.             wprintf(L"WM_IME_NOTIFY IMN_CLOSECANDIDATE\n");
  282.             return 0;
  283.         case IMN_CLOSESTATUSWINDOW:
  284.             wprintf(L"WM_IME_NOTIFY IMN_CLOSESTATUSWINDOW\n");
  285.             return 0;
  286.         case IMN_GUIDELINE:
  287.             wprintf(L"WM_IME_NOTIFY IMN_GUIDELINE\n");
  288.             return 0;
  289.         case IMN_OPENCANDIDATE:
  290.             wprintf(L"WM_IME_NOTIFY IMN_OPENCANDIDATE\n");
  291.             return 0;
  292.         case IMN_OPENSTATUSWINDOW:
  293.             wprintf(L"WM_IME_NOTIFY IMN_OPENSTATUSWINDOW\n");
  294.             return 0;
  295.         case IMN_SETCANDIDATEPOS:
  296.             wprintf(L"WM_IME_NOTIFY IMN_SETCANDIDATEPOS\n");
  297.             return 0;
  298.         case IMN_SETCOMPOSITIONFONT:
  299.             wprintf(L"WM_IME_NOTIFY IMN_SETCOMPOSITIONFONT\n");
  300.             return 0;
  301.         case IMN_SETCOMPOSITIONWINDOW:
  302.             wprintf(L"WM_IME_NOTIFY IMN_SETCOMPOSITIONWINDOW\n");
  303.             return 0;
  304.         case IMN_SETCONVERSIONMODE:
  305.             wprintf(L"WM_IME_NOTIFY IMN_SETCONVERSIONMODE\n");
  306.             return 0;
  307.         case IMN_SETOPENSTATUS:
  308.             wprintf(L"WM_IME_NOTIFY IMN_SETOPENSTATUS\n");
  309.             return 0;
  310.         case IMN_SETSENTENCEMODE:
  311.             wprintf(L"WM_IME_NOTIFY IMN_SETSENTENCEMODE\n");
  312.             return 0;
  313.         case IMN_SETSTATUSWINDOWPOS:
  314.             wprintf(L"WM_IME_NOTIFY IMN_SETSTATUSWINDOWPOS\n");
  315.             return 0;
  316.         default:
  317.             wprintf(L"WM_IME_NOTIFY %i\n", wParam);
  318.             return DefWindowProcW(hwnd, uMsg, wParam, lParam);
  319.         }
  320.     case WM_PAINT:
  321.         wprintf(L"WM_PAINT\n");
  322.         WindowPaint(hwnd);
  323.         return 0;
  324.     default:
  325.         return DefWindowProcW(hwnd, uMsg, wParam, lParam);
  326.     }
  327. }
  328.  
  329. int CALLBACK WinMain(
  330.     HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  331. {
  332.     AllocConsole();
  333.     freopen("CONOUT$", "w", stdout);
  334.     const DWORD WindowStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_BORDER | WS_MINIMIZEBOX;
  335.     WNDCLASSW wndclass;
  336.     wndclass.style = CS_VREDRAW | CS_HREDRAW;
  337.     wndclass.lpfnWndProc = &WindowProc;
  338.     wndclass.cbClsExtra = 8;
  339.     wndclass.cbWndExtra = 0;
  340.     wndclass.hInstance = hInstance;
  341.     wndclass.hIcon = LoadIcon(0, IDI_APPLICATION);
  342.     wndclass.hCursor = LoadCursor(0, IDC_ARROW);
  343.     wndclass.hbrBackground = 0;
  344.     wndclass.lpszMenuName = 0;
  345.     wndclass.lpszClassName = L"MyWindowClass";
  346.     RegisterClassW(&wndclass);
  347.     RECT WindowRect = { 0, 0, 800, 600 };
  348.     AdjustWindowRect(
  349.         &WindowRect, WindowStyle, false);
  350.     HWND hwnd = CreateWindowW(
  351.         L"MyWindowClass",
  352.         L"window",
  353.         WindowStyle,
  354.         20,
  355.         20,
  356.         WindowRect.right - WindowRect.left,
  357.         WindowRect.bottom - WindowRect.top,
  358.         0,
  359.         0,
  360.         hInstance,
  361.         0);
  362.     ShowWindow(hwnd, SW_SHOW);
  363.     UpdateWindow(hwnd);
  364.     MSG message = { 0, 0, 0, 0 };
  365.     while (GetMessageW(&message, hwnd, 0, 0) > 0) {
  366.         printf("-");
  367.         TranslateMessage(&message);
  368.         DispatchMessageW(&message);
  369.     }
  370.     return 0;
  371. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement