I am trying to change cursor color when the mouse left button is in the 'hold down state'. This is supposed to work in Windows 10, so something at the OS level, not in any specific program. I would like to do this to know when "ClickLock" is enabled.
Is there anyway to achieve this?
I have tried with Autohotkey but nothing happens
; Cursor types
IDC_APPSTARTING := 32650
~LButton::
while GetKeyState("LButton", "P")
{
; this is the code to the Dll call, but I am not sure how to integrate it
hCursor:=DllCall("LoadCursor", "UInt", NULL,"Int", IDC_APPSTARTING, "UInt")
DllCall("SetCursor","UInt",hCursor)
}
return
For more info, please refer to: https://autohotkey.com/board/topic/32608-changing-the-system-cursor/
IDC_APPSTARTING := 32650
~LButton::
changeCursor(IDC_APPSTARTING)
Return
~LButton Up::
changeCursor()
Return
changeCursor(cursor := 0) {
if (cursor) {
CursorHandle := DllCall("LoadCursor", Uint, 0, Int, cursor)
Cursors = 32512,32513,32514,32515,32516,32640,32641,32642,32643,32644,32645,32646,32648,32649,32650,32651
Loop, Parse, Cursors, `,
DllCall("SetSystemCursor", Uint, CursorHandle, Int, A_Loopfield )
} else {
DllCall("SystemParametersInfo", UInt, 0x57, UInt, 0, UInt, 0, UInt, 0 )
}
}
Have you tried anything yet? I would say probably start googling. I came across a few different resources on the first try that pointed me in the direction of the registry keys, and even a nifty powershell script to set them on demand. Do a little research, bro. Happy coding.
So I use a clock replacement program. The problem is it also hijack clicks on the clock. So whenever I click on the clock in the notification area, program's popup menu launch rather than the default windows clock widget.
I also tried AHK ControlClick on TrayClockWClass. I still didn't get original widget. Is there any way to launch the original widget programmatically? I use Windows 10 1607.
I am fine with RunDll, API, SendMessage or any other way whatsoever.
Somebody upvoted my question today. So maybe they are looking for the answer. I posted it on autohotkey.com forums back then, and I get the answer there.
https://autohotkey.com/boards/viewtopic.php?t=21274
ControlGet, hClock, Hwnd,, TrayClockWClass1, ahk_class Shell_TrayWnd ; https://autohotkey.com/board/topic/70770-win7-taskbar-clock-toggle/
if (hClock) {
VarSetCapacity(IID_IAccessible, 16), DllCall("ole32\CLSIDFromString", "WStr", "{618736e0-3c3d-11cf-810c-00aa00389b71}", "Ptr", &IID_IAccessible)
if (DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hClock, "UInt", OBJID_CLIENT := 0xFFFFFFFC, "Ptr", &IID_IAccessible, "Ptr*", accTrayClock))
return
VarSetCapacity(variant, A_PtrSize == 8 ? 24 : 16, 0), NumPut(VT_I4 := 3, variant,, "UShort")
if (A_PtrSize == 4) ; https://autohotkey.com/boards/viewtopic.php?p=111355#p111355
DllCall(NumGet(NumGet(accTrayClock+0)+25*A_PtrSize), "Ptr", accTrayClock, "Int64", NumGet(variant, 0, "Int64"), Int64, NumGet(variant, 8, "Int64")) ; IAccessible::DoDefaultAction
else
DllCall(NumGet(NumGet(accTrayClock+0)+25*A_PtrSize), "Ptr", accTrayClock, "Ptr", &variant) ; IAccessible::DoDefaultAction
ObjRelease(accTrayClock)
}
It is a bit beyond of my knowledge, so I copy&pasted the whole script.
But I was rejected with a message, which reads, (Firefox version is 28.0) Anybody please help me.
Error: Call to nonexistent function.
Specifically: Acc_Get( ... ...
SetTitleMatchMode 2
WinGet, windows, List, Mozilla Firefox
Loop %windows% {
hwnd := windows%A_Index%
;// Acc_Get(Cmd, ChildPath="", ChildID=0, WinTitle="", WinText="", ExcludeTitle="", ExcludeText="")
page_tab_list := Acc_Get("object", "application.grouping2.property_page.tool_bar3.page_tab_list", "", "ahk_id" hwnd)
For Each, tab in Acc_Children(page_tab_list)
if tab.accName(0) = "https://www.apple.com/" {
tab.accDoDefaultAction(0) ;// remove line to NOT activate tab
WinActivate ahk_id %hwnd%
break 2
}
}
This script simply walks through all tabs until it finds the correct one, via the page title in the window title. Sleep timer can be adjusted.
SetTitleMatchMode 2
needle := "Stack Overflow"
WinActivate, Firefox
Loop {
WinGetTitle, title
IfWinNotActive, Firefox
break
if (InStr(title,needle))
Break
Else
send ^{PgUp}
sleep 50
}
You didn't take all the dependencies from the source. You are missing the required Acc Library.
; Acc.ahk https://github.com/sancarn/ACC.AHK/blob/master/AccV2.ahk
; ACC Tutorial: https://www.autohotkey.com/boards/viewtopic.php?f=7&t=40590
I am looking for a way to add an option(s) to the right click context menu when editing text on a WinXP machine. I already do a lot of copy/pasting on it, so the clipboard is always changing, but there is one string I type repeatedly in almost every file I edit.
I've already added some custom option to the context menu for .zip files to batch unzip them, but I'm not having any luck finding a way to add this.
The machine is used for a single purpose and I try to keep it as stable as possible so I'm trying to stay away from any new third-party software that could bloat the system.
I don't think there's an extension point for that sort of thing. You'd have to inject code into every process that has a window with a text box control, which would be complicated and frowned upon by most anti-virus applications.
I know you said you wanted to avoid third-party software, but there really isn't any way around it. A program like AutoIt will allow you to create a custom keyboard shortcut to paste whatever text you like into almost any application. It would probably be much more stable than any custom program written in the short term.
You can even compile the automation script to a standalone executable if you don't want to install the entire AutoIt distribution on the machine.
Assuming you are referring to the Edit control context menu.
You can achieve this by cloning and amending the Edit control context menu, via AutoHotkey. If the context menu is a for a different type of control, the same principle applies but it may be harder to recreate the existing menu item functions.
To 'add' a menu item, the simplest method would be to replace the entire menu with your own custom context menu. With your custom menu item at the top of it, and you would probably want to recreate the Undo/Cut/Copy/Paste/Delete/Select All items that appear on the Edit control. Using ControlGet, vText, Selected to recreate the Copy function for example. You use #IfWinActive to make
the menus only appear if a certain window is the active window, e.g. only if Notepad is the active window.
You would also need to capture right-clicks via the RButton hotkey and/or capture AppsKey presses,
and use ControlGetFocus to check if an Edit control was in focus, and MouseGetPos to check if an Edit control was under the cursor. So there would be a bit of work involved. Regarding capturing right-clicks, see the link below, where you would replace LButton with RButton. Good luck!
Is it possible to catch the close button and minimize the window instead? AutoHotKey
Similar question:
Can I edit the context menu of a text field (not Explorer context menu)?
Note:
- For typing long/repetitive strings, the use of hotstrings in AutoHotkey can really facilitate this. Achievable in literally one line of code.
- For batch jobs involving zip files perhaps try 7-Zip and using command lines parameters in AutoHotkey. This could probably be achieved in around 10 or 20 lines of code.
AutoHotkey is very lightweight, about 1MB, you could try it for a day or two, possibly watch a short 'hello world' tutorial video, it can be quite easy to get started.
The question asks how to edit the context menu for an Edit control,
it it slightly unclear whether this is wanted for renaming or editing files,
the AutoHotkey script below replicates
the Edit control menu when editing files in Explorer and using Notepad.
It adds a button that sends a string to the Edit control.
The script shows a custom context menu,
when an Edit control is right-clicked,
or when an Edit control is focused and the AppsKey is pressed.
Note: The script below is tested on Windows 7,
but the methods should work on Windows XP.
Note: The Explorer address bar also uses an Edit control,
however, this is taken into account by the script.
Note: You requested a method that is lightweight,
AutoHotkey can be run with one exe file (under 2MB in size),
and one script file. Scripts can also be compiled to small exes.
;AutoHotkey script for:
;contextmenu - Can I add a custom paste option to the windows text editing context menu? - Stack Overflow
;http://stackoverflow.com/questions/17370415/can-i-add-a-custom-paste-option-to-the-windows-text-editing-context-menu/41343891#41343891
;see also:
;windows - Can I edit the context menu of a text field (not Explorer context menu)? - Stack Overflow
;http://stackoverflow.com/questions/39827324/can-i-edit-the-context-menu-of-a-text-field-not-explorer-context-menu/41343741#41343741
;tested on Windows 7
GroupAdd, WinGroupFolder, ahk_class CabinetWClass ;explorer
#IfWinActive, ahk_group WinGroupFolder
$RButton Up:: ;explorer - custom Edit control menu
$AppsKey:: ;explorer - custom Edit control menu
#IfWinActive, ahk_class Notepad
$RButton Up:: ;notepad - custom Edit control menu
$AppsKey:: ;notepad - custom Edit control menu
;STAGE - create menu if not already created
if !vIsReady
{
Menu, EditMenu, Add, &My Item, MyItem
Menu, EditMenu, Add ;------------------------------
Menu, EditMenu, Add, &Undo, EditUndo
Menu, EditMenu, Add ;------------------------------
Menu, EditMenu, Add, Cu&t, EditCut
Menu, EditMenu, Add, &Copy, EditCopy
Menu, EditMenu, Add, &Paste, EditPaste
Menu, EditMenu, Add, &Delete, EditDelete
Menu, EditMenu, Add ;------------------------------
Menu, EditMenu, Add, Select &All, EditSelectAll
VarSetCapacity(vPos1, 4), VarSetCapacity(vPos2, 4)
VarSetCapacity(vPos1X, 4), VarSetCapacity(vPos2X, 4)
vIsReady := 1
}
;STAGE - perform certain checks, if any of them fail
;then let hotkeys perform their normal function,
;start by stating that, so far, the checks have not failed
vRet := 1
;check - if active control is an Edit/RichEdit control
if vRet
{
WinGet, hWnd, ID, A
ControlGetFocus, vCtlClassNN, ahk_id %hWnd%
ControlGet, hCtl, Hwnd, , %vCtlClassNN%, ahk_id %hWnd%
WinGetClass, vWinClass, ahk_id %hCtl%
if !(SubStr(vWinClass, 1, 4) = "Edit") && !(SubStr(vWinClass, 1, 8) = RichEdit)
vRet := 0
}
;check - if a right-click was performed, the control
;under the cursor must be the active control
if vRet && InStr(A_ThisHotkey, "RButton")
{
CoordMode, Mouse, Screen
MouseGetPos, vPosX, vPosY, , hCtl2, 3
if !(hCtl2 = hCtl)
vRet := 0
}
;check - the Edit control must be for a file icon and not the address bar
if vRet
{
;hWndParent := DllCall("user32\GetParent", Ptr,hCtl, Ptr)
hWndParent := DllCall("user32\GetAncestor", Ptr,hCtl, UInt,1, Ptr) ;GA_PARENT := 1
WinGetClass, vWinClassParent, ahk_id %hWndParent%
if (vWinClassParent = "ComboBox")
vRet := 0
}
;if a check has failed, then let hotkeys perform their normal function
if !vRet
{
if InStr(A_ThisHotkey, "RButton")
SendInput {Click right}
if InStr(A_ThisHotkey, "AppsKey")
SendInput {AppsKey}
Return
}
;STAGE - if clicked Edit control, menu will appear
;relative to cursor coordinates retrieved earlier,
;if pressed AppsKey, menu will appear in centre of Edit control
if !InStr(A_ThisHotkey, "RButton")
{
WinGetPos, vPosX, vPosY, vPosW, vPosH, ahk_id %hCtl%
vPosX += vPosW/2, vPosY += vPosH/2
}
;STAGE - retrieve information from Edit control
;and disable menu items accordingly
;Undo - check undo status (is undo available)
;Cut - check text selection > 0
;Copy - check text selection > 0
;Paste - check clipboard not empty
;Delete - check text selection > 0
;Select All - always available
SendMessage, 0xC6, 0, 0, , ahk_id %hCtl% ;EM_CANUNDO := 0xC6
vOptU := ErrorLevel ? "En" : "Dis" ;1=undo available/0=undo not available
ControlGet, vText, Selected, , , ahk_id %hCtl%
vOptT := StrLen(vText) ? "En" : "Dis"
vOptC := StrLen(Clipboard) ? "En" : "Dis"
Menu, EditMenu, % vOptU "able", &Undo, EditUndo
Menu, EditMenu, % vOptT "able", Cu&t, EditCut
Menu, EditMenu, % vOptT "able", &Copy, EditCopy
Menu, EditMenu, % vOptC "able", &Paste, EditPaste
Menu, EditMenu, % vOptT "able", &Delete, EditDelete
;STAGE - get Edit control character positions
;(unfortunately showing the custom menu ends the rename mode,
;we get the Edit control character positions in order to restore them later)
SendMessage, 0xB0, &vPos1, &vPos2, , ahk_id %hCtl% ;EM_GETSEL := 0xB0
vPos1 := NumGet(vPos1), vPos2 := NumGet(vPos2)
;STAGE - show menu
CoordMode, Menu, Screen
Menu, EditMenu, Show, %vPosX%, %vPosY%
Return
;==============================
;STAGE - replicate standard Edit control menu items
;(or perform custom menu function)
;(unfortunately showing the custom menu ends the rename mode,
;so the Edit control has to be put into rename again,
;and the character positions restored)
EditUndo:
EditCut:
EditCopy:
EditPaste:
EditDelete:
EditSelectAll:
MyItem:
;STAGE - enter rename mode again
IfWinActive, ahk_group WinGroupFolder
{
SendInput {F2}
Loop, 20
{
ControlGetFocus, vCtlClassNN, ahk_id %hWnd%
if (SubStr(vCtlClassNN, 1, 4) = "Edit")
break
Sleep 50
}
if !(SubStr(vCtlClassNN, 1, 4) = "Edit")
{
MsgBox % "error"
Return
}
ControlGet, hCtl, Hwnd, , % vCtlClassNN, ahk_id %hWnd%
;STAGE - restore character positions
if !InStr(A_ThisLabel, "SelectAll")
{
vRet := 0
Loop, 100
{
SendMessage, 0xB1, vPos1, vPos2, , ahk_id %hCtl% ;EM_SETSEL := 0xB1
SendMessage, 0xB0, &vPos1X, &vPos2X, , ahk_id %hCtl% ;EM_GETSEL := 0xB0
vPos1X := NumGet(vPos1X), vPos2X := NumGet(vPos2X)
if (vPos1 = vPos1X) && (vPos2 = vPos2X)
{
vRet := 1
break
}
Sleep 50
if !vRet
{
MsgBox % "error"
Return
}
}
}
}
;STAGE - perform standard Edit control menu functions
if InStr(A_ThisLabel , "Undo")
SendMessage, 0x304, , , , ahk_id %hCtl% ;WM_UNDO := 0x304
if InStr(A_ThisLabel , "Cut")
SendMessage, 0x300, , , , ahk_id %hCtl% ;WM_CUT := 0x300
if InStr(A_ThisLabel , "Copy")
SendMessage, 0x301, , , , ahk_id %hCtl% ;WM_COPY := 0x301
if InStr(A_ThisLabel , "Paste")
SendMessage, 0x302, , , , ahk_id %hCtl% ;WM_PASTE := 0x302
if InStr(A_ThisLabel , "Delete")
SendMessage, 0x303, , , , ahk_id %hCtl% ;WM_CLEAR := 0x303
if InStr(A_ThisLabel , "SelectAll")
SendMessage, 0xB1, 0, -1, , ahk_id %hCtl% ;EM_SETSEL := 0xB1
;STAGE - actions to take if user chooses custom menu item
if InStr(A_ThisLabel , "MyItem")
{
vText := "My String"
;ControlSend, , % vText, ahk_id %hCtl% ;use SendInput instead since capitalisation can be unreliable
SendInput {Raw}%vText%
}
;STAGE - actions to take if user chooses custom menu item
if 0 ;this comments out the 9 lines below
if InStr(A_ThisLabel , "MyItem") && !(vText = "")
{
MsgBox, 0x40003, , % "Choose 'Yes' to search for:`r`n" vText
IfMsgBox Yes
{
vUrl := "http://www.google.co.uk/search?q=" UriEncode(vText)
Run, "%vUrl%"
}
}
Return
#IfWinActive
;==================================================
;URL encoding - Rosetta Code
;https://www.rosettacode.org/wiki/URL_encoding#AutoHotkey
; Modified from https://autohotkey.com/board/topic/75390-ahk-l-unicode-uri-encode-url-encode-function/?p=480216
UriEncode(Uri)
{
VarSetCapacity(Var, StrPut(Uri, "UTF-8"), 0)
StrPut(Uri, &Var, "UTF-8")
f := A_FormatInteger
SetFormat, IntegerFast, H
While Code := NumGet(Var, A_Index - 1, "UChar")
If (Code >= 0x30 && Code <= 0x39 ; 0-9
|| Code >= 0x41 && Code <= 0x5A ; A-Z
|| Code >= 0x61 && Code <= 0x7A) ; a-z
Res .= Chr(Code)
Else
Res .= "%" . SubStr(Code + 0x100, -1)
SetFormat, IntegerFast, %f%
Return, Res
}
;==================================================
By default on Windows, when copying text, it gets put in the clipboard. But when attempting to copy empty text, the clipboard is untouched. For example, selecting no text in your editor, then hitting ctrl+c, will cause no change in the clipboard.
Problem is, I need to catch this event with AutoHotKey. Since the clipboard is unchanged, I have no idea how to do this cleanly (without a timeout, that is).
Does anyone have any idea how to do this?
Edit: To clarify, I'm sending the ctrl+c from within AutoHotKey. I'm doing so to tell if any text is selected, i.e., I'm sending ctrl+c, then checking if any text was copied to the clipboard or not. Problem is, if no text is selected, the clipboard handlers for AutoHotKey never get called, forcing me to use a timeout, which isn't good practice.
Here is what I did. Since the clipboard is a variable in AutoHotkey, you can check to see if it is empty. I first cleared the clipboard, send control+c, then see if the clipboard is still empty. You can temporarily move the current clipboard to a temporary place first if you want.
ClipSaved := ClipboardAll
Clipboard = ; empties the clipboard
Send ^+{Left} ; I just used highlight left to select text, you can replace this with
; whatever your program uses to select an input.
Send ^c ; attempt to copy text
If Clipboard = ; checks to see if clipboard is empty
{
break ; Put what you want to do if the clipboard is empty, I used break to stop a loop
}
Clipboard := ClipSaved ; puts the original clipboard contents back
I was searching text from an open document in which the user can choose a forward or backward direction. When going backwards, it would get stuck in a loop at the beginning of the document. I set a loop limit to keep it from being an infinite loop, but it still wasted time having to wait for the loop to finish. I used the break function to end the loop if the clipboard was empty.
To give credit where credit is due, I got the inspiration from another post which had other tood tips. It posted you can check for a blank variable with this script.
http://www.autohotkey.net/~deleyd/xprxmp/autohotkey_expression_examples.htm#J
v := ""
If v =
MsgBox v = ""
If (v = "")
MsgBox v = ""
From the AutoHotkey documentation website I found out how to temporarily store and replace the clipboard content. http://www.autohotkey.com/docs/misc/Clipboard.htm
ClipSaved := ClipboardAll ; Save the entire clipboard to a variable of your choice.
;... here make temporary use of the clipboard, such as for pasting Unicode text via Transform Unicode ...
Clipboard := ClipSaved ; Restore the original clipboard. Note the use of Clipboard (not ClipboardAll).
ClipSaved = ; Free the memory in case the clipboard was very large.
Hope this helps.
Samuel
Here's the solution I currently use. Basically, it comes down to sending ctrl+c, waiting a certain timeout, then seeing if text was actually copied. If it wasn't, I know there is not selection.
There is no way, afaik, to avoid waiting a timeout, since Windows takes a certain time to perform the copy operation. I set the timeout to 0.15 seconds, so it isn't too bad.
Here's the function I use whenever I want to grab the contents of the clipboard, or check if it's empty. I always call this function first:
clipped_text :=
clip_empty := false
ClipSaved =
is_clipped := false
clip_speed := 0.15
Clip() {
global ClipSaved
global clip_empty
global clipped_text
global is_clipped
global clip_speed
if (!is_clipped) {
ClipSaved := ClipboardAll ; Save the entire clipboard to a variable of your choice.
; msgbox % ClipSaved
is_clipped := true
}
clipboard = ; Empty the clipboard
Send ^{c}
ClipWait clip_speed
if (ErrorLevel = 1)
{
clip_empty := false
}
else
{
clip_empty := true
clipped_text := clipboard
}
}
And I use this function to actually get the contents of the clipboard or check if it's empty:
IsTextSelected() {
global ClipSaved
global clip_empty
global clipped_text
if (clip_empty == true) {
return true
}
else {
return false
}
}
To get the contents of the clipboard I just look at the clipped_text variable.
After performing a "Clip()" operation, I always call the following function to restore the clipboard (this function is called once for multiple calls of Clip()):
UnClip() {
global ClipSaved
global clip_empty
global clipped_text
global is_clipped
is_clipped := false
Clipboard := ClipSaved
ClipSaved =
}
While not an actual answer to this question, a google search might lead you here if you are looking for a way to catch text on paste and modify it before pasting.
Here's the script which eliminates whitespace from text pasted from clipboard on CTRL + V:
~^v::
Trimmed := RegExReplace(Clipboard, "^\s+", "")
Trimmed := RegExReplace(Trimmed, "\s+$", "")
Clipboard = %Trimmed%
SendInput ^v
return
I think I have a solution. Set aside current clipboard, then copy. Compare what you have copied to an empty string.. if it's equal, then something was copied; otherwise, nothing was copied. At then, restore the clipboard to what you saved. Here is a code sample demonstrating the principle.
^#x::
ClipSaved := ClipboardAll ; Save the entire clipboard to a variable of your choice.
; ... here make temporary use of the clipboard, such as for pasting Unicode text via Transform Unicode ...
Clipboard := ; Clear the clipboard
Send, {CTRLDOWN}c{CTRLUP}
if (Clipboard = "") {
Send, you copied nothing
} else {
Send, you copied something
}
Clipboard := ClipSaved ; Restore the original clipboard. Note the use of Clipboard (not ClipboardAll).
ClipSaved = ; Free the memory in case the clipboard was very large.
return
Actually, I was hoping that there is another way to simply test if the cursor is currently selecting anything. I have asked this question on the AutoHotkey forums (http://www.autohotkey.com/forum/posting.php?mode=reply&t=69468), but until or if there is a better answer, I will use the above method.
Script for babylon (Middle Mouse Key for firefox):
MButton::
SetTitleMatchMode, 2
send {LButton}{LButton}
Send ^c
sleep, 100
send {F10}
sleep, 100
SendInput {Raw}%clipboard%
send {enter}
Return
I had the same problem - I would send the copy command, but it wouldn't copy anything. I tried working with timers to no avail.
Here is what I ended up doing (trying different modes):
thisclipboard := clipboard . a_now ;add NOW so that it won't possibly be the same as the contents of the clipboard
sendplay,^c
if(clipboard == thisclipboard){
sendinput,^c
}
if(clipboard == thisclipboard){
send,^c
}
Maybe you should hotkey the Ctrl + C instead, that way any time that hotkey is pressed you will know.
You might want to make sure to send the normal Ctrl + C action to windows so you can copy.
consider this example:
~^c::
msgbox, % "Clipboard Changed even if you didnt copy anything"
. "(...not really but you tried at least)"
return
That message will fire up every time you press Ctrl + C even if you didnt copy anything to the clipboard. At the same time you will be sending the native function of Ctrl + C to windows so your clipboard WILL change if you copied something.
From the help file:
~: When the hotkey fires, its key's native function will not be blocked (hidden from the system).
You might want to also have an onClipboardChange to check when the clipboard really changed.