Switch keyboard layout Works but NOT Always - autohotkey

I'm a bit new to Autohotkey.
I have 3 Language installed, one of them I use very rarely. so I want to Toggle switch only between 2 languages (EN-RU) using WIN+Space.
I searched web found code which was short and logically close to my need, I done some modification to be more object like and personalised conditions.
Code: Select all - Expand View
#Space::
SetFormat, Integer, H
Lang := { "EN" : "0x4090409" , "RU" : "0x4190419", "HE": "0x40D040D" }
WinGet, WinID,, A
ThreadID:=DllCall("GetWindowThreadProcessId", "Int", WinID, "Int", "0")
InputLocaleID:=DllCall("GetKeyboardLayout", "Int", ThreadID)
if(InputLocaleID=Lang.RU OR InputLocaleID=Lang.HE)
SendMessage, 0x50,, % Lang.EN,, A
else if(InputLocaleID=Lang.EN)
SendMessage, 0x50,, % Lang.RU,, A
Exit
it works well with most of programs but with few of them it only get switch to RU.
Works Well: Chrome, notePad, notePad++, Notion, VScode, Android Studio, IntelliJ IDEA,
Doesn't Work: OneNote Windows 10 app (even so in Onenote 2016 it works fine)
If someone can help me with it I would Greatly appreciate it.
Thanks in Advance!

related answer Autohotkey Forum
#Space:: ; Switch keyboard (EN-RU)
Lang := { "EN": 0x4090409, "RU": 0x4190419 }
; For compatibility with UWP apps, get the thread of the focused
; control, not the active window. This is necessary because those
; apps are hosted within a window owned by a different process.
ControlGetFocus Focused, A
ControlGet CtrlID, Hwnd,, % Focused, A
; Using Ptr vs. Int vs. UInt won't matter in these cases
ThreadID := DllCall("GetWindowThreadProcessId", "Ptr", CtrlID, "Ptr", 0)
; HKL is a handle type (64-bit on x64)
InputLocaleID := DllCall("GetKeyboardLayout", "UInt", ThreadID, "Ptr")
if (InputLocaleID != Lang.EN)
SendMessage, 0x50,, % Lang.EN,, ahk_id %CtrlID%
else
SendMessage, 0x50,, % Lang.RU,, ahk_id %CtrlID%
Exit

Related

AHK Trouble getting my image to show when pressing GUI

I've been editing a code to make it more personal and can't seem to get the %crsLocation% image to open with it. The button presses, but nothing else happens. I have tried directly connecting the directory to no prevail. I'm not sure what else to do. I am still kinda new to AHK and besides some basic classes in college and Codecademy my knowledge is still limited.
I was wondering if anyone could see what I am doing wrong
#NoEnv
#SingleInstance Force
SetBatchLines, -1
SetWorkingDir, A_ScriptDir
; GUI Design
Gui Show, x600 y325 w481 h381, CrossHair Overlay
Gui, Color, Gray
Gui, Font, Caqua
; GUI Buttons
Gui Add, Button, vCrosshair gCrosshair Default w80, Crosshair
Gui Add, Button, vReload gReload Default w80, Reload
Gui Add, Button, vExit gExit Default w80, Exit
Return
; Labels
Reload:
Reload
return
Exit:
ExitApp
return
Crosshair:
If _Crosshair := ! _Crosshair
Loop
{
;Config
crsLocation := "crosshairdot.png"
crsHeight := "7"
crsWidth := "7"
invsColor := "ffffff"
locCompensator := "4"
locX := "960"
loxY := "540"
;End of config
diflocX := locX - locCompensator
diflocY := locY - locCompensator
setCross = 0
~XButton2::
if (setCross = 0) {
Gui, chscript: New
Gui, Add, Picture, x0 y0 h%crsHeight% w%crsWidth%, %crsLocation%
Gui +LastFound +AlwaysOnTop -Caption +ToolWindow +E0x00000020
Gui, Show, x%diflocX% y%diflocY% h%crsHeight% w%crsWidth%
; Middle of Screen = 960 540
Gui, Color, %invsColor%
WinSet, TransColor, %invsColor%
setCross = 1;
}
else {
Gui, chscript: Destroy
setCross = 0
}
Return
}
Return
Return
First of all in the documents it states scriptdir with percents around it, even though it works without signs I'd stick with docs suggestions,
SetWorkingDir, %A_ScriptDir%
and then there is this typo,
loxY := "540"
should be locY I belive

Autohotkey DLLcall to CreateCaret returns 0 (The function failed) but A_LastError is also 0 (The function succeeded)

