前提・実現したいこと
Edit Controlで垂直中央寄せをするためteratail:WinAPI エディットコントロールのプロシージャにおいてサブクラス化やReact/Wineなど聞きましたがReactのWM_PAINTを参考にサブクラス化する方法が思いつかなかったので一からつくることにしました.
(以下のコードはサブクラス化をいじってみたのですが元のウィンドウがでてきてしまいます.)
自作する上での疑問点なのですが
- アクティブ時の入力カーソル
- 文字列の変換
- 文字列の選択
です.
一つ目のアクティブ時の入力カーソルですが
文字入力時に横に出るカーソルはどのような技術・関数で作られているのでしょうか?GDIで自分で描画する必要があるのでしょうか?
二つ目の文字列の変換は
Reactのコードで見たようにIMMのAPIを用いればいいのでしょうか?
三つ目ですが
DrawTextやTextOutされた文字は選択することができません.
とはいえブラウザなど様々なUIにおいて選択できるものが(選択できないほうがいいものも含めて)たくさんあります.これはほかの関数やAPIの形で提供されているものなのでしょうか?それとも標準のEdit Controlでない限りマウスキャプチャーと背景色変更で自己実装する必要があるのでしょうか?
サブクラス化したコード
C
1#define UNICODE 2 3#include <Windows.h> 4#include <Windowsx.h> 5 6LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM); 7LRESULT CALLBACK EditProc(HWND, UINT, WPARAM, LPARAM); 8 9#define ID_BUTTON 101 10 11const wchar_t CLASS_NAME[] = L"CLASS NAME"; 12 13HINSTANCE hGlobalInstance; 14WNDPROC getEditControl; 15 16int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR nCmdLine, int nCmdShow) { 17 UNREFERENCED_PARAMETER(hPrevInstance); 18 UNREFERENCED_PARAMETER(nCmdLine); 19 20 hGlobalInstance = hInstance; 21 22 WNDCLASSEX wc = { 23 sizeof(WNDCLASSEX), CS_VREDRAW | CS_HREDRAW, WindowProc, 24 0, 0, hInstance, 25 NULL, (HCURSOR)LoadCursor(NULL,IDC_ARROW), (HBRUSH)GetStockObject(WHITE_BRUSH), 26 NULL, CLASS_NAME, NULL 27 }; 28 RegisterClassEx(&wc); 29 30 HWND hwnd = CreateWindowEx( 31 0, CLASS_NAME, L"Title", WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 32 CW_USEDEFAULT, CW_USEDEFAULT, 960, 540, 33 NULL, NULL, hInstance, NULL 34 ); 35 36 ShowWindow(hwnd, nCmdShow); 37 UpdateWindow(hwnd); 38 39 MSG msg = {}; 40 while (GetMessage(&msg, NULL, 0, 0) > 0) { 41 TranslateMessage(&msg); 42 DispatchMessage(&msg); 43 } 44 45 return (int)msg.wParam; 46} 47 48LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 49 switch (uMsg) { 50 case WM_CREATE: 51 { 52 HWND hedit = CreateWindowEx( 53 0, L"Edit", L"Hello World", ES_CENTER | WS_CHILD | WS_VISIBLE | WS_BORDER, 54 160, 160, 190, 60, 55 hwnd, (HMENU)ID_BUTTON, hGlobalInstance, 0 56 ); 57 58 /* 59 TEXTMETRIC tm = {}; 60 ZeroMemory(&tm, sizeof(TEXTMETRIC)); 61 GetTextMetrics(GetDC(hedit), &tm); 62 63 wchar_t mes[1024] = {}; 64 wsprintf(mes, L"tmHeight : %d\ntmAscent : %d\ntmDescent : %d\n", tm.tmHeight, tm.tmAscent, tm.tmDescent); 65 MessageBox(hwnd, mes, L"RESULT", MB_OK); 66 */ 67 68 getEditControl = (WNDPROC)GetWindowLong(hedit, GWL_WNDPROC); 69 70 SetWindowLong(hedit, GWLP_WNDPROC, (LONG)EditProc); 71 } 72 break; 73 74 case WM_DESTROY: 75 PostQuitMessage(0); 76 break; 77 } 78 79 return DefWindowProc(hwnd, uMsg, wParam, lParam); 80} 81 82LRESULT CALLBACK EditProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 83 switch (uMsg) { 84 case WM_KEYDOWN: 85 SendMessage(hwnd, WM_PAINT, 0, 0); 86 break; 87 88 case WM_PAINT: 89 90 wchar_t inputstring[1024]; 91 ZeroMemory(inputstring, sizeof(wchar_t) * 1024); 92 GetWindowText(hwnd, inputstring, 1024); 93 94 PAINTSTRUCT eps = {}; 95 HDC ehdc = BeginPaint(hwnd, &eps); 96 TextOut(ehdc, 30, 30, inputstring, lstrlen(inputstring)); 97 EndPaint(hwnd, &eps); 98 99 break; 100 } 101 102 return CallWindowProc(getEditControl, hwnd, uMsg, wParam, lParam); 103}
補足情報
Windows10 Pro
VisualStudio2017 Community

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/03/29 03:46
2019/03/30 07:24