私は自分のカスタムエディットコントロールを書いていましたが、うまくいきましたので、ここで私の経験を共有します。このコードは参考になるでしょう...カスタムエディットコントロールが不可能なので(see here)あなた自身の編集コントロールを書く必要があります。一般的な手順は次のとおりです。
// global vars
int select; // current selection position
int cursor; // current cursor position
HWND parent; // parent window
wchar_t buf[MAXINPUTBUF]; // edit buffer
WNDPROC oldproc; // old window procedure
// create custom control window
hWnd = CreateWindowW(L"static", NULL, WS_CHILD | WS_TABSTOP | SS_LEFT | SS_NOTIFY, 0, 0, 0, 0, parent, NULL, (HINSTANCE)GetWindowLongPtr(parent, GWL_HINSTANCE), NULL);
// todo: use SetProp() to store all global vars
oldproc = (WNDPROC)SetWindowLongPtrW(hWnd, GWL_WNDPROC, (LONG_PTR)InputWndProc);
SetWindowPos(hWnd, HWND_TOP, x, y, cx, cy, 0);
キーボード入力の表示方法は、hereです。
LRESULT CALLBACK InputWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_LBUTTONDOWN:
//SetFocus(hWnd);
PostMessageW(GetParent(hWnd), WM_NEXTDLGCTL, (WPARAM)hWnd, TRUE);
break;
case WM_KILLFOCUS:
HideCaret(hWnd);
DestroyCaret();
break;
case WM_SETFOCUS:
{
RECT r;
GetClientRect(hWnd, &r);
// Create a solid black caret.
CreateCaret(hWnd, (HBITMAP) NULL, 2, r.bottom-r.top);
ShowCaret(hWnd);
InputWndRedraw(hWnd);
}
return FALSE;
case WM_GETDLGCODE:
return DLGC_WANTALLKEYS | DLGC_WANTARROWS;
case WM_KEYDOWN:
{
switch (wParam)
{
case 'V':
if (0x8000 & GetKeyState(VK_CONTROL))
{
HANDLE h;
wchar_t *cb;
int len,slen;
InputWndDelete(hWnd);
OpenClipboard(NULL);
h = GetClipboardData(CF_UNICODETEXT);
cb = (wchar_t*)GlobalLock(h);
if (cb)
{
memcpy(buf+(cursor+len)*sizeof(wchar_t), buf+cursor*sizeof(wchar_t), (slen-cursor)*sizeof(wchar_t));
memcpy(buf+cursor*sizeof(wchar_t), cb, len*sizeof(wchar_t));
}
GlobalUnlock(h);
CloseClipboard();
InputWndRedraw(hWnd);
}
break;
case VK_RIGHT:
if (cursor-1 >= MAXINPUTBUF || cursor >= (int)wcslen(buf))
break;
cursor++;
if (!(GetKeyState(VK_SHIFT) & 0x8000))
select = cursor;
InputWndRedraw(hWnd);
break;
case VK_TAB:
PostMessageW(GetParent(hWnd), WM_NEXTDLGCTL, GetKeyState(VK_SHIFT) & 0x8000, FALSE);
break;
case VK_LEFT:
if (cursor <= 0)
break;
cursor--;
if (!(GetKeyState(VK_SHIFT) & 0x8000))
select = cursor;
InputWndRedraw(hWnd);
break;
case VK_HOME:
cursor = 0;
if (!(GetKeyState(VK_SHIFT) & 0x8000))
select = cursor;
InputWndRedraw(hWnd);
break;
case VK_END:
cursor = wcslen(buf);
if (!(GetKeyState(VK_SHIFT) & 0x8000))
select = cursor;
InputWndRedraw(hWnd);
break;
case VK_DELETE:
if (cursor >= (int)wcslen(buf))
{
InputWndDelete(hWnd);
InputWndRedraw(hWnd);
break;
}
if (select == cursor)
select ++;
InputWndDelete(hWnd);
InputWndRedraw(hWnd);
break;
case VK_BACK:
if (cursor <= 0)
{
InputWndDelete(hWnd);
InputWndRedraw(hWnd);
break;
}
if (select == cursor)
cursor --;
InputWndDelete(hWnd);
InputWndRedraw(hWnd);
}
}
break;
case WM_CHAR:
if (wParam < VK_SPACE)
break;
InputWndDelete(hWnd);
if (wcslen(buf)+1 < MAXINPUTBUF)
{
wmemmove(buf+(cursor+1)*sizeof(wchar_t), buf+cursor*sizeof(wchar_t), wcslen(s->buf)-cursor);
buf[cursor] = wParam;
cursor++;
select = cursor;
}
InputWndRedraw(hWnd);
break;
case WM_ERASEBKGND:
// no flickering
return TRUE;
case WM_PAINT:
{
HDC dc;
PAINTSTRUCT paint;
dc = BeginPaint(hWnd, &paint);
InputWndDraw(hWnd, dc);
EndPaint(hWnd, &paint);
}
return TRUE;
}
return CallWindowProcW(oldproc, hWnd, msg, wParam, lParam);
}
は現在選択されているテキストを削除し、次のように私のウィンドウプロシージャが(からカーソルに選択)になります。ウィンドウの
void InputWndDelete(HWND hWnd)
{
int len;
len = wcslen(buf);
if (select > cursor)
{
memcpy(buf+cursor*sizeof(wchar_t), buf+select*sizeof(wchar_t), (len - select)*sizeof(wchar_t));
ZeroMemory(buf+(len-select+cursor)*sizeof(wchar_t), (MAXINPUTBUF-len+select-cursor)*sizeof(wchar_t));
select = cursor;
}
else if (select < cursor)
{
memcpy(buf+select*sizeof(wchar_t), buf+cursor*sizeof(wchar_t), (len - cursor)*sizeof(wchar_t));
ZeroMemory(buf+(len-cursor+select)*sizeof(wchar_t), (MAXINPUTBUF-len+cursor-select)*sizeof(wchar_t));
cursor = select;
}
else
{
select = cursor;
}
}
}
描画ウィンドウDC
void InputWndRedraw(HWND hWnd)
{
HDC hdc;
HideCaret(hWnd);
hdc = GetDC(hWnd);
InputWndDraw(hWnd, hdc);
ReleaseDC(hWnd, hdc);
ShowCaret(hWnd);
}
デバイスコンテキストに入力バッファ(BUF *)を描きます。シンタックスハイライトおよびその他の書式設定機能をここに...
void InputWndDraw(HWND hWnd, HDC hdc)
{
RECT r,cr;
GetClientRect(hWnd, &cr);
// draw selected rectangle FillRect()...
CopyRect(&r,&cr);
DrawTextW(hdc, buf, -1, &r, DT_LEFT | DT_TOP);
if (cursor)
DrawTextW(hdc, buf, cursor, &r, DT_LEFT | DT_TOP | DT_CALCRECT);
else
r.right = cr.left;
if (GetFocus() == hWnd)
{
if (r.right > cr.right)
SetCaretPos(cr.right, cr.top);
else
SetCaretPos(r.right, cr.top);
}
}
[Visual Studioのサンプル](http://archive.msdn.microsoft.com/vcsamplesmfcは)ないワードパッドおよびSUPERPADサンプルに –
おかげを持っていますが、実際にはイムMFCチュートリアルを探しています。 – devjeetroy
英語以外の言語を考慮すると、適切なカスタム編集コントロールは重要ではありません。私はあなたが再考することをお勧めします。 –