I have some accelerators configured and if using just the Ctrl key it works fine, but if I make it Shift+Ctrl it doesn't work (doesn't even show as a shortcut in the MFC menus where as the Ctrl version does). The entries I've tried with both upper and lower case letters, doesn't make a difference. This is what the entries in the accelerators look like:
"R", ID_R1, VIRTKEY, CONTROL, NOINVERT
"R", ID_R2, VIRTKEY, SHIFT, CONTROL, NOINVERT
What am I doing wrong?
Edit: I made the "R" capital above because of the two answer talking about that, but I originally had "R" and only changed to "r" before giving up and asking here. But the "R" doesn't work for Ctrl-Shift-R either, where as the Ctrl-R works fine?
Edit: Using Spy x64 and checking the main window, never get a command sent. If I go to the list view on the right side of a splitter window and press Ctrl-Shift-R in that order, the only thing generated is:
<000041> 00000000002100D6 P WM_KEYDOWN nVirtKey:VK_CONTROL cRepeat:1 ScanCode:1D fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<000042> 00000000002100D6 S LVM_GETNEXTITEM iStart:-1 flags:LVNI_SELECTED
<000043> 00000000002100D6 R LVM_GETNEXTITEM iIndex:-1
<000044> 00000000002100D6 P WM_KEYDOWN nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<000045> 00000000002100D6 S LVM_GETNEXTITEM iStart:-1 flags:LVNI_SELECTED
<000046> 00000000002100D6 R LVM_GETNEXTITEM iIndex:-1
<000047> 00000000002100D6 P WM_KEYUP nVirtKey:'R' cRepeat:1 ScanCode:13 fExtended:0 fAltDown:0 fRepeat:0 fUp:1
<000048> 00000000002100D6 S LVM_GETNEXTITEM iStart:-1 flags:LVNI_SELECTED
<000049> 00000000002100D6 R LVM_GETNEXTITEM iIndex:-1
<000050> 00000000002100D6 P WM_KEYUP nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:1 fUp:1
<000051> 00000000002100D6 S LVM_GETNEXTITEM iStart:-1 flags:LVNI_SELECTED
<000052> 00000000002100D6 R LVM_GETNEXTITEM iIndex:-1
<000053> 00000000002100D6 P WM_KEYUP nVirtKey:VK_CONTROL cRepeat:1 ScanCode:1D fExtended:0 fAltDown:0 fRepeat:1 fUp:1
Edit:
Even more data, I placed a conditional breakpoint in thrdcore.cpp at line 178 where the message loop is (the line is if (pState->m_msgCur.message != WM_KICKIDLE && !AfxPreTranslateMessage(&(pState->m_msgCur)))). The break point is: pState->m_msgCur.message==0x0100 && pState->m_msgCur.wParam==0x52 (WM_KEYDOWN for R). When pressing R or Ctrl-R the breakpoint hits, when pressing Ctrl-Shift-R the breakpoint doesn't occur. Above spy trace there is never a WM_KEYDOWN for the R, only an up?
Edit:
Now really getting weird. I decided to go in to the keyboard settings for VS2017 and see if something assigned to Ctrl-Shift-R, I press it and nothing happens, I try any other letter like Ctrl-Shift-T and it works fine. Could it by my keyboard? Or something deeper in Win10 x64 that is eating a WM_KEYDOWN for R when Ctrl-Shift is pressed?
Thanks.
The reason why the title names of accelerator keys and menu items are not updated is that the registry information is not updated.
There are two solutions for your reference:
First, you can manually delete the information in the registry.You can enter the registry area:
HKEY_CURRENT_USER\SOFTWARE\Local AppWizard-Generated Applications
Then delete the registry information of your current application name, and it will work normally after recompiling the program.
In the second method, you can clear the registry information by adding the CleanState() function to the ExitInstance() function. After restarting the program, the key information and menu bar information of the current program will be updated.
You can refer to:
int CMFCApplication1App::ExitInstance()
{
//TODO: handle additional resources you may have added
AfxOleTerm(FALSE);
this->CleanState();
return CWinAppEx::ExitInstance();
}
And both solutions worked for me.
You should use upper-case characters in the accelerator table:
"R", ID_R2, VIRTKEY, SHIFT, CONTROL, NOINVERT
To show the shortcut keys on the menu, you have to modify the menu item itself, like change
MENUITEM "&New\tCtrl+N", ID_FILE_NEW
to
MENUITEM "&New\tCtrl+Shift+N", ID_FILE_NEW
Related
I need Firefox to always open Desktop in the Save as dialogue on saving files, so I can type in the name of the folder on the Desktop and save the file where I want. That would be a simple and very efficient way of grouping downloaded files. The problem is that Firefox opens the last save folder in the Save as dialogue window, and I can't do this in a reasonable number of steps. To get Desktop automatically opened in the Save as dialogue the best I could think of is this autohotkey script, and I have a problem with it:
!+^s::
MouseMove, %A_CaretX%, %A_CaretY%
CoordMode, Mouse, Screen
MouseGetPos, xpos, ypos
SetMouseDelay, 2
MouseMove,445,46
Click Left
Send,Desktop
Send,{Enter}
MouseMove, %xpos%, %ypos%
Click Left
CoordMode, Mouse, Screen
MouseGetPos, xpos, ypos
SetMouseDelay, 2
MouseMove,445,46
Click Left
MouseMove,%xpos%, %ypos%
Click Left
Input, L, V L1
Loop {
Input, L, V L1 T1.4
If (ErrorLevel = "Timeout")
Break
}
Send,^{Down}
Send,{Enter}
MouseClick,Left,720,473
MouseClick,Left,720,473
return
The problem with this script is the Input command - it doesn't wait for me to type in the name of the folder but executes the following command immediatelly.
EDITED: The script is now fully working (thanks to Forivin). An additional line with Input comamand "Input, L, V L1" was required for the script to pause and wait for the name of the folder to be typed in. I've used MouseClick command and coordinates that work for my monitor to confirm the dialogue box. Confirming the dialog box with Enter (4 times) doesn't work accurately on my computer for some reason. EDIT2: Added two lines, in order to make use of the drop down list folder name suggestions, so the whole folder name doesn't need to be typed in.
Using the Control*-commands would be a much more reliable way of doing this:
!+^s::
WinGet, hWnd, ID, A ;Get handle of active window
;Navigate the the users desktop folder
ControlFocus, ToolbarWindow324, ahk_id %hWnd%
ControlClick, ToolbarWindow324, ahk_id %hWnd%,,,2, NA
ControlSetText, Edit2, `%HOMEPATH`%\Desktop\, ahk_id %hWnd%
ControlSend, Edit2, {Enter}, ahk_id %hWnd%
;Set focus to the folder list
Sleep, 100
ControlFocus, DirectUIHWND2, ahk_id %hWnd%
Input, L, V L1 T2 ;wait until you start typing a folder name (if you just wait 2 seconds, the download will be canceled)
If (ErrorLevel = "Timeout") { ;if you waited too long:
ControlClick, Button2, ahk_id %hWnd%,,,, NA ;click the Cancel button
Return ;end of the hotkey
}
Loop { ;wait until you haven't typed a new letter for 0.4 seconds
Input, L, V L1 T0.4
If (ErrorLevel = "Timeout")
Break
}
ControlGetText, button1Text, Button1, ahk_id %hWnd%
If (button1Text = "&Open") { ;If your windows isn't English, you need to replace the word "Open", if you're confused remove the if statement (but leave the content)
ControlClick, Button1, ahk_id %hWnd%,,,, NA ;click the Open button
Sleep, 100
}
ControlClick, Button1, ahk_id %hWnd%,,,, NA ;click the Save button
Return
I want to handle action double click by clicking left_mouse 2 times.Between 2 click-time,I sleep 100ms
SendInput(LEFT_CLICK...); Sleep(100); SendInput(LEFT_CLICK...);
It works OK in my PC,but not works correctly in virtual machine
May be,There is a delay-time when machine do function "SendInput"Eventhough I remove "Sleep(100)",It just clicks 2 times and doesn't "double click" as I want.
How to handle double click exactly in this case
Please suggest me anyway to do it
Thanks,
Btw you should specify what environment you're working in and make your code a bit more detailed. Using SendInput is one option, I don't know what you're trying to do exactly, but I'll give you two more options to try for simulating clicks. Something like this would works fine (I code in python but it should be the same idea):
def leftClick(x=0, y=0):
win32api.SetCursorPos((x,y)) #set the cursor to where you wanna click
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, x, y, 0, 0) #generate a mouse event
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, x, y, 0, 0)
return True
def doubleClick(x=0, y=0):
leftClick(x,y)
leftClick(x,y)
You could sleep for 50 ms in between time.sleep(0.05) but it works for me without it and I've tested in a vm.
Another option if you want to perform silent clicks without having to move the cursor, you can send a message to the window where you want to click knowing the window handle (hwnd), here I assume you pass the handle as a parameter.
def leftClick(x=0, y=0, hwnd):
lParam = win32api.MAKELONG(x,y) # create a c long type to hold your click coordinates
win32gui.SendMessage(hwnd, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, lparam) # send a message to the window that the mouse left button is down.
win32gui.SendMessage(hwnd, win32con.WM_LBUTTONUP, 0, lparam) # send a message to the window that the mouse left button is up.
return True
def doubleClick(x=0, y=0, hwnd):
leftClick(x,y, hwnd)
leftClick(x,y, hwnd)
or you can send the message WM_LBUTTONDBLCLK up to you.
I'm trying to create a Hotkey (Win+Shift+Q) that toggles on/off another Hotkey that changes the right Alt key to a left mouse click; however, I can't get it to work.
Expected Behavior:
Pressing Windows+Shift+Q will initially toggle the Right-Alt key to act as a left mouse click.
Pressing Windows+Shift+Q again will toggle the Right-Alt key back to acting as a Right-Alt key.
Pressing Windows+Shift+Q again will revert to the left-click behavior (see #1). And so on.
Here's the most current iteration of my code:
Hotkey, RAlt, MyClick, On
#+Q:: ;Win+Shift+Q :: ::Right-Alt acts as a left mouse button click
switch := !switch
MsgBox %switch%
Hotkey RAlt, % (switch ? "Off": "On")
Return
MyClick:
MouseClick
Return
When I run my script I get the following error after clicking OK on the MsgBox and the script quits:
Error: Nonexistent hotkey
Specifically: RAlt
Line#
141: Hotkey,RAlt,MyClick,On
143: switch:=!switch
144: MsgBox %switch%
-->145: Hotkey RAlt, % (switch ? "Off": "On")
146: Return
149: MouseClick
150: Return
The current thread will exit.
Most of the other posts that might relate (Can AutoHotKey toggle keymapping?, Autohotkey: Toggle a set of keybinds on and off) only deal with key to key mapping and not key to mouse mapping. I can't tell if that is the cause of my issues or not.
Previously I had this, but the Win+Shift+Q didn't toggle the behavior, RAlt always acted as a left-click so I commented it out:
#+Q:: ;Win+Shift+Q :: ::Right-Alt acts as a left mouse button click
RAlt::LButton
;Hotkey, RAlt, Toggle ;Does not work for some reason
int += 1
test := mod(int, 2) = 0
if (test) {
msgbox on
Hotkey, RAlt, On
}
else {
msgbox off
Hotkey, leftClick, Off
}
Return
I'll also add that I would like this behavior across Windows, not just a single application (which also seems to be a topic in other posts that allows for the #IfWinActive-type suggestions/solutions).
I tried your current iteration of code in AutoHotkey v1.1.13.01 Unicode 32-bit and I don't have any errors after pressing OK on the message box, the script works as advertised.
Try updating your AutoHotkey version here: http://ahkscript.org/download/ and see if the problem persists.
bState:=False
#If bState
RAlt::Click
#If
#+vk51:: ; win + shift + q
KeyWait, vk51
TrayTip, % "state of switch", % (bState:=!bState) ? "on":"off"
Return
I have a Win32 window message loop. I want to intercept "Copy to clipboard" via CTRL+C.
My current approach is to handle it like this:
...
case WM_KEYDOWN:
TranslateMessage(&message);
// Intercept Ctrl+C for copy to clipboard
if ('C' == message.wParam && (::GetKeyState(VK_CONTROL)>>15))
{ // do the copy... }
...
Is there a better way to do this other than explicitly checking for the key-stroke combination?
Is there some way to register the standard copy-to-clipboard keystroke and then handle a WM_COPY message?
Windows treats Ctrl+C, Ctrl+V, Ctrl+X as one key in the WM_CHAR message.
enum
{
CTRL_BASE = 'A' - 1,
SELECT_ALL = 'A' - CTRL_BASE, // Ctrl+A
COPY = 'C' - CTRL_BASE, // Ctrl+C
CUT = 'X' - CTRL_BASE, // Ctrl+X
PASTE = 'V' - CTRL_BASE, // Ctrl+V
UNDO = 'Z' - CTRL_BASE, // Ctrl+Z
REDO = 'Y' - CTRL_BASE, // Ctrl+Y
};
Note: This is not documented at MSDN - WM_CHAR message. This is an observation I made while creating my text editor. Although Ctrl+A == 0x41 is mentioned in Keyboard Input.
Using WM_CHAR instead of manually handling WM_KEYDOWN, etc makes processing closer to the standard, specifically does auto-repeat when a key is held, and does not emit the message when extra keys are held.
Apparently there's no readily available way to have WM_COPY delivered for you instead of keys.
In Windows 7, you can give focus to a window just by hovering over it with the mouse. This feature is not enabled by default, but you can enable it in the Control Panel. (Here is the path to take:
[Ease of Access Center-->Make the mouse easier to use-->check "Activate a window by hovering over it with the mouse"]).
I like this feature a lot, but sometimes it annoys me when I try to open a C# class in Visual Studio using Resharper. I'll hit CTRL+N and type the name of the class I want to see (for example, "MyWpfClass"). Resharper will then show a dropdown of suggestions with "MyWpfClass" on top. I hit return, and now Resharper opens a dropdown which lets me choose between "MyWpfClass.xaml" and "MyWpfClass.xaml.cs". However, if the mouse cursor is in the wrong place, the dropdown closes within a second and I'm back to square one. Is there a way to fix this without turning the focus-follows-mouse feature off?
I was having the same problem with MS Outlook: the auto-suggestions list for contacts would close automatically because Windows treated it as a window rather than part of the New Message window.
You could use NiftyWindows, which has the same option "Focus Follows Mouse", accessible through its context menu.
Alternatively, as it is written in Autohotkey, you could use extract and run its subroutine "XWN_FocusHandler" into a standalone script:
#Persistent
#SingleInstance force
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
#Warn All, OutputDebug ; Recommended for catching common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
SetTimer, XWN_FocusHandler, 100
return
XWN_FocusHandler:
CoordMode, Mouse, Screen
MouseGetPos, XWN_MouseX, XWN_MouseY, XWN_WinID
If ( !XWN_WinID )
Return
If ( (XWN_MouseX != XWN_MouseOldX) or (XWN_MouseY != XWN_MouseOldY) )
{
IfWinNotActive, ahk_id %XWN_WinID%
XWN_FocusRequest = 1
Else
XWN_FocusRequest = 0
XWN_MouseOldX := XWN_MouseX
XWN_MouseOldY := XWN_MouseY
XWN_MouseMovedTickCount := A_TickCount
}
Else
If ( XWN_FocusRequest and (A_TickCount - XWN_MouseMovedTickCount > 500) )
{
WinGetClass, XWN_WinClass, ahk_id %XWN_WinID%
If ( XWN_WinClass = "Progman" )
Return
; checks wheter the selected window is a popup menu
; (WS_POPUP) and !(WS_DLGFRAME | WS_SYSMENU | WS_THICKFRAME)
WinGet, XWN_WinStyle, Style, ahk_id %XWN_WinID%
If ( (XWN_WinStyle & 0x80000000) and !(XWN_WinStyle & 0x4C0000) )
Return
IfWinNotActive, ahk_id %XWN_WinID%
WinActivate, ahk_id %XWN_WinID%
XWN_FocusRequest = 0
}
Return