Sign in to follow this  
Followers 0
fisofo

receive broadcast of monitor change?

8 posts in this topic

#1 ·  Posted (edited)

For those just arriving, the new question is further down this topic... here.

I could poll wmi for this change using a function I posted before, or even using builtin desktopwidth/desktopheight but I don't really like running a checker script over and over again, I want it to be smarter. Is there some sort of broadcast message that gets sent when resolution/position/number of monitors is changed? And if so, is there a good way to catch (via polling :) )

Searched a deal and haven't found much yet... thank you!

Edited by fisofo

Share this post


Link to post
Share on other sites



Try this :

#include <GUIConstants.au3>

Global Const $WM_DISPLAYCHANGE = 0x007E

GUICreate("")
GUIRegisterMsg($WM_DISPLAYCHANGE, "MY_WM_DISPLAYCHANGE")

While 1
    GUIGetMsg()
WEnd

Func MY_WM_DISPLAYCHANGE($hWnd, $nMsgID, $wParam, $lParam)
    TrayTip("Monitor", 'Resolution changed to "' & @DesktopWidth & 'x' & @DesktopHeight & '".', 2000, 1)
    Return $GUI_RUNDEFMSG
EndFunc

Share this post


Link to post
Share on other sites

Try this :

#include <GUIConstants.au3>

Global Const $WM_DISPLAYCHANGE = 0x007E

GUICreate("")
GUIRegisterMsg($WM_DISPLAYCHANGE, "MY_WM_DISPLAYCHANGE")

While 1
    GUIGetMsg()
WEnd

Func MY_WM_DISPLAYCHANGE($hWnd, $nMsgID, $wParam, $lParam)
    TrayTip("Monitor", 'Resolution changed to "' & @DesktopWidth & 'x' & @DesktopHeight & '".', 2000, 1)
    Return $GUI_RUNDEFMSG
EndFunc
A thing of beauty... that worked wonderfully, thank you.

Share this post


Link to post
Share on other sites

So that code works great, but I found I also need to detect when the "workspace" changes. What I mean is, the WM_DISPLAYCHANGE does not fire if I resize or autohide the taskbar.

I did some research and found that the message I want to nab is $ABN_STATECHANGE (I think), but it looks like it only gets sent to appbar's(???) which is probably why the below code doesn't work. Any ideas?

#include <GUIConstants.au3>

Global Const $ABN_STATECHANGE = 0x00000000

GUICreate("")
GUIRegisterMsg($ABN_STATECHANGE, "MY_WM_DISPLAYCHANGE")

While 1
    GUIGetMsg()
WEnd

Func MY_WM_DISPLAYCHANGE($hWnd, $nMsgID, $wParam, $lParam)
    msgbox(0, "", "Workspace changed!")
    Return $GUI_RUNDEFMSG
EndFunc

Share this post


Link to post
Share on other sites

Good news! I was able to figure it out from some code that darren posted.

But please if someone could just answer a question for me: This procedure hooks all messages sent to appbar's, I would really prefer to just hook the "ABN_POSCHANGED" message. As you can see in the code, I currently have to check in function MY_ABN_POSCHANGED whether I got that message or not... the function is basically always being called. Is there some other way to do this???

thanks!

#include <GUIConstants.au3>

Global Const $ABM_NEW = 0x00000000
Global Const $ABM_REMOVE = 0x00000001
Global Const $ABN_POSCHANGED = 1

$hwnd=GUICreate("")

$msgid=DllCall("User32.dll","int","RegisterShellHookWindow","hwnd",$hwnd)

GUIRegisterMsg($msgid,"MY_ABN_POSCHANGED")

$AppBarData = DllStructCreate("dword;hwnd;uint;uint;int[4];int")
DllStructSetData($AppBarData,1,DllStructGetSize($AppBarData))
DllStructSetData($AppBarData,2,$hwnd)
DllStructSetData($AppBarData,3,$msgid)
DllCall("shell32.dll","int","SHAppBarMessage","int",$ABM_NEW,"ptr",DllStructGetPtr($AppBarData)) ; register the appbar

