TEdit - 如果剪贴板包含特定字符串,则忽略粘贴操作
TEdit - ignore paste operation if clipboard contains specific string
我想在粘贴到 TEdit 控件之前检查剪贴板字符串(同时使用 Ctrl+V 和上下文菜单 'Paste')。如果剪贴板中包含特定字符串,则 TEdit 控件不应粘贴该字符串。剪贴板文本应保持原样,不应被清除。
对于 CTRL-V
,您可以创建一个 OnKeyPress
事件处理程序以在粘贴之前验证剪贴板中的文本。
我结合了检查单个字符与 table 个有效字符以及检查整个粘贴是否无效的字符串。
注意:无效字符串可能仍然是手动输入的,因为这只是检查粘贴文本中的无效字符串。如果您需要检查以确保用户不会一次输入一个错误的字符串,请在 OnChange
事件处理程序中调用 valid_string()
。
#include <Clipbrd.hpp>
#include <algorithm>
#include <vector>
// A function to validate a pasted string against a number of blacklisted strings
bool valid_string(const UnicodeString& InStr) {
static const std::vector<UnicodeString> BadStrings{" ", "--"};
return std::find_if(BadStrings.begin(), BadStrings.end(), [&](const auto& badstr) {
// return true if the current badstr was found
return
std::search(InStr.begin(),
InStr.end(),
badstr.begin(),
badstr.end()) != InStr.end();
}) == BadStrings.end(); // true if a bad string was NOT found
}
// OnKeyPress event handler
void __fastcall TForm1::Edit1KeyPress(TObject *Sender, System::WideChar &Key)
{
TEdit& se = *static_cast<TEdit*>(Sender);
using StrType = decltype(se.Text);
// A lambda to validate a single character:
static const auto validkey = [](auto Ch) {
// example of valid characters:
static const StrType Accepted = "0123456789 -()";
return std::find(Accepted.begin(), Accepted.end(), Ch) != Accepted.end();
};
if(Key >= ' ') { // don't validate control characters
// Single key validation
if(not validkey(Key)) Key = 0;
} else if(Key == 22) { // CTRL-V - check that the whole clipboard buffer is ok
auto& c = *Clipboard();
if(c.HasFormat(CF_UNICODETEXT)) {
// Extract the pasted string
StrType paste = StrType(c.AsText.c_str());
// Use the lambda on all characters
bool all_chars_ok = std::all_of(paste.begin(), paste.end(), validkey);
if(not (all_chars_ok && valid_string(paste))) { // reject the whole paste
Key = 0;
}
}
}
}
下面是一个在 OnChange
处理程序中完成所有操作的示例。这应该从上下文菜单中捕获错误的粘贴,以及用户是否键入任何非法组合(即使它包含有效字符)。
#include <utility>
void __fastcall TForm1::Edit1Change(TObject *Sender)
{
TEdit& se = *static_cast<TEdit*>(Sender);
using StrType = decltype(se.Text);
static StrType old_text;
// A lambda to validate a single character:
static const auto validkey = [](auto Ch) {
// example of valid characters:
static const StrType Accepted = "0123456789 -()";
return std::find(Accepted.begin(), Accepted.end(), Ch) != Accepted.end();
};
// Making an unnecessary copy of the text.
// Using se.Text's iterators directly fails for some reason.
auto txt = se.Text;
// Use the lambda on all characters
bool all_chars_ok = std::all_of(txt.begin(), txt.end(), validkey);
if(all_chars_ok && valid_string(txt)) {
// All is ok, save this text
old_text = std::move(txt);
} else {
// Revert back to the old text
se.Text = old_text;
se.SelStart = old_text.Length();
// se.Undo(); // May be a better idea to use instead.
}
}
我想在粘贴到 TEdit 控件之前检查剪贴板字符串(同时使用 Ctrl+V 和上下文菜单 'Paste')。如果剪贴板中包含特定字符串,则 TEdit 控件不应粘贴该字符串。剪贴板文本应保持原样,不应被清除。
对于 CTRL-V
,您可以创建一个 OnKeyPress
事件处理程序以在粘贴之前验证剪贴板中的文本。
我结合了检查单个字符与 table 个有效字符以及检查整个粘贴是否无效的字符串。
注意:无效字符串可能仍然是手动输入的,因为这只是检查粘贴文本中的无效字符串。如果您需要检查以确保用户不会一次输入一个错误的字符串,请在 OnChange
事件处理程序中调用 valid_string()
。
#include <Clipbrd.hpp>
#include <algorithm>
#include <vector>
// A function to validate a pasted string against a number of blacklisted strings
bool valid_string(const UnicodeString& InStr) {
static const std::vector<UnicodeString> BadStrings{" ", "--"};
return std::find_if(BadStrings.begin(), BadStrings.end(), [&](const auto& badstr) {
// return true if the current badstr was found
return
std::search(InStr.begin(),
InStr.end(),
badstr.begin(),
badstr.end()) != InStr.end();
}) == BadStrings.end(); // true if a bad string was NOT found
}
// OnKeyPress event handler
void __fastcall TForm1::Edit1KeyPress(TObject *Sender, System::WideChar &Key)
{
TEdit& se = *static_cast<TEdit*>(Sender);
using StrType = decltype(se.Text);
// A lambda to validate a single character:
static const auto validkey = [](auto Ch) {
// example of valid characters:
static const StrType Accepted = "0123456789 -()";
return std::find(Accepted.begin(), Accepted.end(), Ch) != Accepted.end();
};
if(Key >= ' ') { // don't validate control characters
// Single key validation
if(not validkey(Key)) Key = 0;
} else if(Key == 22) { // CTRL-V - check that the whole clipboard buffer is ok
auto& c = *Clipboard();
if(c.HasFormat(CF_UNICODETEXT)) {
// Extract the pasted string
StrType paste = StrType(c.AsText.c_str());
// Use the lambda on all characters
bool all_chars_ok = std::all_of(paste.begin(), paste.end(), validkey);
if(not (all_chars_ok && valid_string(paste))) { // reject the whole paste
Key = 0;
}
}
}
}
下面是一个在 OnChange
处理程序中完成所有操作的示例。这应该从上下文菜单中捕获错误的粘贴,以及用户是否键入任何非法组合(即使它包含有效字符)。
#include <utility>
void __fastcall TForm1::Edit1Change(TObject *Sender)
{
TEdit& se = *static_cast<TEdit*>(Sender);
using StrType = decltype(se.Text);
static StrType old_text;
// A lambda to validate a single character:
static const auto validkey = [](auto Ch) {
// example of valid characters:
static const StrType Accepted = "0123456789 -()";
return std::find(Accepted.begin(), Accepted.end(), Ch) != Accepted.end();
};
// Making an unnecessary copy of the text.
// Using se.Text's iterators directly fails for some reason.
auto txt = se.Text;
// Use the lambda on all characters
bool all_chars_ok = std::all_of(txt.begin(), txt.end(), validkey);
if(all_chars_ok && valid_string(txt)) {
// All is ok, save this text
old_text = std::move(txt);
} else {
// Revert back to the old text
se.Text = old_text;
se.SelStart = old_text.Length();
// se.Undo(); // May be a better idea to use instead.
}
}