It is currently October 3rd, 2024, 10:52 pm

Trying to make a skin to open specific windows of a program

Get help with creating, editing & fixing problems with skins
User avatar
Yincognito
Rainmeter Sage
Posts: 8324
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Trying to make a skin to open specific windows of a program

Post by Yincognito »

Sunyata wrote: November 11th, 2023, 11:33 pm My next step was basically going to be installing Winamp in order to start from there so I appreciate you testing that out, I'm just trying to make sure the Rainmeter portion of what I'm doing is right and then I can toy around with the window class and message some more. It seems like this *should* be possible so I don't think I'll be able to get it out of my head until I figure it out, it will probably take some time though as I don't really have much of a clue what I'm doing.
It should be possible indeed, but without an actual expert advice on those parameters, it's mostly guesswork. The Rainmeter part is the easiest to figure out, but the details on the needed parameters is what's hindering quick progress on this. Persistence is key... :twisted:
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
Sunyata
Posts: 6
Joined: November 10th, 2023, 8:36 pm

Re: Trying to make a skin to open specific windows of a program

Post by Sunyata »

I've tried playing around with the command with various types of windows, and no matter what message I send or what program I send it to, there's no response of any kind from the window itself. The only thing I have seen is a window become unable to close after I sent it a message. I get the feeling that this isn't really documented because it's an experimental feature that was never really finished due to the receiving application needing to be explicitly designed to receive a message in this capacity, and probably shouldn't be used without an in-depth knowledge of how both the OS and the specific application will actually *handle* the messages that are going to be sent.

This video gives a very basic gist of what the OS does with these messages, and one thing in particular that stands out to me is that you can either send a message, which places it into a queue, or post a message, which sends it instantly. Sending it, as Rainmeter seems to be doing, places it into a queue which I think the application actually has to explicitly define for itself, and then check at some point. So, if the application isn't defining a queue for the specific window that you're trying to send a message to, it may not actually go anywhere once Rainmeter sends it. The developer could have elected to simply post messages directly, which could mean the queue for that application does not exist or is never checked. Another possibility is that they use one central queue for all windows. I really can't say at all as I have literally zero understanding of this beyond scraping a few tutorials I've found.

Moreover, there seem to be two ranges of messages that can be sent, system-defined messages, and user(developer)-defined messages. This little snippet of an explanation on the whole topic of window messages specifies that "Windows reserves all messages from 0 to WM_USER -1 for its own use." So, anything prior to WM_USER (1024 in decimal notation or 0400 in hex) may not even be possible to send via another application, such as Rainmeter. This number in particular stood out to me because it was the message that was sent in the example Winamp skin you were kind enough to try out for me. So, it seems like Winamp, being the only application that is mentioned in the manual page for the WindowMessage Plugin, may actually be written with the possibility of receiving window messages from somewhere other than the system in mind, whereas most applications are not built with the intent of ever interacting with other applications in this way, and so may not be checking a custom-defined queue for messages from somewhere other than the system. If they even are, I think the messages would have to begin at 1024, and would be entirely up to the developer to define.

So, without active input from the developer of a specific application, I think both the problem of queueing and the problem of messages needing to begin at WM_USER (1024) make it more or less impossible to make any headway trying to understand the results of testing this plugin. Even if someone testing it were a developer with knowledge of using window messages, they would probably just be trying various values beginning at 1024 at random hoping to find one that was actively defined to get the specific result they wanted.

When I initially asked here and on the HWinfo forums, my hope was that there would be some generic, universal message that is used to open or close any window, as that's a pretty baseline function of any window, and it would just be a matter of figuring out how to get that message to the window through something like this plugin. The plugin exists, but the generic message does not seem to, or at least it isn't very generic. I'm basically just guessing at all this and could very well be entirely wrong in my assessment. While I think it would be really cool to get this working in some sense, I know so little about it that I feel like I would just be bothering any developer I were asking for information from, and I don't wanna bother people who are already handing out free applications for the benefit of others.
User avatar
Yincognito
Rainmeter Sage
Posts: 8324
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Trying to make a skin to open specific windows of a program

Post by Yincognito »

