What happened to the Messenger Plus! forums on msghelp.net?
Shoutbox » MsgHelp Archive » Messenger Plus! for Live Messenger » Scripting » [?] Toggle display of PlusWnd taskbar button...

[?] Toggle display of PlusWnd taskbar button...
Author: Message:
whiz
Senior Member
****


Posts: 568
Reputation: 8
– / – / Flag
Joined: Nov 2008
O.P. [?] Toggle display of PlusWnd taskbar button...
Javascript code:
TopToggle = function(PlusWnd)
{
    Interop.Call("user32", "SetWindowPos", PlusWnd.Handle, PlusWnd.Button_IsChecked("ChkTop") ? -1 : -2, 0, 0, 0, 0, 3);
    Interop.Call("user32", "ShowWindow", PlusWnd.Handle, 0); // hide window
    var Get = Interop.Call("user32", "GetWindowLong", PlusWnd.Handle, -20); // -20 for extended window styles    Get += (PlusWnd.Button_IsChecked("ChkTop") ? 262016 : -262016); // toggle APPWINDOW / TOOLWINDOW
    Interop.Call("user32", "SetWindowLong", PlusWnd.Handle, -20, Get); // set new flag
    Interop.Call("user32", "ShowWindow", PlusWnd.Handle, 1); // show window
}


Error: unknown (code: -2147467259) at highlighted line.  MSDN says the GetWindowLong function returns a LONG type result - is this the problem?
06-05-2011 04:35 PM
Profile E-Mail PM Find Quote Report
Eljay
Elite Member
*****

Avatar
:O

Posts: 2949
Reputation: 77
– / Male / –
Joined: May 2004
RE: [?] Toggle display of PlusWnd taskbar button...
*cough* GetWindowLongW *cough* :P
06-05-2011 04:44 PM
Profile PM Find Quote Report
whiz
Senior Member
****


Posts: 568
Reputation: 8
– / – / Flag
Joined: Nov 2008
O.P. RE: [?] Toggle display of PlusWnd taskbar button...
Gah, thought I was missing something simple...  :P

What is the difference between them, anyway?  Do they handle parameters differently or something?
06-07-2011 07:56 AM
Profile E-Mail PM Find Quote Report
CookieRevised
Elite Member
*****

Avatar