I'm trying to use a simple AHK DLLCall to the user32 api function CreateCaret. I want it to give notepad a thick text caret.
caretWidth := 10
NULL := 0
Ptr := A_PtrSize ? "Ptr" : "UInt" ; If A_PtrSize is not defined, use UInt instead.
WinHwnd := WinExist("A")
result := Dllcall("CreateCaret", Ptr, WinHwnd, Ptr, NULL, "Int", caretWidth, "Int", 0)
msgbox % "LE " A_lasterror ; Gives LE 0
msgbox % result ; Gives 0
This should be equivalent to the following c++ call:
CreateCaret(0x37072c, NULL, 10, 0);
Purposefully screwing up the function name makes result blank, so I believe the function is being called correctly. I just don't know why it is failing
Using similar code for GetCursorBlinkRate returns a sensible number.
I have also tried with caretWidth := 0
Similar questions about GetLastError are c++ calls, and AHK supposedly ensures that GetLastError is called in a timely enough manner to ensure A_lasterror is set correctly. Why is it showing no error code when the function apparently fails?
You can't change the caret of an external process.
If you try this for example, you'll see it works just fine if you own the process:
#Persistent
Gui, +hwndHWND
Gui, Add, Edit
Gui, Show
DllCall("CreateCaret", Ptr, HWND, Ptr, 0, Int, 50, Int, 50)
DllCall("ShowCaret", Ptr, HWND)
ESC::
GuiClose:
ExitApp

get keyboard layout of active window (win 10)

I use this script to track the keyboard layout on Win 7, it works ok:
getactiveKL() {
active_hwnd := WinExist("A")
threadID := dllCall("GetWindowThreadProcessId", "uint", active_hwnd)
code := dllCall("GetKeyboardLayout", "uint", threadID, "uint") & 0xFFFF
return code
}
; 1049 - RU (hex: 419)
; 1033 - EN (hex: 409)
loop {
sleep, 600
KL := getactiveKL()
tooltip, %KL%
}
But it dooes not work on win 10. Namely it works only once - if I set the layout to RU, and then run this script, it detects correctly, but when I switch the layout - nothing changes.
Do you know how to make it work on windows 10?
The problem was in this line:
threadID := dllCall("GetWindowThreadProcessId", "uint", active_hwnd)
It should be:
threadID := dllCall("GetWindowThreadProcessId", "uint", active_hwnd, "uint", 0)
There are many examples in the web with different spelling of this dll call, so the latter works on windows 10 correctly.

Toggle HighContrast Theme - windows 10

I want to be able to toggle the HighContrast Theme in Windows 10, by pressing F1.
The shortcut for toggling the HighContrast Theme in Windows 10 is:
Left Alt + Left Shift + Print Screen
https://msdn.microsoft.com/en-us/library/hh923906.aspx
Here is my script:
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
; Toggle HighContrast Theme: Alt + Shift + PrintScreen
F1::
Send !+{PrintScreen}
Return
You can apply the setting by manually running the .theme file. The problem is that it will open the Settings dialog. This script will run the high contrast 1 theme file, wait for the Settings dialog to open, then close it.
Edit: Added code to toggle between two themes
hc := false
hctheme := "C:\Windows\Resources\Ease of Access Themes\hc1.theme"
stdtheme := "C:\Windows\Resources\Themes\theme1.theme"
; your personalized theme may be in
; C:\Users\{user.name}\AppData\Local\Microsoft\Windows\Themes\Custom.theme
F1::
hc := !hc
if (hc)
run %hctheme%
else
run %stdtheme%
WinWait Settings
WinClose Settings
return
In testing this, it seems that the Alt+PrtScr keyboard combo is hooked too low in the OS to be overridden by AutoHotKey to add in the Shift modifier before it just goes with the default of taking a screenshot of the active window. (Looking around the AHK forums, this seems to be the consensus as well.)
I did manage to find some script suggestions here, of which this slight modification does work for me on Win10 Pro:
F1:: ;toggle high contrast
vSize := A_PtrSize=8?16:12
VarSetCapacity(HIGHCONTRAST, vSize, 0)
NumPut(vSize, &HIGHCONTRAST, 0, "UInt") ;cbSize
;SPI_GETHIGHCONTRAST := 0x42
DllCall("user32\SystemParametersInfo", UInt,0x42, UInt,vSize, Ptr,&HIGHCONTRAST, UInt,0)
vFlags := NumGet(&HIGHCONTRAST, 4, "UInt") ;dwFlags
;JEE_Progress(vFlags, 1000)
if (vFlags & 1) ;HCF_HIGHCONTRASTON := 0x1
vFlags -= 1
else
vFlags += 1
;JEE_Progress(vFlags, 1000)
VarSetCapacity(HIGHCONTRAST, vSize, 0)
NumPut(vSize, &HIGHCONTRAST, 0, "UInt") ;cbSize
NumPut(vFlags, &HIGHCONTRAST, 4, "UInt") ;dwFlags
;SPI_SETHIGHCONTRAST := 0x43
DllCall("user32\SystemParametersInfo", UInt,0x43, UInt,vSize, Ptr,&HIGHCONTRAST, UInt,0)
return
Use this:
F1::
Send {LAlt down}{LShift down}{PrintScreen}{LAlt Up}{LShift Up}
return
From official documentation:
Press use down like : {LWin down} {RWin down}
Release use up like : {LWin up} {RWin up}

