In any case my keyboard's LEDs have stopped working and I'm tired of not knowing whether my caps lock in on or off. This opens a little dialog that tells you. Left to right is Caps lock, Num Lock and Scroll Lock status.
This little script demos a few advanced dialog capabilities. For example:
It shows how to make your Dialog stay on top of other windows. You need two things for this to happen. Your dialog needs to have its FormStyle parameter set to "fsStayOnTop". Additionally the dialog position needs to be set on a frequent basis so there is a loop that captures the dialog's position then "moves" the dialog to its current location 100 times per second. This causes the dialog to stay at the top level of the desktop windows.
It shows a method to move a dialog around the screen with the mouse even though there is no titlebar to grab to move the dialog. Select anywhere on the dialog and move it around the desktop.
It shows a use for SetControlText> as mentioned in THIS forum post. In this case if a second instance of the script is run, it passes the initial coordinates of the dialog back to the first instance of the script. The first instance of the script then moves its dialog to those coordinates and the second instance quits. This is useful for not having multiple instances running. Also, if a second instance was started it usually means the first instance's dialog is off screen somewhere and therefore not visible. Passing the initial coordinates and having the dialog move there makes it visible and available again.
ALT + Q will close the program.
Code: Select all
//Initial position for the Lock Key display dialog.
//Values could be stored in a config file.
Let>DiaXPos=0
Let>DiaYPos=0
//////////////////////////////////////////////////
//Allows only one instance of the app.
//Also puts the dialog in its initial position
IfWindowOpen>Display Lock Key States
SetControlText>Display Lock Key States,TEdit,2,DiaXPos
SetControlText>Display Lock Key States,TEdit,1,DiaYPos
Exit>0
EndIF
//////////////////////////////////////////////
//Key down events to detect lock key pressed
OnEvent>Key_Down,VK20,0,DetectCapState
OnEvent>Key_Down,VK144,0,DetectNumState
OnEvent>Key_Down,VK145,0,DetectScrState
////////////////////////////////////////////
//Alt + Q event to quit the app
OnEvent>Key_Down,VK81,3,Quit
///////////////////////////////
SRT>Quit
Exit>0
END>Quit
Let>lOCKTimeFlag=0
Let>MoveDialogFlag=0
Let>VK_CAPITAL=20
Let>VK_NUMLOCK=144
Let>VK_SCROLL=145
Dialog>Dialog1
object Dialog1: TForm
BorderStyle = bsNone
Caption = 'Display Lock Key States'
ClientHeight = 20
ClientWidth = 80
Color = 16777200
Formstyle = fsStayOnTop
object Panel1: TPanel
Left = 5
Top = 5
Width = 10
Height = 10
Caption = ''
ParentBackground = False
end
object Panel2: TPanel
Left = 35
Top = 5
Width = 10
Height = 10
Caption = ''
ParentBackground = False
end
object Panel3: TPanel
Left = 65
Top = 5
Width = 10
Height = 10
Caption = ''
ParentBackground = False
end
object Edit1: TEdit
Visible = False
end
object Edit2: TEdit
Visible = False
end
end
EndDialog>Dialog1
//Dialog handlers that allow the mouse to move the dialog
AddDialogHandler>Dialog1,,OnMouseDown,srtMoveDialog
AddDialogHandler>Dialog1,,OnMouseUp,srtNoMoveDialog
AddDialogHandler>Dialog1,Panel1,OnMouseDown,srtMoveDialog
AddDialogHandler>Dialog1,Panel1,OnMouseUp,srtNoMoveDialog
AddDialogHandler>Dialog1,Panel2,OnMouseDown,srtMoveDialog
AddDialogHandler>Dialog1,Panel2,OnMouseUp,srtNoMoveDialog
AddDialogHandler>Dialog1,Panel3,OnMouseDown,srtMoveDialog
AddDialogHandler>Dialog1,Panel3,OnMouseUp,srtNoMoveDialog
/////////////////////////////////////////////////////////
//Initial Dialog position saved to Dialog Labels for SetControlText> use.
SetDialogProperty>Dialog1,Edit1,Text,DiaXPos
SetDialogProperty>Dialog1,Edit2,Text,DiaYPos
/////////////////////////////////////////////////////////////
Show>Dialog1
Wait>0.1
GoSub>DetectCapState
Wait>0.1
GoSub>DetectNumState
Wait>0.1
GoSub>DetectScrState
//Loop and subs to allow mouse to move the dialog
//and to keep the dialog on top of other windows.
Label>StayOnTopLoop
Wait>0.01
//Constantly moving the dialog to its current position
//in conjuction with setting the dialog's form style to
//"fsStayOnTop" Keeps it on top of other windows.
GetDialogProperty>Dialog1,Edit1,Text,DiaXPos
GetDialogProperty>Dialog1,Edit2,Text,DiaYPos
Let>WIN_USEHANDLE=1
MoveWindow>Dialog1.handle,DiaXPos,DiaYPos
Let>WIN_USEHANDLE=0
///////////////////////////////////////////////////////
//When flag var is set to one the dialog will
//follow the mouse.
If>MoveDialogFlag=1
GetCursorPos>CurX,CurY
Let>DiaXPos=%CurX%-%XDiff%
Let>DiaYPos=%CurY%-%YDiff%
SetDialogProperty>Dialog1,Edit1,Text,DiaXPos
SetDialogProperty>Dialog1,Edit2,Text,DiaYPos
EndIf
/////////////////////////////////////////////
Goto>StayOnTopLoop
SRT>srtMoveDialog
If>MoveDialogFlag=0
Let>WIN_USEHANDLE=1
GetWindowPos>Dialog1.handle,DiaXPos,DiaYPos
Let>WIN_USEHANDLE=0
GetCursorPos>CurX,CurY
Let>XDiff=%CurX%-%DiaXPos%
Let>YDiff=%CurY%-%DiaYPos%
EndIF
Let>MoveDialogFlag=1
END>srtMoveDialog
SRT>srtNoMoveDialog
Let>MoveDialogFlag=0
END>srtNoMoveDialog
/////////////////////////////////////////////////
SRT>DetectCapState
Timer>LockTimeNow
Let>LockTimeDiff=%LockTimeNow%-%LockTimeFlag%
If>{%LockTimeDiff%>50}
LibFunc>User32,GetKeyState,CAP_STATE,VK_CAPITAL
If>{(%Cap_state%=65409)or(%Cap_state%=1)}
SetDialogObjectColor>Dialog1,Panel1,111111
Else
SetDialogObjectColor>Dialog1,Panel1,16777200
EndIf
EndIf
Let>LockTimeFlag=LockTimeNow
END>DetectCapState
SRT>DetectNumState
Timer>LockTimeNow
Let>LockTimeDiff=%LockTimeNow%-%LockTimeFlag%
If>{%LockTimeDiff%>50}
LibFunc>User32,GetKeyState,NUM_STATE,VK_NUMLOCK
If>{(%Num_state%=65409)or(%Num_state%=1)}
SetDialogObjectColor>Dialog1,Panel2,111111
Else
SetDialogObjectColor>Dialog1,Panel2,16777200
EndIf
EndIf
Let>LockTimeFlag=LockTimeNow
END>DetectNumState
SRT>DetectScrState
Timer>LockTimeNow
Let>LockTimeDiff=%LockTimeNow%-%LockTimeFlag%
If>{%LockTimeDiff%>50}
LibFunc>User32,GetKeyState,SCR_STATE,VK_SCROLL
If>{(%Scr_state%=65409)or(%Scr_state%=1)}
SetDialogObjectColor>Dialog1,Panel3,111111
Else
SetDialogObjectColor>Dialog1,Panel3,16777200
EndIf
EndIf
Let>LockTimeFlag=LockTimeNow
END>DetectScrState
It seemed reasonable to expect that clicking on the boxes would actually set the key state so the following will do that. Also changed the boxes to representative characters because over time I forgot which was which.
So now C = Caps Lock, N = Num Lock and S = Scroll Lock.
Code: Select all
//Initial position for the Lock Key display dialog.
//Values could be stored in a config file.
Let>DiaXPos=920
Let>DiaYPos=1015
//////////////////////////////////////////////////
//Allows only one instance of the app.
//Also puts the dialog in its initial position
IfWindowOpen>Display Lock Key States
SetControlText>Display Lock Key States,TEdit,2,DiaXPos
SetControlText>Display Lock Key States,TEdit,1,DiaYPos
Exit>0
EndIF
//////////////////////////////////////////////
//Key down events to detect lock key pressed
OnEvent>Key_Down,VK20,0,DetectCapState
OnEvent>Key_Down,VK144,0,DetectNumState
OnEvent>Key_Down,VK145,0,DetectScrState
////////////////////////////////////////////
//Alt + Q event to quit the app
OnEvent>Key_Down,VK81,3,Quit
///////////////////////////////
SRT>Quit
Exit>0
END>Quit
Let>lOCKTimeFlag=0
Let>MoveDialogFlag=0
Let>VK_CAPITAL=20
Let>VK_NUMLOCK=144
Let>VK_SCROLL=145
Dialog>Dialog1
object Dialog1: TForm
BorderStyle = bsNone
Caption = 'Display Lock Key States'
ClientHeight = 20
ClientWidth = 80
Color = 16777215
Formstyle = fsStayOnTop
object Panel1: TLabel
Left = 2
Top = -2
Width = 10
Height = 10
Caption = 'C'
Font.Charset = DEFAULT_CHARSET
Font.Color = clGray
Font.Height = -16
Font.Name = 'Arial'
Font.Style = [fsBold]
ParentFont = False
end
object Panel2: TLabel
Left = 33
Top = -2
Width = 10
Height = 10
Caption = 'N'
Font.Charset = DEFAULT_CHARSET
Font.Color = clGray
Font.Height = -16
Font.Name = 'Arial'
Font.Style = [fsBold]
ParentFont = False
end
object Panel3: TLabel
Left = 65
Top = -2
Width = 10
Height = 10
Caption = 'S'
Font.Charset = DEFAULT_CHARSET
Font.Color = clGray
Font.Height = -16
Font.Name = 'Arial'
Font.Style = [fsBold]
ParentFont = False
end
object Edit1: TEdit
Visible = False
end
object Edit2: TEdit
Visible = False
end
end
EndDialog>Dialog1
//Dialog handlers that allow the mouse to move the dialog
AddDialogHandler>Dialog1,,OnMouseDown,srtMoveDialog
AddDialogHandler>Dialog1,,OnMouseUp,srtNoMoveDialog
AddDialogHandler>Dialog1,Panel1,OnMouseDown,srtMoveDialog
AddDialogHandler>Dialog1,Panel1,OnMouseUp,srtNoMoveDialog(1)
AddDialogHandler>Dialog1,Panel2,OnMouseDown,srtMoveDialog
AddDialogHandler>Dialog1,Panel2,OnMouseUp,srtNoMoveDialog(2)
AddDialogHandler>Dialog1,Panel3,OnMouseDown,srtMoveDialog
AddDialogHandler>Dialog1,Panel3,OnMouseUp,srtNoMoveDialog(3)
/////////////////////////////////////////////////////////
//Initial Dialog position saved to Dialog Labels for SetControlText> use.
SetDialogProperty>Dialog1,Edit1,Text,DiaXPos
SetDialogProperty>Dialog1,Edit2,Text,DiaYPos
///////////////////////////////////////////////////////////////
Show>Dialog1
Wait>0.1
GoSub>DetectCapState
Wait>0.1
GoSub>DetectNumState
Wait>0.1
GoSub>DetectScrState
//Loop and subs to allow mouse to move the dialog
//and to keep the dialog on top of other windows.
Label>StayOnTopLoop
Wait>0.01
//Constantly moving the dialog to its current position
//in conjuction with setting the dialog's form style to
//"fsStayOnTop" Keeps it on top of other windows.
GetDialogProperty>Dialog1,Edit1,Text,DiaXPos
GetDialogProperty>Dialog1,Edit2,Text,DiaYPos
Let>WIN_USEHANDLE=1
MoveWindow>Dialog1.handle,DiaXPos,DiaYPos
Let>WIN_USEHANDLE=0
///////////////////////////////////////////////////////
//When flag var is set to one the dialog will
//follow the mouse.
If>MoveDialogFlag=1
GetCursorPos>CurX,CurY
Let>DiaXPos=%CurX%-%XDiff%
Let>DiaYPos=%CurY%-%YDiff%
SetDialogProperty>Dialog1,Edit1,Text,DiaXPos
SetDialogProperty>Dialog1,Edit2,Text,DiaYPos
EndIf
/////////////////////////////////////////////
Goto>StayOnTopLoop
SRT>srtMoveDialog
VbEval>timer,vStartTime
If>MoveDialogFlag=0
Let>WIN_USEHANDLE=1
GetWindowPos>Dialog1.handle,DiaXPos,DiaYPos
Let>WIN_USEHANDLE=0
GetCursorPos>CurX,CurY
Let>XDiff=%CurX%-%DiaXPos%
Let>YDiff=%CurY%-%DiaYPos%
EndIF
Let>MoveDialogFlag=1
END>srtMoveDialog
SRT>srtNoMoveDialog
VbEval>timer-%vStartTime%,vEndTime
If>vEndTime<0.3
If>srtNoMoveDialog_var_1=1
Press CAPS
EndIf
If>srtNoMoveDialog_var_1=2
Press num lock
EndIf
If>srtNoMoveDialog_var_1=3
Press scroll lock
EndIf
GoSub>DetectCapState
Wait>0.1
GoSub>DetectNumState
Wait>0.1
GoSub>DetectScrState
EndIf
Let>MoveDialogFlag=0
END>srtNoMoveDialog
/////////////////////////////////////////////////
SRT>DetectCapState
Timer>LockTimeNow
Let>LockTimeDiff=%LockTimeNow%-%LockTimeFlag%
If>{%LockTimeDiff%>50}
LibFunc>User32,GetKeyState,CAP_STATE,20
If>{(%Cap_state%=65409)or(%Cap_state%=1)}
SetDialogObjectFont>Dialog1,Panel1,Arial,16,1,111111
Else
SetDialogObjectFont>Dialog1,Panel1,Arial,16,0,15790230
EndIf
EndIf
Let>LockTimeFlag=LockTimeNow
END>DetectCapState
SRT>DetectNumState
Timer>LockTimeNow
Let>LockTimeDiff=%LockTimeNow%-%LockTimeFlag%
If>{%LockTimeDiff%>50}
LibFunc>User32,GetKeyState,NUM_STATE,VK_NUMLOCK
If>{(%Num_state%=65409)or(%Num_state%=1)}
SetDialogObjectFont>Dialog1,Panel2,Arial,16,1,111111
Else
SetDialogObjectFont>Dialog1,Panel2,Arial,16,0,15790230
EndIf
EndIf
Let>LockTimeFlag=LockTimeNow
END>DetectNumState
SRT>DetectScrState
Timer>LockTimeNow
Let>LockTimeDiff=%LockTimeNow%-%LockTimeFlag%
If>{%LockTimeDiff%>50}
LibFunc>User32,GetKeyState,SCR_STATE,VK_SCROLL
If>{(%Scr_state%=65409)or(%Scr_state%=1)}
SetDialogObjectFont>Dialog1,Panel3,Arial,16,1,111111
Else
SetDialogObjectFont>Dialog1,Panel3,Arial,16,0,15790230
EndIf
EndIf
Let>LockTimeFlag=LockTimeNow
END>DetectScrState