Advertisement
Delfigamer

wm_char

Dec 3rd, 2023 (edited)
707
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.62 KB | None | 0 0
  1. #define WIN32_LEAN_AND_MEAN
  2. #define _CRT_SECURE_NO_WARNINGS
  3. #define _SCL_SECURE_NO_WARNINGS
  4.  
  5. #include <Windows.h>
  6. #include <cstdio>
  7. #include <utility>
  8. #include <string>
  9. #include <vector>
  10.  
  11. struct TextEdit {
  12.     std::wstring buffer;
  13.     int caret = 0;
  14.  
  15.     wchar_t const* Buffer() {
  16.         return buffer.data();
  17.     }
  18.  
  19.     int Length() {
  20.         return buffer.size();
  21.     }
  22.  
  23.     void NormalizeCaret() {
  24.         if (caret < 0) {
  25.             caret = 0;
  26.         } else if (caret > Length()) {
  27.             caret = buffer.size();
  28.         }
  29.     }
  30.  
  31.     void Insert(wchar_t ch) {
  32.         NormalizeCaret();
  33.         buffer.insert(caret, 1, ch);
  34.         caret += 1;
  35.     }
  36.  
  37.     void Insert(std::wstring const& str) {
  38.         NormalizeCaret();
  39.         if (!str.empty()) {
  40.             buffer.insert(caret, str);
  41.             caret += str.size();
  42.         }
  43.     }
  44.  
  45.     void EraseLeft() {
  46.         NormalizeCaret();
  47.         if (caret > 0) {
  48.             buffer.erase(caret - 1, 1);
  49.             caret -= 1;
  50.         }
  51.     }
  52.  
  53.     void EraseRight() {
  54.         NormalizeCaret();
  55.         if (caret < Length()) {
  56.             buffer.erase(caret, 1);
  57.         }
  58.     }
  59.  
  60.     void MoveLeft() {
  61.         if (caret > 0) {
  62.             caret -= 1;
  63.         }
  64.     }
  65.  
  66.     void MoveRight() {
  67.         if (caret < Length()) {
  68.             caret += 1;
  69.         }
  70.     }
  71.  
  72.     void MoveHome() {
  73.         caret = 0;
  74.     }
  75.  
  76.     void MoveEnd() {
  77.         caret = buffer.size();
  78.     }
  79. };
  80.  
  81. TextEdit Current;
  82. HPEN CaretPen;
  83.  
  84. void WindowPaint(HWND hwnd) {
  85.     RECT clientrect;
  86.     GetClientRect(hwnd, &clientrect);
  87.     SIZE wndsize = {clientrect.right - clientrect.left, clientrect.bottom - clientrect.top};
  88.  
  89.     PAINTSTRUCT ps;
  90.     HDC wnddc = BeginPaint(hwnd, &ps);
  91.     HBITMAP bitmap = CreateCompatibleBitmap(wnddc, wndsize.cx, wndsize.cy);
  92.     HDC dc = CreateCompatibleDC(wnddc);
  93.     SelectObject(dc, bitmap);
  94.  
  95.     RECT wndrect = {0, 0, wndsize.cx, wndsize.cy};
  96.     HBRUSH brush = CreateSolidBrush(RGB(255, 255, 255));
  97.     FillRect(dc, &wndrect, brush);
  98.  
  99.     TEXTMETRICW textmetric;
  100.     GetTextMetricsW(dc, &textmetric);
  101.  
  102.     int currentx = textmetric.tmHeight;
  103.     int currenty = textmetric.tmHeight;
  104.     SIZE textsize;
  105.  
  106.     TextOutW(dc, currentx, currenty, Current.Buffer(), Current.Length());
  107.  
  108.     GetTextExtentPointW(dc, Current.Buffer(), Current.caret, &textsize);
  109.     SelectObject(dc, CaretPen);
  110.     MoveToEx(dc, currentx + textsize.cx, currenty, nullptr);
  111.     LineTo(dc, currentx + textsize.cx, currenty + textmetric.tmHeight);
  112.  
  113.     BitBlt(wnddc, 0, 0, wndsize.cx, wndsize.cy, dc, 0, 0, SRCCOPY);
  114.     DeleteObject(brush);
  115.     DeleteDC(dc);
  116.     DeleteObject(bitmap);
  117.     EndPaint(hwnd, &ps);
  118. }
  119.  
  120. LRESULT CALLBACK WindowProc(
  121.     HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam
  122. ) {
  123.     switch (uMsg) {
  124.     case WM_CREATE:
  125.         CaretPen = CreatePen(PS_SOLID, 0, RGB(0, 0, 0));
  126.         return 0;
  127.     case WM_DESTROY:
  128.         DeleteObject(CaretPen);
  129.         PostQuitMessage(0);
  130.         return 0;
  131.     case WM_CHAR:
  132.         wprintf(L"WM_CHAR %#4llx'%lc' %3lli\n", wParam, (wchar_t)wParam, (lParam >> 16) & 0xff);
  133.         if (wParam == 8) {
  134.             Current.EraseLeft();
  135.         } else if (wParam >= 32) {
  136.             Current.Insert(wParam);
  137.         }
  138.         InvalidateRect(hwnd, nullptr, false);
  139.         return 0;
  140.     case WM_KEYDOWN:
  141.         wprintf(L"WM_KEYDOWN    %4lli %3lli\n", wParam, (lParam >> 16) & 0xff);
  142.         if (wParam == VK_LEFT) {
  143.             Current.MoveLeft();
  144.             InvalidateRect(hwnd, nullptr, false);
  145.         } else if (wParam == VK_RIGHT) {
  146.             Current.MoveRight();
  147.             InvalidateRect(hwnd, nullptr, false);
  148.         } else if (wParam == VK_HOME || wParam == VK_PRIOR || wParam == VK_UP) {
  149.             Current.MoveHome();
  150.             InvalidateRect(hwnd, nullptr, false);
  151.         } else if (wParam == VK_END || wParam == VK_NEXT || wParam == VK_DOWN) {
  152.             Current.MoveEnd();
  153.             InvalidateRect(hwnd, nullptr, false);
  154.         } else if (wParam == VK_DELETE) {
  155.             Current.EraseRight();
  156.             InvalidateRect(hwnd, nullptr, false);
  157.         }
  158.         return 0;
  159.     case WM_KEYUP:
  160.         return 0;
  161.     case WM_PAINT:
  162.         WindowPaint(hwnd);
  163.         return 0;
  164.     default:
  165.         return DefWindowProcW(hwnd, uMsg, wParam, lParam);
  166.     }
  167. }
  168.  
  169. int CALLBACK WinMain(
  170.     HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
  171.     AllocConsole();
  172.     freopen("CONOUT$", "w", stdout);
  173.     const DWORD WindowStyle = WS_OVERLAPPEDWINDOW;
  174.     WNDCLASSW wndclass;
  175.     wndclass.style = CS_VREDRAW | CS_HREDRAW;
  176.     wndclass.lpfnWndProc = &WindowProc;
  177.     wndclass.cbClsExtra = 8;
  178.     wndclass.cbWndExtra = 0;
  179.     wndclass.hInstance = hInstance;
  180.     wndclass.hIcon = LoadIcon(0, IDI_APPLICATION);
  181.     wndclass.hCursor = LoadCursor(0, IDC_ARROW);
  182.     wndclass.hbrBackground = 0;
  183.     wndclass.lpszMenuName = 0;
  184.     wndclass.lpszClassName = L"MyWindowClass";
  185.     ATOM wndclassatom = RegisterClassW(&wndclass);
  186.     RECT WindowRect = {0, 0, 800, 600};
  187.     AdjustWindowRect(
  188.         &WindowRect, WindowStyle, false);
  189.     HWND hwnd = CreateWindowW(
  190.         (LPCWSTR)wndclassatom,
  191.         L"window",
  192.         WindowStyle,
  193.         20,
  194.         20,
  195.         WindowRect.right - WindowRect.left,
  196.         WindowRect.bottom - WindowRect.top,
  197.         0,
  198.         0,
  199.         hInstance,
  200.         0);
  201.     ShowWindow(hwnd, SW_SHOW);
  202.     UpdateWindow(hwnd);
  203.     MSG message = {0, 0, 0, 0};
  204.     while (GetMessageW(&message, nullptr, 0, 0)) {
  205.         TranslateMessage(&message);
  206.         DispatchMessageW(&message);
  207.     }
  208.     return 0;
  209. };
  210.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement