|
From: Perl R. <pe...@co...> - 2008-12-08 04:46:58
|
Well, I figured it out. Hopefully this will help someone else.
It turns out that editing the registry is not necessary. I simply had to
send the WM_COMMAND message (which means a command was selected from a menu)
and a specific message number (which, for locking/unlocking the taskbar,
happens to be 424). Here's the code in its entirety-just 3 lines. I decided
to use SendMessageTimeout() in case the taskbar doesn't respond:
use Win32::GUI qw(WM_COMMAND);
my $taskbar = Win32::GUI::FindWindow("Shell_TrayWnd", "");
Win32::GUI::SendMessageTimeout($taskbar, WM_COMMAND, 424, 0, 0, 1000);
By the way, I found a list of message numbers in the 3rd post here (although
I'm still not sure where these message numbers are actually defined):
http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/eb0b17d6-
66de-4ce6-bb3a-0c174a17991e
-Rob
_____
From: Perl Rob [mailto:pe...@co...]
Sent: Sunday, December 07, 2008 8:18 PM
To: 'per...@li...'
Subject: Refresh the taskbar
Hi all,
I've been banging my head against this one for the last several hours, so
I'll buy a beer for the man or woman who helps me figure it out! :-)
Quite simply, all I'm trying to do is programmatically toggle the "Lock the
Taskbar" setting. However, I can't get the taskbar to refresh itself after I
toggle the setting (I have to hover my mouse over the taskbar and press F5).
I thought I could do it in two steps:
1. Set the pertinent registry value to 1 (not locked) or 0 (locked).
2. Then send the HWND_BROADCAST message to all windows using the
SendMessageTimeout() function.
Here's the code:
use Win32::TieRegistry( Delimiter=>"/" );
$Registry->{"CUser/Software/Microsoft/Windows/CurrentVersion/Explorer/Advanc
ed//TaskbarSizeMove"} = [ pack("L",1), "REG_DWORD" ];
use Win32::API;
use constant HWND_BROADCAST => 65535;
use constant WM_SETTINGCHANGE => 26;
my $SendMessageTimeout = new Win32::API('user32', 'SendMessageTimeout',
'NNNNNNN', 'N');
$SendMessageTimeout->Call(HWND_BROADCAST, WM_SETTINGCHANGE, 0, "Windows",
SMTO_BLOCK, 1000, undef);
This code almost works. The setting is toggled in the registry and the
desktop refreshes itself...but the taskbar stays the same unless I manually
refresh it.
Since broadcasting the message didn't work, I decided to get the taskbar
handle and send the message only to it:
use Win32::GUI();
my $taskbar = Win32::GUI::FindWindow("Shell_TrayWnd", "");
Win32::GUI::SendMessage($taskbar, WM_SETTINGCHANGE, undef,
"HKEY_CURRENT_USER");
This doesn't work either, so I decided to call invalidateRect() on the
taskbar:
Win32::GUI::InvalidateRect($taskbar, 0, 0, Win32::GUI::Width($taskbar),
Win32::GUI::Height($taskbar), 1);
Still nothing, so I tried calling Hide() and Show() on the taskbar
Win32::GUI::Hide($taskbar);
sleep(1); # To make sure it's hiding
Win32::GUI::Show($taskbar);
It hides and shows, but the setting still isn't taking effect! I get the
feeling I'm going about this all wrong, but I'm running out of ideas (and
I've searched all over MSDN).
Any ideas?
Thanks,
Rob
|