While 1
    GUIGetMsg()
WEnd

DllCall("shell32.dll","int","SHAppBarMessage","int",$ABM_REMOVE,"ptr",DllStructGetPtr($AppBarData)) ; unregister the appbar

Func MY_ABN_POSCHANGED($hWnd, $nMsgID, $wParam, $lParam)
    If $wParam = $ABN_POSCHANGED Then
        ToolTip("Workspace changed")
        Return $GUI_RUNDEFMSG
    EndIf
EndFunc

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

One follow-up to the previous post, I also got this code to work which uses a RegisterWindowMessage instead... but it still doesn't seem to matter what I input for the string into RegisterWindowMessage! I still have to have that If statement in the MY_ABN_POSCHANGED if I just want to get POS_CHANGED messages.

Here's the code:

#include <GUIConstants.au3>

Global Const $ABM_NEW = 0x00000000
Global Const $ABM_REMOVE = 0x00000001
Global Const $ABN_POSCHANGED = 1

$msgid=DllCall("User32.dll","int","RegisterWindowMessage","str",$ABN_POSCHANGED) ;string doesn't matter?!?

GUIRegisterMsg($msgid,"MY_ABN_POSCHANGED")

$hwnd=GUICreate("")

$AppBarData = DllStructCreate("dword;hwnd;uint;uint;int[4];int")
DllStructSetData($AppBarData,1,DllStructGetSize($AppBarData))
DllStructSetData($AppBarData,2,$hwnd)
DllStructSetData($AppBarData,3,$msgid)
DllCall("shell32.dll","int","SHAppBarMessage","int",$ABM_NEW,"ptr",DllStructGetPtr($AppBarData)) ; register the appbar

While 1
    GUIGetMsg()
WEnd

DllCall("shell32.dll","int","SHAppBarMessage","int",$ABM_REMOVE,"ptr",DllStructGetPtr($AppBarData)) ; unregister the appbar

Func MY_ABN_POSCHANGED($hWnd, $nMsgID, $wParam, $lParam)
    If $wParam = $ABN_POSCHANGED Then
        ToolTip("Workspace changed")
        Return $GUI_RUNDEFMSG
    EndIf
EndFunc

Edit: again, just to clarify, if you remove the If statement in MY_ABN_POSCHANGED in this code or the code above, the tooltip message constantly appears, I would like to have it such that the MY_ABN_POSCHANGED only gets called when the specific $ABN_POSCHANGED message occurs.

Any Ideas???

Edited by fisofo

Share this post


Link to post
Share on other sites

Happy Friday! The weekend is almost here... *bump*

Also, in regards to RegisterWindowMessage I read this:

lpString

[in]Pointer to a null-terminated string that specifies the message to be registered.

I'm guessing I've hosed something or other, but doesn't this mean I can tell it to only hook a specific message, such as ABN_POSCHANGED? And if so, why the crap doesn't it work?!?

Share this post


Link to post
Share on other sites

WM_SETTINGCHANGE

http://msdn2.microsoft.com/en-us/library/ms725497.aspx

SystemParametersInfo

http://msdn2.microsoft.com/en-us/library/ms724947.aspx

Global Const $WM_SETTINGCHANGE = 0x001A

$gui = GUICreate("test")
$lbl = GUICtrlCreateLabel("",0,0,300,300)
GUISetState()

GUIRegisterMsg($WM_SETTINGCHANGE,"MY_WM_SETTINGCHANGE")

While 1
    If GUIGetMsg() = -3 Then Exit
WEnd

Func MY_WM_SETTINGCHANGE($hWnd, $Msg, $wParam, $lParam)
    GUICtrlSetData($lbl,$hWnd & @LF & $Msg & @LF & $wParam & @LF & $lParam)
EndFunc

Run script... change taskbar size

So simple... man, I don't know why didn't find that before; I think I spent a good 3 hours in the last couple days trying to figure that out :)

Thanks Larry. As usual, you da man.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0