Hello just me,
First of all, thank you for this awesome class
I have made a little input viewer with the help of
Class_CtlColors. It looks like this:
I use
Class_CtlColors to color my GUI controls. Whenever a key is pressed down or released, the corresponding control's color should change.
However I'm facing a problem. The program works fine at the beginning, but it will
stop working after some time.
By
after some time I mean:
For example, it may be working for 47 minutes and then it stops working.
By
stop working I mean:
- It stops showing my key press. The view does not update anymore. Instead, it fixes on the last key(s) I pressed before it stopped working.
- Right click on the tray brings nothing. Default behavior: AHK default tray menu should show up.
- Somehow the program is still running. For example, it can still print logs. And it doesn't show "Not Responding" in task manager.
I use it to display my key press in gaming, so the colors will change very often and rather fast. Can this be the cause of the problem? I know nothing about Windows API, I am just guessing that maybe it's kind of heavy operation...
Here's my code:
IWannaInputViewer.ahk
Code: Select all
#SingleInstance Force
#NoEnv
; #Warn
#Include <Class_CtlColors>
class IWannaInputViewer {
static config := { Left: { options: "x129 y97 w30 h30", text: "" } ; Designed in AutoGUI 2.5.4
, Right: { options: "x193 y97 w30 h30", text: "" }
, Up: { options: "x161 y65 w30 h30", text: "" }
, Down: { options: "x161 y97 w30 h30", text: "" }
, LShift: { options: "x1 y65 w62 h30", text: "Shift" }
, RShift: { options: "x97 y65 w62 h30", text: "Shift" }
, Z: { options: "x65 y65 w30 h30", text: "Z" }
, R: { options: "x65 y1 w30 h30", text: "R" }
, S: { options: "x65 y33 w30 h30", text: "S" }
, Q: { options: "x33 y1 w30 h30", text: "Q" }
, P: { options: "x97 y1 w30 h30", text: "P" }
, Enter: { options: "x129 y33 w62 h30", text: "Enter" }
, Backspace: { options: "x129 y1 w62 h30", text: "Back" }
, F2: { options: "x1 y1 w30 h30", text: "F2" }
, CapsLock: { options: "x1 y33 w62 h30", text: "Caps" }
, RControl: { options: "x97 y97 w30 h30", text: "Ctrl" } }
static commonOptions := "+Center +0x200" ; +Border
static fontName := "Envy Code R"
static fontOptions := "s9 q3"
static windowTitle := "I wanna be the Input Viewer"
static windowW := 224, windowH := 128
static windowBgColor := "000000"
static idleKeyBgColor := "333333"
static idleKeyTextColor := "666666"
static activeKeyBgColor := "666666"
static activeKeyTextColor := "CCCCCC"
static classInitialized := IWannaInputViewer.ClassInit()
static debugMode := False
ClassInit() {
#Include %A_LineFile%/../IWannaInputViewer_Unicode.ahk
this.config.Left.text := STRINGS.LEFT_ARROW
this.config.Right.text := STRINGS.RIGHT_ARROW
this.config.Up.text := STRINGS.UP_ARROW
this.config.Down.text := STRINGS.DOWN_ARROW
Return True
}
class Key {
isDown := False
hwnd :=
__New(hwnd := "") {
If (hwnd != "") {
this.hwnd := hwnd
}
}
}
static keys := {}
; https://autohotkey.com/docs/misc/SendMessageList.htm
static WINDOWS_MESSAGES := { WM_LBUTTONDOWN: 0x201, WM_NCLBUTTONDOWN: 0xA1 }
NewGui() {
Gui, IWannaInputViewer:New, +AlwaysOnTop, % this.windowTitle
Gui, Font, % this.fontOptions, % this.fontName,
Gui, Color, % this.windowBgColor
For k, v in this.config {
keyName := k
options := v.options . " " . this.commonOptions . " Hwndh"
text := v.text
Gui, Add, Text, %options%, %text%
this.keys[keyName] := new IWannaInputViewer.Key(h)
; Color it
CtlColors.Attach(h, this.idleKeyBgColor, this.idleKeyTextColor)
; Create hotkeys
funcObj := ObjBindMethod(this, "OnKeyDown", keyName)
Hotkey, ~*%keyName%, %funcObj%
funcObj := ObjBindMethod(this, "OnKeyUp", keyName)
Hotkey, ~*%keyName% up, %funcObj%
}
options := "w" . this.windowW . " h" . this.windowH
Gui, Show, %options%,
funcObj := ObjBindMethod(this, "GuiMove")
OnMessage(this.WINDOWS_MESSAGES.WM_LBUTTONDOWN, funcObj)
funcObj := ObjBindMethod(this, "ToggleDebugMode")
Menu, IWannaInputViewerContextMenu, Add, % "Debug Mode", %funcObj%
}
OnKeyDown(keyName) {
If (this.keys[keyName].isDown == False) {
this.keys[keyName].isDown := True
this.Mark(keyName, True)
If (this.debugMode) {
this.DebugLog("OnKeyDown(" . keyName . ")")
}
}
}
OnKeyUp(keyName) {
If (this.keys[keyName].isDown == True) {
this.keys[keyName].isDown := False
this.Mark(keyName, False)
If (this.debugMode) {
this.DebugLog("OnKeyUp(" . keyName . ")")
}
}
}
Mark(keyName, isDown) {
If (isDown) {
; GuiControl, Show, % this.keys[keyName].hwnd,
CtlColors.Change(this.keys[keyName].hwnd, this.activeKeyBgColor, this.activeKeyTextColor)
}
Else {
; GuiControl, Hide, % this.keys[keyName].hwnd,
CtlColors.Change(this.keys[keyName].hwnd, this.idleKeyBgColor, this.idleKeyTextColor)
}
}
GuiMove() {
PostMessage, % this.WINDOWS_MESSAGES.WM_NCLBUTTONDOWN, 2, , , A
}
DebugLog(msg) {
FormatTime, timeStr, %A_Now%, Time
text = [%timeStr%] %msg%`n
FileAppend, %text%, iwbtiv.log
}
ToggleDebugMode() {
this.debugMode := !this.debugMode
Menu, IWannaInputViewerContextMenu, % this.debugMode ? "Check" : "Uncheck", % "Debug Mode"
Return this.debugMode
}
}
IWannaInputViewerGuiEscape() {
IWannaInputViewerGuiClose()
}
IWannaInputViewerGuiClose() {
ExitApp
}
IWannaInputViewerGuiContextMenu() {
Menu, IWannaInputViewerContextMenu, Show
}
IWannaInputViewer.NewGui()
IWannaInputViewer_Unicode.ahk
Code: Select all
STRINGS := { UP_ARROW: "↑"
, DOWN_ARROW: "↓"
, LEFT_ARROW: "←"
, RIGHT_ARROW: "→" }
Actually I have fixed the problem using a temporary way. If I create two
Text control for each key, one for the idle status, one for the pressed down status, and use
GuiControl, Show and
GuiControl, Hide to show or hide the pressed down status one, then the program will work all the way. I'm just kind of not satisfied with this solution :/