I have requirement to disable copy/paste/cut operations on a textbox. For this purpose I inherited the Textbox and created MyTextbox and had the KeyDown event overriden with the following code
if (!(e.Key == Key.Back || e.Key == Key.Left || e.Key == Key.Right || e.Key == Key.Delete || e.Key == Key.Tab))
{
if ((e.Key == Key.C || e.Key == Key.X || e.Key == Key.V) &&
(Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
{
e.Handled = true;
}
}
and then used this textbox. This textbox now prevents copy/paste/cut operations.
I am trying to acheive this same purpose using Behaviors.For this purpose I have created a behavior. The code is as under
public class MyTextboxBehavior : Behavior<TextBox>
{
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.KeyDown += new KeyEventHandler(AssociatedObject_KeyDown);
}
private void AssociatedObject_KeyDown(object sender, KeyEventArgs e)
{
if (!(e.Key == Key.Back || e.Key == Key.Left || e.Key == Key.Right || e.Key == Key.Delete || e.Key == Key.Tab))
{
if ((e.Key == Key.C || e.Key == Key.X || e.Key == Key.V) &&
(Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
{
e.Handled = true;
}
}
}
}
and have added this behavior to Textbox as under
<TextBox>
<Interactivity:Interaction.Behaviors>
<CustomControl:MyTextboxBehavior></CustomControl:MyTextboxBehavior>
</Interactivity:Interaction.Behaviors>
</TextBox>
Does anyone know why this is not working?
UPDATED JUNE 24
In WPF, you would be able to capture the CTRL + X/C/V key presses at the PreviewKeyDown event, and then you would be able to suppress these functions in your text box.
In Silverlight Preview methods are not available, so here it is not an option. The TextBox control also has built-in handling of the clipboard actions copy and paste CTRL+C and CTRL+V (see Clipboard class remarks), so it is not straightforward to suppress these actions.
There is an attempt for an SL3 project here where the OnKeyDown and OnKeyUp event handlers are overridden in a class deriving from TextBox. The implementation calls the base methods which are obviously not accessible in the Behavior implementation, so a straightforward implementation of the copy and paste suppression in the TextBox via behaviors does not seem to be possible.
if (e.Key == Key.Ctrl)
Clipboard.SetText(string.Empty);
Related
In the last question, I had a problem with placing the cursor in the right place when clicking on the LineEdit with the mouse.
The problem was solved, I, with God's help, wrote an algorithm that solves my problem. I wrote it in an EMPTY project, where there is nothing but LineEdit. Everything worked great there. Here is the code:
if(object == ui->lineEdit_newClientPhone && event->type() == QEvent::MouseButtonRelease)
{
QString line = ui->lineEdit_newClientPhone->displayText();
qDebug() << line;
ui->lineEdit_newClientPhone->setFocus();
bool isValid = true;
for(int i = 0; i<=15; i++){
if(line[i] == '_'){
ui->lineEdit_newClientPhone->setCursorPosition(i);
isValid = false;
break;
}
}
if(isValid){
ui->lineEdit_newClientPhone->setCursorPosition(16);
}
}
It worked great. You click on any place in lineEdit, the mouse cursor is placed on the first empty "_" character. I joyfully ran to transfer it to the main project.
But then I encountered a strange behavior - in the main project, exactly copied code does not give such behavior. When you click on lineEdit with the mouse, the cursor is placed in the place where you clicked. I debugged all the events associated with this LineEdit and found strange behavior - the order of the events is different. Excluding unnecessary events, which were the MOST:
if(object == ui->lineEdit_newClientPhone){
if(event->type() != QEvent::Paint && event->type() != QEvent::MouseMove && event->type() != QEvent::HoverMove){
qDebug() << event->type();
}
}
Got this result in "EMPTY" project:
QEvent::MouseButtonPress
QEvent::MouseButtonRelease
QEvent::InputMethodQuery
But in the main project, the sequence turned out to be different:
QEvent::MouseButtonPress
QEvent::InputMethodQuery
QEvent::MouseButtonRelease
I don't know if this is the case, but in this way, my logic does not work and the cursor remains in the place where you clicked. I was able to fix the situation by changing the event to QEvent::MouseButtonRelease, but this way I get mocking cursor travels first to the place where you clicked, then to the place I need. What could be the problem and how can it be fixed? Thanks to all!
I don't think this is the right decision, so I would like to hear more solutions, but QTimer::singleShot helped me
f(object == ui->lineEdit_newClientPhone && event->type() == QEvent::MouseButtonPress){
QTimer::singleShot(0,ui->lineEdit_newClientPhone,[this]
{
QString line = ui->lineEdit_newClientPhone->displayText();
qDebug() << line;
ui->lineEdit_newClientPhone->setFocus();
bool isValid = true;
for(int i = 0; i<=15; i++){
if(line[i] == '_'){
ui->lineEdit_newClientPhone->setCursorPosition(i);
isValid = false;
break;
}
}
if(isValid){
ui->lineEdit_newClientPhone->setCursorPosition(16);
}
});
}
I am trying to implement default Emacs shortcuts supported by macOS.
Example of the code:
void InputField::keyPressEventInner(QKeyEvent *e) {
if(e->modifiers().testFlag(Qt::MetaModifier) && e->key() == Qt::Key_A) {
// Does not work
}
I've tried to use QGuiApplication::keyboardModifiers():
if(QGuiApplication::keyboardModifiers().testFlag(Qt::MetaModifier) && e->key() == Qt::Key_A) {
// does not work
}
QKeyEvent::nativeModifiers() always returns 0 when a modifier key is pressed.
Note: I use MetaModifier because according to the official documentation:
On macOS, the ControlModifier value corresponds to the Command keys on the keyboard, and the MetaModifier value corresponds to the Control keys.
How do I catch the Control key?
Qt 5.12.8
XCode 11.7
Update:
I can catch either Ctrl or a:
if(e->modifiers() & Qt::MetaModifier))
or
if(e->key() == Qt::Key_A)
I am following lazy foo's tutorial, however I realized every time I press press s or p, SDL_KEYDOWNtriggers twice. How can this be fixed?
Here is the code snippet:
while(SDL_PollEvent(&e) != 0) {
if(e.type == SDL_QUIT) {
quit = true;
}
else if(e.type == SDL_KEYDOWN) {
if(e.key.keysym.sym == SDLK_s) {
if(timer.isStarted()) {
timer.stop();
printf("stop\n");
}
else {
timer.start();
printf("start\n");
}
}
else if(e.key.keysym.sym == SDLK_p) {
if(timer.isPaused()) {
timer.unpause();
printf("unpause\n");
}
else {
timer.pause();
printf("pause\n");
}
}
}
}
Pressing s once:
start
stop
TL;DR: Check if e.key.repeat equals to 0 before handling the events.
SDL generates fake repeated keypresses if you hold a key long enough. This is used mostly for text input.
The original key press has .repeat == 0, and fake presses have .repeat == 1.
For convenience reasons probably (I'd argue that it's rather inconvenient), since SDL 2.0.5 the actual key press generates two events instead of one. One has .repeat set to 0, and other (new) one has it set to 1.
I'm building a basic text editor, with SFML. For this I need to save with the key combination CTRL + S.
My current solution saves when I press CTRL + S, AND produces an 's' in my editor. This extra 's' is not wanted.
This is the code I currently have:
//Main loop:
if (event.type == sf::Event::KeyPressed)
{
if (event.key.code == sf::Keyboard::S
&& event.key.control)
{
cout << "testing" << endl;
}
}
else if (event.type == sf::Event::TextEntered)
{
}
In other words: I want TextEntered to be working normally. But if I press CTRL + S, it will disable TextEntered and perform the save. How do I do this?
Just do a real-time key check inside the handler for TextEntered. e.g.
else if (event.type == sf::Event::TextEntered)
{
if (!sf::Keyboard::isKeyPressed(sf::Keyboard::LControl) &&
!sf::Keyboard::isKeyPressed(sf::Keyboard::RControl))
{
// handle text event
}
else
{
// do something else, or nothing
}
}
I am new to CDHTMLDialog in mfc.
I know how to disable Refresh keys.
Is there generic solution to disable internet shortcut keys(accelerators)?
Ex: ctrl+n , ctrl+o.
Thanks
Override CDHtmlDialog::TranslateAccelerator
Override CDHtmlDialog::TranslateAccelerator
if( ( GetAsyncKeyState(VK_CONTROL) & 0x8000 )
&& (('N' == lpMsg->wParam)
|| ('O' == lpMsg->wParam)
|| ('L' == lpMsg->wParam)
|| ('P' == lpMsg->wParam)))
return S_OK;