Sunyata wrote: November 19th, 2023, 3:19 am I've tried playing around with the command with various types of windows, and no matter what message I send or what program I send it to, there's no response of any kind from the window itself. The only thing I have seen is a window become unable to close after I sent it a message. I get the feeling that this isn't really documented because it's an experimental feature that was never really finished due to the receiving application needing to be explicitly designed to receive a message in this capacity, and probably shouldn't be used without an in-depth knowledge of how both the OS and the specific application will actually *handle* the messages that are going to be sent.

This video gives a very basic gist of what the OS does with these messages, and one thing in particular that stands out to me is that you can either send a message, which places it into a queue, or post a message, which sends it instantly. Sending it, as Rainmeter seems to be doing, places it into a queue which I think the application actually has to explicitly define for itself, and then check at some point. So, if the application isn't defining a queue for the specific window that you're trying to send a message to, it may not actually go anywhere once Rainmeter sends it. The developer could have elected to simply post messages directly, which could mean the queue for that application does not exist or is never checked. Another possibility is that they use one central queue for all windows. I really can't say at all as I have literally zero understanding of this beyond scraping a few tutorials I've found.

Moreover, there seem to be two ranges of messages that can be sent, system-defined messages, and user(developer)-defined messages. This little snippet of an explanation on the whole topic of window messages specifies that "Windows reserves all messages from 0 to WM_USER -1 for its own use." So, anything prior to WM_USER (1024 in decimal notation or 0400 in hex) may not even be possible to send via another application, such as Rainmeter. This number in particular stood out to me because it was the message that was sent in the example Winamp skin you were kind enough to try out for me. So, it seems like Winamp, being the only application that is mentioned in the manual page for the WindowMessage Plugin, may actually be written with the possibility of receiving window messages from somewhere other than the system in mind, whereas most applications are not built with the intent of ever interacting with other applications in this way, and so may not be checking a custom-defined queue for messages from somewhere other than the system. If they even are, I think the messages would have to begin at 1024, and would be entirely up to the developer to define.

So, without active input from the developer of a specific application, I think both the problem of queueing and the problem of messages needing to begin at WM_USER (1024) make it more or less impossible to make any headway trying to understand the results of testing this plugin. Even if someone testing it were a developer with knowledge of using window messages, they would probably just be trying various values beginning at 1024 at random hoping to find one that was actively defined to get the specific result they wanted.

When I initially asked here and on the HWinfo forums, my hope was that there would be some generic, universal message that is used to open or close any window, as that's a pretty baseline function of any window, and it would just be a matter of figuring out how to get that message to the window through something like this plugin. The plugin exists, but the generic message does not seem to, or at least it isn't very generic. I'm basically just guessing at all this and could very well be entirely wrong in my assessment. While I think it would be really cool to get this working in some sense, I know so little about it that I feel like I would just be bothering any developer I were asking for information from, and I don't wanna bother people who are already handing out free applications for the benefit of others.
Yep, you did research this topic well, and came to the conclusion I also hinted at, that it's the poor documentation on this which is the main problem. This was the reason I suggested trying with Winamp first, because you could have started with a couple of window messages that (although partially obsolete by now for more recent Winamp versions) actually work and for which there are more docs and posts on their forums about, given the once widely used application. Such attempts would have helped understanding how and what other apps expect in this regard.

