hiuwo wrote: ↑June 6th, 2023, 4:42 amHaving said that, the MultiWindowState thing you made and now expanded on, will probably be something very useful another time in my lifetime. So thanks!
Yincognito wrote: ↑June 6th, 2023, 8:06 pmJoking aside, I have good news on the MultiWindowState front - I managed to do what I wanted, and now the executable only needs to be run once at skin load time, unless dynamically changing related variables in Rainmeter (in which case it will run then as well). I'll post the finished skin either tonight or tomorrow, depending on whether balala wants to solve one of his past issues as well.
Here is the final version of the MultiWindowState skin...
AU3 Script:
Code: Select all
#NoTrayIcon
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Change2CUI=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
Opt("WinTitleMatchMode", -2)
#include <SendMessage.au3>
Func SendBang($szBang)
Local Const $hWnd = WinGetHandle("[CLASS:RainmeterMeterWindow]")
If $hWnd Then
Local Const $iSize = StringLen($szBang) + 1
Local Const $pMem = DllStructCreate("wchar[" & $iSize & "]")
Local Const $pCds = DllStructCreate("dword;dword;ptr")
Local Const $WM_COPYDATA = 0x004A
DllStructSetData($pMem, 1, $szBang)
DllStructSetData($pCds, 1, 1)
DllStructSetData($pCds, 2, ($iSize * 2))
DllStructSetData($pCds, 3, DllStructGetPtr($pMem))
_SendMessage($hWnd, $WM_COPYDATA, 0, DllStructGetPtr($pCds))
EndIf
EndFunc
Func GetResult()
Local $Action = $CmdLine[1], $Separator = $CmdLine[2], $Interval = $CmdLine[3]
While 1
Local $Output = ""
For $i = 4 To $CmdLine[0]
Local $hWnd = WinGetHandle("[REGEXPTITLE:(?i)" & $CmdLine[$i] & "]")
Local $Item = $hWnd ? WinGetState($hWnd) : 0
$Output = $Output & ($i > 4 ? $Separator : "") & $Item
Next
SendBang(StringReplace($Action, "$Output", $Output))
Sleep($Interval)
WEnd
EndFunc
GetResult()
INI Config:
Code: Select all
[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
[Metadata]
Name=MultiWindowState
Author=JSMorley & Yincognito
Version=Jun 07, 2023
License=Creative Commons Attribution-Non-Commercial-Share Alike 3.0
Information=Demonstrates the included MultiWindowState.exe AutoIt addon to check the "states" of any number of program windows.
; Notes: The variable TitleRegExp must be part or all of the "Title" string displayed in the title bar of the window you wish to check.
; This does not operate on the "process" name, but the "window" name of the application. This is a case-insensitive regular expression.
; While searching for "Notepad" to find the Notepad.exe window works, it's ambiguous if you also have Notepad++ running, or even a browser
; opened to a site having "notepad" in the site title. Using ".* - Notepad$" in this case is more reliable to find the Notepad.exe window.
; The MultiWindowState.exe addon is simply called with (any number of window titles can be searched for):
; MultiWindowState.exe "Action" "Separator" "Interval" "First title string to search for" "Second title string to search for" ...
; Based on the searched titles, the addon will create an "$Output" list of window state numbers separated by "Separator", which will be sent
; as a "Windows" variable to the current Rainmeter skin once every "Interval" milliseconds, with the help of the bangs specified in "Action".
; The decimal numbers in that list are the addition of the following matching attributes:
; 1 = Window exists
; 2 = Window is visible
; 4 = Window is enabled
; 8 = Window has focus
; 16 = Window is minimized
; 32 = Window is maximized
; The Bitwise AND (&) operator is used to determine if any specific hex attribute is set:
; 0x1 = Window exists
; 0x2 = Window is visible
; 0x4 = Window is enabled
; 0x8 = Window has focus
; 0x10 = Window is minimized
; 0x20 = Window is maximized
; Story: Originally developed by jsmorley as single session and title capable WindowState.exe
; Multi title and background running of an action at time interval added by Yincognito
; Bonus: The addon's AutoIt script (i.e. MultiWindowState.au3) can be edited and recompiled to provide any results based on any parameters.
[Variables]
Windows=
Action=[!SetVariable Windows ""$Output"" ""MultiWindowState""]
Separator=" "
Interval=1000
TitleRegExp1=^.*(?:cmd.exe|Command Prompt).*$
TitleRegExp2=^.* - Notepad$
TitleRegExp3=^Task Manager$
TitleRegExp4=^Performance Monitor$
TitleRegExp5=^.*Calculator.*$
TitleRegExp6=^.*winamp.*$
ActualTitle1=Command Prompt
ActualTitle2=Notepad
ActualTitle3=Task Manager
ActualTitle4=Performance Monitor
ActualTitle5=Calculator
ActualTitle6=Winamp
Exists=0x1
Visible=0x2
Enabled=0x4
Focus=0x8
Minimized=0x10
Maximized=0x20
---Measures RunCommand---
; Kill the addon executable if it's running, wait a moment, then run it to retrieve or update its output
[MeasureUpdate]
Group=Commands
Measure=Calc
UpdateDivider=-1
OnUpdateAction=[!CommandMeasure MeasureCommand "Kill"][!Delay 250][!CommandMeasure MeasureCommand "Run"]
; Run the addon executable using the defined Action, Separator, Interval and Expressions as parameters
[MeasureCommand]
Group=Commands
Measure=Plugin
Plugin=RunCommand
Program="#@#Addons\MultiWindowState.exe"
Parameter=""#Action#" "#Separator#" "#Interval#" "#TitleRegExp1#" "#TitleRegExp2#" "#TitleRegExp3#" "#TitleRegExp4#" "#TitleRegExp5#" "#TitleRegExp6#""
OutputType=ANSI
UpdateDivider=-1
DynamicVariables=1
; Use the variable holding the output list sent by the addon earlier to further split it into individual elements
[MeasureWindows]
Group=Commands
Measure=String
String="[#Windows]"
OnUpdateAction=[!EnableMeasureGroup Windows][!EnableMeasureGroup States][!ShowMeterGroup Output]
DynamicVariables=1
---Measures Windows---
[MeasureWindow1]
Group=Windows
Disabled=1
Measure=String
String=[MeasureWindows]
RegExpSubstitute=1
Substitute="^(?:\s?\d+){0,0}+\s?(\d+).*$":"\1","^(?:\\1|)$":"0"
DynamicVariables=1
[MeasureWindow2]
Group=Windows
Disabled=1
Measure=String
String=[MeasureWindows]
RegExpSubstitute=1
Substitute="^(?:\s?\d+){0,1}+\s?(\d+).*$":"\1","^(?:\\1|)$":"0"
DynamicVariables=1
[MeasureWindow3]
Group=Windows
Disabled=1
Measure=String
String=[MeasureWindows]
RegExpSubstitute=1
Substitute="^(?:\s?\d+){0,2}+\s?(\d+).*$":"\1","^(?:\\1|)$":"0"
DynamicVariables=1
[MeasureWindow4]
Group=Windows
Disabled=1
Measure=String
String=[MeasureWindows]
RegExpSubstitute=1
Substitute="^(?:\s?\d+){0,3}+\s?(\d+).*$":"\1","^(?:\\1|)$":"0"
DynamicVariables=1
[MeasureWindow5]
Group=Windows
Disabled=1
Measure=String
String=[MeasureWindows]
RegExpSubstitute=1
Substitute="^(?:\s?\d+){0,4}+\s?(\d+).*$":"\1","^(?:\\1|)$":"0"
DynamicVariables=1
[MeasureWindow6]
Group=Windows
Disabled=1
Measure=String
String=[MeasureWindows]
RegExpSubstitute=1
Substitute="^(?:\s?\d+){0,5}+\s?(\d+).*$":"\1","^(?:\\1|)$":"0"
DynamicVariables=1
---Measures States---
[MeasureExists1]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow1] & #Exists# = #Exists# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureVisible1]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow1] & #Visible# = #Visible# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureEnabled1]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow1] & #Enabled# = #Enabled# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureFocus1]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow1] & #Focus# = #Focus# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureMinimized1]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow1] & #Minimized# = #Minimized# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureMaximized1]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow1] & #Maximized# = #Maximized# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureExists2]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow2] & #Exists# = #Exists# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureVisible2]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow2] & #Visible# = #Visible# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureEnabled2]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow2] & #Enabled# = #Enabled# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureFocus2]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow2] & #Focus# = #Focus# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureMinimized2]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow2] & #Minimized# = #Minimized# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureMaximized2]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow2] & #Maximized# = #Maximized# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureExists3]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow3] & #Exists# = #Exists# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureVisible3]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow3] & #Visible# = #Visible# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureEnabled3]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow3] & #Enabled# = #Enabled# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureFocus3]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow3] & #Focus# = #Focus# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureMinimized3]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow3] & #Minimized# = #Minimized# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureMaximized3]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow3] & #Maximized# = #Maximized# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureExists4]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow4] & #Exists# = #Exists# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureVisible4]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow4] & #Visible# = #Visible# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureEnabled4]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow4] & #Enabled# = #Enabled# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureFocus4]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow4] & #Focus# = #Focus# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureMinimized4]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow4] & #Minimized# = #Minimized# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureMaximized4]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow4] & #Maximized# = #Maximized# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureExists5]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow5] & #Exists# = #Exists# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureVisible5]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow5] & #Visible# = #Visible# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureEnabled5]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow5] & #Enabled# = #Enabled# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureFocus5]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow5] & #Focus# = #Focus# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureMinimized5]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow5] & #Minimized# = #Minimized# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureMaximized5]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow5] & #Maximized# = #Maximized# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureExists6]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow6] & #Exists# = #Exists# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureVisible6]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow6] & #Visible# = #Visible# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureEnabled6]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow6] & #Enabled# = #Enabled# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureFocus6]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow6] & #Focus# = #Focus# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureMinimized6]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow6] & #Minimized# = #Minimized# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
[MeasureMaximized6]
Group=States
Disabled=1
Measure=Calc
Formula=[MeasureWindow6] & #Maximized# = #Maximized# ? 1 : -1
Substitute="-1":"🗷","1":"🗹"
DynamicVariables=1
---Meters---
[MeterActualTitles]
Group=Output
Hidden=1
Meter=String
W=205
FontSize=16
FontColor=255,255,255,255
SolidColor=0,0,0,128
FontEffectColor=0,0,0,255
StringEffect=Shadow
Padding=5,5,5,5
AntiAlias=1
Text=Windows States#CRLF##ActualTitle1##CRLF##ActualTitle2##CRLF##ActualTitle3##CRLF##ActualTitle4##CRLF##ActualTitle5##CRLF##ActualTitle6#
InlinePattern=(?siU)^.*\R(.*)$
InlineSetting=GradientColor | 180 | 252,94,37 ; 0.0 | 252,117,41 ; 0.25 | 251,163,48 ; 0.5 | 249,215,56 ; 0.75 | 249,242,61 ; 1.0
DynamicVariables=1
[MeterWindowsStates]
Group=Output
Hidden=1
Meter=String
X=5R
FontSize=14
FontColor=255,255,255,255
SolidColor=0,0,0,128
FontEffectColor=0,0,0,255
StringEffect=Shadow
Padding=5,5,5,5
AntiAlias=1
MeasureName =MeasureExists1
MeasureName2 =MeasureVisible1
MeasureName3 =MeasureEnabled1
MeasureName4 =MeasureFocus1
MeasureName5 =MeasureMinimized1
MeasureName6 =MeasureMaximized1
MeasureName7 =MeasureExists2
MeasureName8 =MeasureVisible2
MeasureName9 =MeasureEnabled2
MeasureName10=MeasureFocus2
MeasureName11=MeasureMinimized2
MeasureName12=MeasureMaximized2
MeasureName13=MeasureExists3
MeasureName14=MeasureVisible3
MeasureName15=MeasureEnabled3
MeasureName16=MeasureFocus3
MeasureName17=MeasureMinimized3
MeasureName18=MeasureMaximized3
MeasureName19=MeasureExists4
MeasureName20=MeasureVisible4
MeasureName21=MeasureEnabled4
MeasureName22=MeasureFocus4
MeasureName23=MeasureMinimized4
MeasureName24=MeasureMaximized4
MeasureName25=MeasureExists5
MeasureName26=MeasureVisible5
MeasureName27=MeasureEnabled5
MeasureName28=MeasureFocus5
MeasureName29=MeasureMinimized5
MeasureName30=MeasureMaximized5
MeasureName31=MeasureExists6
MeasureName32=MeasureVisible6
MeasureName33=MeasureEnabled6
MeasureName34=MeasureFocus6
MeasureName35=MeasureMinimized6
MeasureName36=MeasureMaximized6
Text=R V E F S L#CRLF#%1 %2 %3 %4 %5 %6#CRLF#%7 %8 %9 %10 %11 %12#CRLF#%13 %14 %15 %16 %17 %18#CRLF#%19 %20 %21 %22 %23 %24#CRLF#%25 %26 %27 %28 %29 %30#CRLF#%31 %32 %33 %34 %35 %36
InlinePattern=🗷
InlineSetting=Color | 176,176,176,255
InlinePattern2=🗹
InlineSetting2=Color | 182,252,196,255
DynamicVariables=1
[MeterInformation]
Group=Output
Hidden=1
Meter=String
X=(([MeterActualTitles:W]+[MeterWindowsStates:W])/2)
Y=5R
W=([MeterActualTitles:W]+[MeterWindowsStates:W])
FontSize=9
FontColor=255,255,255,255
SolidColor=0,0,0,128
FontEffectColor=0,0,0,255
StringEffect=Shadow
Padding=5,5,5,5
StringAlign=Center
AntiAlias=1
Text=R: Running V: Visible E: Enabled F: Focus S: Small L: Large
DynamicVariables=1
; Optional: example of dynamically changing one of the addon parameters in order to run it again with the updated values
LeftMouseUpAction=[!SetVariable ActualTitle3 "Registry Editor"][!SetVariable TitleRegExp3 "^Registry Editor$"][!UpdateMeasureGroup Commands][!UpdateMeter *][!Redraw]
Package:
MultiWindowState_2.0.0.rmskin
Preview:
MultiWindowState.jpg
Features:
- only one execution at skin load required if the parameters don't change
- additional executions required only when some of its parameters change
- ability to not only send data as parameters to the script, but also receive back data in any skin at defined time intervals via bangs
- any part of the process is configurable via the passed parameters: the sent data, the action bangs, the time interval or the list separator
- unlimited data being able to be sent or received, since there can be any number of parameters and any length for the output string list
- zero impact on system resources, as the executable runs as a background process, regularly sending data to any Rainmeter skin via bangs
- only one executable instance runs at any moment, since the previous instance is killed before running another with different parameters
- the script can be adapted to provide any return data using any bangs in any scenario, not just this one, by editing the GetResult() function
Other:
I included some comments in key places in the code, in addition to the originals from jsmorley, for better understanding of what happens. A simple example of modifying one of the parameters to run the executable with the updated ones and get different data is also included at the end of the code.
You do not have the required permissions to view the files attached to this post.