Posts: 15519
Reputation: 173
– / Male / Flag
Joined: Jul 2003
Status: Away
RE: [?] Toggle display of PlusWnd taskbar button...
'W' stands for Wide character version, 'A' for ansi version. The difference is in how they handle strings (note that this can be an internal thing though, like with the GetWindowLong API; it doesn't nessecairly mean the API needs string parameters).

To know the exact difference see the UNICODE vs. ANSI subject and how characters are used and coded in both of them.
Way to much to properly explain here, but some important articles to get started:
Unicode
Unicode in the Windows API
Unicode and ANSI Functions in Windows
Unicode in Win32s and Windows 95


Also, if you look up APIs in the MSDN Library, you will always see if there is a Wide character version and an Ansi version available or not (in the Requirements section). If they are available, you should always use the unicode version unless you have a specific reason not to (eg: you're programming for a 16-bit system, or for legacy purposes, etc).
This is one more reason why you should always look APIs up in the MSDN Library when using them, even if they seem trivial and an easy to use.

---------------

Important: SetWindowLong isn't correct either, it should also be SetWindowLongW for the same reasons.

---------------

Even more importantly:
Javascript code:
var Get = Interop.Call("user32", "GetWindowLong", PlusWnd.Handle, -20); // -20 for extended window styles
Get += (PlusWnd.Button_IsChecked("ChkTop") ? 262016 : -262016); // toggle APPWINDOW / TOOLWINDOWInterop.Call("user32", "SetWindowLong", PlusWnd.Handle, -20, Get); // set new flag

You should never ever do the above to toggle a flag setting! It will never work properly.

You should use boolean arithmetics with the bitmask of the flags you whish to set/remove, not normal arithmetics!!! Otherwise, if the style flags already included the specific flag you whish to set, you will calculate the wrong value when you add the value of the bit in question using normal arithmetics. The same for when you whish to remove a flag when you simply substract the bitvalue instead of doing a boolean operation.

Say the initial value of the styles is 15 (binary 1111), and you whish to set the 3rd bit (which is already set, but you don't know that).
If you do A = A + 4 the result will actually be 19 (binary 10011), not 15 (binary 1111).
So, instead you should do A = A OR 4
(4 in binary is 0100)
...which will result in 15 (binary 1111) if the initial value was already 15 (binary 1111).
...which will result in 6 (binary 0110) if the initial value was 2 (binary 0010).

Vice versa, if you whish to remove the 3rd bit and your inital value has already the 3rd bit removed, for example value 10 (binary 1010):
If you do A = A - 4 the result will actually be 6 (binary 0110), not the expected 10 (binary 1010).
Instead you should do A = A AND 11
(11 is the mask where all bits are set except the ones you want to remove, in binary it is 1011, thus the inverse of 4, see above)
...which will result in 10 (binary 1010), if the initial value was already 10 (binary 1010).
...which will result in 9 (binary 1001), if the initial value was 13 (binary 1101).


Thus if you want to set a specific flag:
  Result = Original OR flagvalue

If you want to remove a specific flag:
  Result = Original AND (NOT flagvalue)


So, instead you should use an AND or OR operation. eg:
  To set a flag (in this case WS_EX_APPWINDOW) use 'OR' with the flag's value:
  Get = Get | 0x40000

To remove a flag (in this case WS_EX_APPWINDOW) use 'AND' with a bitmask of the bits you whish to keep (otherwise known as the inverse of the flag value):
  Get = Get & ~0x40000
    or
  Get = Get & 0xFFFBFFFF


;)


EDIT: typo fixed (! should be ~)

This post was edited on 06-07-2011 at 02:55 PM by CookieRevised.
.-= A 'frrrrrrrituurrr' for Wacky =-.
06-07-2011 10:24 AM
Profile PM Find Quote Report
Matti
Elite Member
*****

Avatar
Script Developer and Helper

Posts: 1646
Reputation: 39
31 / Male / Flag
Joined: Apr 2004
RE: [?] Toggle display of PlusWnd taskbar button...
One correction for Cookie: to do a bitwise NOT operation, you need to use "~" as opposed to "!", as in:
Javascript code:
Get = Get & ~0x40000;

The boolean not will not give the wanted results:
  • !0x40000: A non-zero number converts to boolean true. The "!" takes this boolean equivalent and returns the opposite.
    Result: false (boolean).
  • Get & false: The bitwise AND takes two integers, so the boolean false is converted to the number zero. Therefore the expression becomes equivalent to Get & 0 which will always evaluate to zero.
    Final result: 0 (number).
The only case where this could produce a non-zero number is when the flag to be subtracted would be zero. Then, the boolean NOT operator would evaluate to true and the expression becomes Get & 1. This gives 1 when the smallest bit is set or 0 if it's not.

I'm sure it was just a typo on Cookie's side but I thought it'd be better to properly explain what's wrong with it. Bitwise arithmetic is frequently used in the Windows API and more developers should be aware of it. :)
Plus! Script Developer | Plus! Beta Tester | Creator of Countdown Live | Co-developer of Screenshot Sender 5

Found my post useful? Rate me!
06-07-2011 01:21 PM
Profile E-Mail PM Web Find Quote Report
CookieRevised
Elite Member
*****

Avatar

Posts: 15519
Reputation: 173
– / Male / Flag
Joined: Jul 2003
Status: Away
RE: [?] Toggle display of PlusWnd taskbar button...
yeah, it was a typo...

|| && | & ! ~ whatever, it confused the crap out of me also when I was writing the post and because I was in a hurry too. Its confusing when so many languages have all different syntax for the same thing and when you don't have the time to think properly (annoying loud music in the background) :p I also first wrote && and || too, which wasn't correct either for the very same reasons, but I forgot to change ! to ~...  oopsy :$...

...but as long as the main point gets across I guess (big no-no to normal arithmetics for stuff like setting flags) :D

But yeah, correct is correct.... Thanks for that.

This post was edited on 06-07-2011 at 02:54 PM by CookieRevised.
.-= A 'frrrrrrrituurrr' for Wacky =-.
06-07-2011 02:50 PM
Profile PM Find Quote Report
whiz
Senior Member
****


Posts: 568
Reputation: 8
– / – / Flag
Joined: Nov 2008
O.P. RE: [?] Toggle display of PlusWnd taskbar button...
Yeah, I got it now.  :)

Javascript code:
// ...
TopToggle: function(PlusWnd)
{
    Interop.Call("user32", "SetWindowPos", PlusWnd.Handle, PlusWnd.Button_IsChecked("ChkTop") ? -1 : -2, 0, 0, 0, 0, 3);
    Interop.Call("user32", "ShowWindow", PlusWnd.Handle, 0);
    var Get = Interop.Call("user32", "GetWindowLongW", PlusWnd.Handle, -20)
    if (PlusWnd.Button_IsChecked("ChkTop"))
    {
        Get = Get & ~0x40000; // remove WS_EX_APPWINDOW
        Get = Get | 0x80; // add WS_EX_TOOLWINDOW
    }
    else
    {
        Get = Get | 0x40000; // add WS_EX_APPWINDOW
        Get = Get & ~0x80; // remove WS_EX_TOOLWINDOW
    }
    Interop.Call("user32", "SetWindowLongW", PlusWnd.Handle, -20, Get);
    Interop.Call("user32", "ShowWindow", PlusWnd.Handle, 1);
},
// ...

It's going to be part of my DevPlus tool, so it hides the taskbar button when topmost.  :P
06-08-2011 07:44 PM
Profile E-Mail PM Find Quote Report
« Next Oldest Return to Top Next Newest »


Threaded Mode | Linear Mode
View a Printable Version
Send this Thread to a Friend
Subscribe | Add to Favorites
Rate This Thread:

Forum Jump:

Forum Rules:
You cannot post new threads
You cannot post replies
You cannot post attachments
You can edit your posts
HTML is Off
myCode is On
Smilies are On
[img] Code is On