INTRODUCTION AND RELEVANT INFORMATION:
I have an edit control
that needs to accept only signed decimal numbers ( something like -12.35
).
I have decided to implement this via subclassing
.
The WM_CHAR
handler seems to works well, and I need to handle several other messages to completely protect user from entering invalid text. One such message is WM_PASTE
.
So far I was able to properly get the text from the clipboard
and to discard or pass the message depending if the copied string is indeed decimal number.
Edit control has limited input to 12 characters. This is done via EM_SETLIMITTEXT
message.
I use pure Winapi
and C++
. No libraries like boost
etc are allowed.
PROBLEM:
So far I test the case where edit control is empty and I discard pasting if the content is invalid. However, user can select a portion of the text in the edit control and then perform pasting. Something like this ( grey characters represent selection ):
Text in edit control: 123456
78.9
Clipboard text : -1A
The resulting string, if I would allow pasting, would be 123-1A78.9 which is invalid format.
This is the part I need help with:
My parsing properly recognizes valid format but I do not know how to properly merge two strings into one so I could test it.
QUESTIONS:
How can I properly form the resulting string from pasting so I can test its validity ?
Is there a function that can do the validity test for me ( it should be locale aware! ) ?
Note: I do not mind parsing the text myself but why "reinventing the wheel" if there is no need for it?
MY EFFORTS TO SOLVE THIS:
Browsing through Internet I found many
std::
functions that concatenate/cut off/ etc string but none of them seem to satisfy my needs for forming the resulting string. The closest thing I found wasstring:: insert(...)
but I do not know how to use it.As for the second question, I found
std:: strtod
by browsing through StackOverflow questions and it seems that it can be used to check the validity of the string. And it seems that it is locale aware as well, but I am not sure if it is what I seek.
To keep this post as brief as possible I provide the link to this question of mine that has relevant code snippets.
Thank you for your time and help.
If further info is required I will update the post.
Best regards.
Try something like this:
case WM_PASTE:
{
std::wstring cbtext;
if( !OpenClipboard(hwnd) ) // open clipboard
return 0;
// get clipboard data
HANDLE hClipboardData = GetClipboardData(CF_UNICODETEXT);
if( hClipboardData )
{
// Call GlobalLock so that to retrieve a pointer
// to the data associated with the handle returned
// from GetClipboardData.
cbtext = (LPWSTR) GlobalLock(hClipboardData);
// Unlock the global memory.
GlobalUnlock(hClipboardData);
}
// Finally, when finished I simply close the Clipboard
// which has the effect of unlocking it so that other
// applications can examine or modify its contents.
CloseClipboard();
if (cbtext.empty())
return 0;
// format the new text with the clipboard data inserted as needed
int len = GetWindowTextLengthW(hwnd);
std::wstring newtext(len, 0);
if (len > 0)
GetWindowTextW(hWnd, &newtext[0], len);
DWORD start, end;
SendMessageW(hwnd, EM_GETSEL, (WPARAM)&start, (LPARAM)&end);
if (end > start)
newtext.replace(start, end-start, cbtext);
else
newtext.insert(start, cbtext);
// parse the new text for validity
// code for parsing text
if( IsTextValid )
SetWindowTextW( hwnd, newtext.c_str() );
return 0;
}
来源:https://stackoverflow.com/questions/22341284/advice-required-to-insert-one-string-into-another-once-obtaining-text-from-clipb