数値のみを受け入れるようにエディット コントロールをサブクラス化しました。
また、サブクラス化の手順で、クリップボード データを解析して禁止文字を削除します。
私は目的の動作を達成したか、少なくともそう思っていましたが、唯一の問題は、編集コントロールにもドットを入力できることです。
自分のコードの何が問題なのかわからないので、他の誰かが助けてくれることを願ってここに投稿します。
クリップボードの解析は適切なデータを返しますが、問題を引き起こすのは WM_CHAR です。
助けてください、コードの何が問題なのかわかりません。
ありがとうございました。
サブクラス化手順のコードは次のとおりです。
LRESULT CALLBACK MyEditProc ( HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam,
UINT_PTR uIdSubclass,
DWORD_PTR dwRefData )
{
switch (message)
{
case WM_PASTE:
{
if ( OpenClipboard( NULL ) )
{
HANDLE hClipboardData = GetClipboardData(CF_UNICODETEXT);
wchar_t *pchData =
(wchar_t*)GlobalLock(hClipboardData);
GlobalUnlock(hClipboardData);
CloseClipboard();
int i = 0, j = 0;
wchar_t *temp = new wchar_t[51]; // parsed string
memset( temp, '\0', sizeof(temp) );
// integer numbers are parsed here
while( ( i < (int)wcslen(pchData) )
&& ( j < 10 ) ) // I just need first 10
{
if( isdigit( pchData[i] ) )
temp[j++] = pchData[i];
i++;
}
temp[j] = '\0';
// replace selection with parsed text
SendMessage( hwnd, EM_REPLACESEL,
(WPARAM)TRUE, (LPARAM)temp );
// set caret at the end of the text
SendMessage( hwnd, EM_SETSEL, j, j );
delete[] temp;
}
}
return TRUE;
break;
case WM_CHAR:
{
if( ! ( isdigit(wParam)
|| wParam == VK_RETURN
|| wParam == VK_DELETE
|| wParam == VK_BACK )
// this check bellow is needed
// so I can catch WM_PASTE !
&& ( ! ( GetKeyState( VK_CONTROL ) & 0x8000 ) ) )
{
return 0;
}
}
break;
}
return DefSubclassProc( hwnd, message, wParam, lParam);
}
次のように WM_CREATE のコントロールをサブクラス化しました。
SetWindowSubclass( hEdit, MyEditProc, 0, 0);
上記の手順では4番目のパラメータとして何も渡さなかったので、呼び出す必要性を感じませんでしたRemoveWindowSubclass
。
編集:
Passant 氏が私のソリューションのエラーを指摘したので、この投稿を読んで同様の問題の解決策を探している人を混乱させないように、それを削除しました。