Autohotkey: How can I get the positions of win 7 desktop icons

I want to implement a poor mans "Windows Fences" (by stardock software) using autohotkey.
It can be as ineffective as it can as far as programming goes. I just want to get the positions of each desktop icon upon running a ahk code snippet and using another code snippet, I'd like to put them back to where they were.
I looked at the ahk code contributions and didn't see anything like this. But again, my search terms might be a little off. Assuming no such code exists, is there a way to get the screen positions of each icon and their identifying information in autohotkey ? This will at least help me start. I am sure more questions will come.
Example
Try the following with the function posted below :
icons := getDeskIconsPos()
chromePos := icons["Google Chrome"]
for k, pos in chromePos
{
msgbox % "Google Chrome.lnk is at X: " pos.x " Y: " pos.y
}
Description
The function returns an object (thanks to MCL) with each item being identified by name. Under each name item is an array of all occurring instances. Each array item will have an X and Y containing the corresponding coordinates.
See code for THE_ITEMNAME, THE_X_COORD and THE_Y_COORD.
I have used these names to clarify where the information is stored.
The Function
getDeskIconsPos() {
Critical
static MEM_COMMIT := 0x1000, PAGE_READWRITE := 0x04, MEM_RELEASE := 0x8000
static LVM_GETITEMPOSITION := 0x00001010, LVM_SETITEMPOSITION := 0x0000100F, WM_SETREDRAW := 0x000B
ControlGet, hwWindow, HWND,, SysListView321, ahk_class Progman
if !hwWindow ; #D mode
ControlGet, hwWindow, HWND,, SysListView321, A
IfWinExist ahk_id %hwWindow% ; last-found window set
WinGet, iProcessID, PID
hProcess := DllCall("OpenProcess" , "UInt", 0x438 ; PROCESS-OPERATION|READ|WRITE|QUERY_INFORMATION
, "Int", FALSE ; inherit = false
, "ptr", iProcessID)
ret := {}
if hwWindow and hProcess
{
ControlGet, list, list,Col1
VarSetCapacity(iCoord, 8)
pItemCoord := DllCall("VirtualAllocEx", "ptr", hProcess, "ptr", 0, "UInt", 8, "UInt", MEM_COMMIT, "UInt", PAGE_READWRITE)
Loop, Parse, list, `n ;Loop through items in list and get the information from the POINT structures
{
SendMessage, %LVM_GETITEMPOSITION%, % A_Index-1, %pItemCoord%
DllCall("ReadProcessMemory", "ptr", hProcess, "ptr", pItemCoord, "UInt", &iCoord, "UInt", 8, "UIntP", cbReadWritten)
;<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>
THE_ITEMNAME := A_LoopField
THE_X_COORD := NumGet(iCoord,"Int")
THE_Y_COORD := Numget(iCoord, 4,"Int")
;<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>
if(!ret.HasKey(THE_ITEMNAME))
{
ret[THE_ITEMNAME] := []
}
ret[THE_ITEMNAME].Insert({x: THE_X_COORD, y: THE_Y_COORD})
}
DllCall("VirtualFreeEx", "ptr", hProcess, "ptr", pItemCoord, "ptr", 0, "UInt", MEM_RELEASE)
}
DllCall("CloseHandle", "ptr", hProcess)
return ret
}
Extra
If you simply want to save and restore the desktop icon positions, you may try DeskIcons() here :
http://ahkscript.org/boards/viewtopic.php?f=6&t=3529
Example usage of DeskIcons() :
; save positions
coords := DeskIcons()
MsgBox now move the icons around yourself
; load positions
DeskIcons(coords)
I don't think there's an easy way to achieche this. But ImageSearch should work quite well if performance isn't an issue (even if it is: for smaller numbers of icons, it should still perform acceptably). The only problem I see is the desktop background: If it changes, ImageSearch will most likely fail, except for perfectly quadratic/nontransparent icons. There are three workarounds for that:
Never change your desktop background. The easiest way but most likely not an option if you are a frequent desktop restyler.
Take new screenshots of the icons every time you change the background. Very high maintenance depending on your need to change the desktop.
Let the script change the desktop background to a default color before it runs ImageSearch. My favorite since it's easy to implement and you won't have to worry about anything.
After you've found the position of the respective icon, the rest is pretty trivial: MouseClickDrag it from its old position to the target position.
References:
ImageSearch
docs
MouseClickDrag docs
Changing the desktop background with AHK