Now that I read your reply, I think one doesn't necessarily have to do guesswork to find out what works for some window. A Rainmeter skin is perfectly capable of having a loop where you can iterate through all the numerical values of wparam and lparam and send a window message with those values to the desired window (since we already know the correct window title here, as mentioned above). Obviously, there are some inconveniences with this approach:
- it would take a long time (basically max wparam * max lparam as per combinatorics)
- each such attempt would have to be supervised by the user to find out if it works and what it does (not sure if there's an automatic way of finding out that), further increasing the time needed to complete the entire test (unless lucky enough to find the parameters needed to restore the desired sensors window early on during the test, of course)
- some messages might be tricky and pose possible stability issues or have unexpected/ undesired effects (e.g. closing the window receiving the messages early on and making subsequent attempts to send messages to it futile), so performing the test would probably need both a safe environment like a virtual machine and constant supervision to ensure attempts are valid and have all the necessary prerequisites (like, say, an existing window to send them to, for the example I mentioned)

That being said, asking for clarifications from the developers (of both HWiNFO and Rainmeter) on these details wouldn't be a bad idea, but of course, this assumes they are well versed in this field, and that's kinda hard to guarantee since the technical and unsufficiently documented nature of the topic is the same for them too... :confused:
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
SilverAzide
Rainmeter Sage
Posts: 2742
Joined: March 23rd, 2015, 5:26 pm

Re: Trying to make a skin to open specific windows of a program

Post by SilverAzide »

Sunyata wrote: November 19th, 2023, 3:19 am When I initially asked here and on the HWinfo forums, my hope was that there would be some generic, universal message that is used to open or close any window, as that's a pretty baseline function of any window, and it would just be a matter of figuring out how to get that message to the window through something like this plugin. The plugin exists, but the generic message does not seem to, or at least it isn't very generic. I'm basically just guessing at all this and could very well be entirely wrong in my assessment. While I think it would be really cool to get this working in some sense, I know so little about it that I feel like I would just be bothering any developer I were asking for information from, and I don't wanna bother people who are already handing out free applications for the benefit of others.
I think you might be thinking of this at too high of a "level". For example, looking for a solution using high-level JavaScript versus a lower-level solution using C or even machine code.

What I mean by this is that your hope, "some generic, universal message that is used to open or close any window", does in fact exist. For example, the Windows message is WM_CLOSE. The problem is that you need the context (a.k.a., the window handle) of the target window to send this message to. Remember, each "window" in Windows (of which there are hundreds if not thousands at any one instant) is listening for a message that is addressed to them only. Like shouting in a crowd, you need to specifically know the name of the person you trying to reach -- everyone else is going to ignore you.

You also need to know that every single bit of the entire Windows UI and every Windows program is made of these windows. A button made of a window, which is sitting on some form/screen which is a window, which is sitting inside a frame (or "chrome") which is a window that contains all the standard Windows window controls (max, min, close, etc.) all of which are little windows. Not all are programmed to respond to a WM_CLOSE, for example; if you sent that message to a button, it would ignore you.

As far as opening a window using a message, that actually makes no sense in an event-driven environment. Windows apps react to messages, and a message cannot be reacted to if the receiver is not actually there to receive it. Using the crowd analogy, shouting "Hey, Bob, open your window!" isn't going to work if Bob is not there to hear it. That's why you won't find a Windows message like "WM_OPEN", it makes no sense.

The problem you are facing can be solved. It is not up to Martin (the HWiNFO developer), the Rainmeter devs, or anyone else to create specialized messaging interfaces just for you. If you want to "drive" HWiNFO, that's your problem. The question of whether there is a return on the investment of your time and effort to do this is what you need to answer.

So, to describe the solution you'd need to implement would go something like this. First, HWiNFO would need to be running so you could send messages to it. That is not done via messages, that is you (the human) starting the app manually or telling Windows to run it at startup. Once it is running and minimized in the notification tray:
  • You'd need to find the window handle belonging to the class of window as named by HWiNFO for the Sensors window. This is most easily done using a Microsoft utility supplied with Visual Studio, called Spy++ (spyxx.exe). It would show you something like this:
    Screenshot 2023-11-19 120420.png
  • Once you have identified the window class name and obtained the handle, you can then send messages to it (like WM_SHOWWINDOW as Martin suggested) to make it react. The Spy++ tool is critical for figuring out how to do this. You can make the window do anything that you could do with a mouse, by sending mouse messages to the various controls (windows) inside the parent window.
It should not take you more than 5 minutes to realize this is exquisitely tedious and a massive effort unless you are very experienced in OS-level event handling and know how messaging works. As I replied to your original post, you can configure HWiNFO to open the Sensors window on startup, then you can "drive" it with Windows messages to minimize/restore the window as needed, same as if you clicked the window controls with a mouse.
You do not have the required permissions to view the files attached to this post.
Gadgets Wiki GitHub More Gadgets...
User avatar
Yincognito
Rainmeter Sage
Posts: 8324
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Trying to make a skin to open specific windows of a program

Post by Yincognito »

Sunyata wrote: November 19th, 2023, 3:19 am I've tried playing around with the command with various types of windows, and no matter what message I send or what program I send it to, there's no response of any kind from the window itself.
SilverAzide wrote: November 19th, 2023, 5:25 pmOnce you have identified the window class name and obtained the handle, you can then send messages to it (like WM_SHOWWINDOW as Martin suggested) to make it react.
[...]
It should not take you more than 5 minutes to realize this is exquisitely tedious and a massive effort unless you are very experienced in OS-level event handling and know how messaging works.
While SilverAzide was writing his message I thought of giving this another try, and it turns out it's easier than we all thought - but a bit of reading the references makes finding the solution possible (and, of course, persistence was key too, as hinted earlier):

Code: Select all

; References:
; - https://docs.rainmeter.net/manual/plugins/windowmessage/
; - https://www.hwinfo.com/forum/threads/trying-to-open-main-sensor-windows-through-rainmeter.9301/post-42591
; - https://forum.rainmeter.net/viewtopic.php?t=43169#p219457
; - https://www.autohotkey.com/docs/v1/misc/SendMessageList.htm
; - https://stackoverflow.com/a/3632316/8418085
; - https://learn.microsoft.com/en-us/windows/win32/menurc/wm-syscommand
; - https://stackoverflow.com/a/61014602/8418085
; - https://learn.microsoft.com/en-us/windows/win32/winmsg/wm-showwindow

[Rainmeter]
Update=1000
AccurateText=1
DynamicWindowSize=1
BackgroundMode=2
SolidColor=47,47,47,255

---Measures---

[HWiNFO]
Measure=Plugin
Plugin=WindowMessagePlugin
WindowName=HWiNFO64 v7.50-5150 - Sensors Status

---Styles---

[STexts]
Y=0R
FontColor=255,255,255,255
FontFace=Consolas
FontSize=16
Padding=5,5,5,5
AntiAlias=1

---Meters---

[Info]
Meter=String
MeterStyle=STexts
Y=0r
Text=HWiNFO Sensors - Window Message Params#CRLF#message WM_SYSCOMMAND (0x0112 =   274)

[Minimize]
Meter=String
MeterStyle=STexts
Text=wParam  SC_MINIMIZE   (0xF020 = 61472)
LeftMouseUpAction=[!CommandMeasure HWiNFO "SendMessage 274 61472 0"]

[Restore]
Meter=String
MeterStyle=STexts
Text=wParam  SC_RESTORE    (0xF120 = 61728)
LeftMouseUpAction=[!CommandMeasure HWiNFO "SendMessage 274 61728 0"]

[Maximize]
Meter=String
MeterStyle=STexts
Text=wParam  SC_MAXIMIZE   (0xF030 = 61488)
LeftMouseUpAction=[!CommandMeasure HWiNFO "SendMessage 274 61488 0"]

[Close]
Meter=String
MeterStyle=STexts
Text=wParam  SC_CLOSE      (0xF060 = 61536)
LeftMouseUpAction=[!CommandMeasure HWiNFO "SendMessage 274 61536 0"]
No other tools were used, although SilverAzide is correct that they can help in such a situation (which is why I also recommended similar window spy tools earlier). Martin's reply regarding WM_SHOWWINDOW, although apparently incorrect as per both my attempts and one of the references above, supplemented by his statement about the app not using WM_USER commands, were key to direct me to the above implementation. So, Eureka, finally this largely unused Rainmeter plugin finds its role! ;-)

P.S. Yes, I know that maximizing doesn't work. I suspect that might be because of the particular shape of the sensor window and not necessarily because the command was invalid itself in the context.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
SilverAzide
Rainmeter Sage
Posts: 2742
Joined: March 23rd, 2015, 5:26 pm

Re: Trying to make a skin to open specific windows of a program

Post by SilverAzide »

Noice! :thumbup: You're more persistent than I am! :)
Gadgets Wiki GitHub More Gadgets...
User avatar
Yincognito
Rainmeter Sage
Posts: 8324
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Trying to make a skin to open specific windows of a program

Post by Yincognito »

SilverAzide wrote: November 19th, 2023, 10:52 pm Noice! :thumbup: You're more persistent than I am! :)
Thanks - the topic being interesting and potentially useful in other cases added to my challenge factor motivation here... :lol:

A bit tricky to find the right way to use the plugin and the window message ability when you have examples related to only one application in the docs, which is why I mentioned the developers and the documentation of the programs involved earlier. This was a revealing case, since in the end, it was an entirely different message and parameters that did the job, instead of the "logical" choice.

I might write a simple WindowMessagePlugin helper skin to facilitate a resolution when dealing with similar issues in the future - I'll post it here if it turns out the way I want it to work... ;-)
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth