SetWindowLong mistery

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

SetWindowLong mistery

Udo Schneider
All,

a few questions regarding SetWindowLong(A).

As far as I can see this function is defined twice:
UserLibrary>>setWindowDWORD:nIndex:dwNewDWORD: (Package Dolphin)
UserLibrary>>setWindowDWORD:nIndex:dwNewDWORD: (Package Dolphin MVP Base)

In addition the comment for the second call is wrong - seems to be
copied from GetWindowsLong(A).

Is there a reason why this is defined twice? On which one should one rely?


CU,

Udo


Reply | Threaded
Open this post in threaded view
|

Re: SetWindowLong mistery

Chris Uppal-3
Udo Schneider wrote:

> In addition the comment for the second call is wrong - seems to be
> copied from GetWindowsLong(A).

Also the two definitions disagree about whether the last parameter is signed.

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: SetWindowLong mistery

Blair McGlashan-4
In reply to this post by Udo Schneider
"Udo Schneider" <[hidden email]> wrote in message
news:[hidden email]...
> All,
>
> a few questions regarding SetWindowLong(A).
>
> As far as I can see this function is defined twice:
> UserLibrary>>setWindowDWORD:nIndex:dwNewDWORD: (Package Dolphin)
> UserLibrary>>setWindowDWORD:nIndex:dwNewDWORD: (Package Dolphin MVP Base)
>

That wouldn't be possible with the current packaging system; since they have
the same class and selector name, one or other (whichever is loaded last)
will win out. I think what you really mean is that there are two methods
defined that both call the underlying SetWindowsLong API, namely:

1) #setWindowDWORD:nIndex:dwNewDWORD:
2) #setWindowLong:nIndex:dwNewLong:

> In addition the comment for the second call is wrong - seems to be copied
> from GetWindowsLong(A).

The comment for setWindowDWORD:etc is wrong, yes, thanks. I'll get that
removed.

> Is there a reason why this is defined twice? ...

Yes, if you look carefully you will see that the last parameter is defined
to be either signed or unsigned.

>...On which one should one rely?

First think carefully about whether you need to rely on either. There aren't
many reasons you need to work with this Windows API, and most of those are
already wrapped up by higher level mechanisms in the Dolphin framework.
Follow the reference chain from each to see if what you want to do is
already available in a simpler, less error prone, form.

If you really need to, then use the one that reflects the signed/unsigned
nature of the "long" you are trying to set. You'll have to refer to the
Win32 Platform SDK docs to work that out.

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: SetWindowLong mistery

Blair McGlashan-4
In reply to this post by Chris Uppal-3
"Chris Uppal" <[hidden email]> wrote in message
news:4423d728$0$1168$[hidden email]...
> Udo Schneider wrote:
>
>> In addition the comment for the second call is wrong - seems to be
>> copied from GetWindowsLong(A).
>
> Also the two definitions disagree about whether the last parameter is
> signed.
>

Which is the reason for having two different versions with different names*,
although that doesn't necessarily mean that the right version is always
used.

Regards

Blair

*The underlying API, a rather nasty historical relic, is called
"SetWindowsLong" and is defined in the header file as having a signed last
argument, but in fact the "long" might be either signed or unsigned.


Reply | Threaded
Open this post in threaded view
|

Re: SetWindowLong mistery

Udo Schneider
In reply to this post by Blair McGlashan-4
Blair McGlashan wrote:
> That wouldn't be possible with the current packaging system; since they have
> the same class and selector name, one or other (whichever is loaded last)
> will win out. I think what you really mean is that there are two methods
> defined that both call the underlying SetWindowsLong API, namely:
>
> 1) #setWindowDWORD:nIndex:dwNewDWORD:
> 2) #setWindowLong:nIndex:dwNewLong:
You're right ... wrong copy&paste cycle.

> Yes, if you look carefully you will see that the last parameter is defined
> to be either signed or unsigned.
Correct. Chris pointed this out as well ... I'm still not sure why this
is neccessary ... according to MSDN dwNewLong is defined as being of
datatype LONG which AFAIk translates to an unsigned long (or dword in
Dolphin).

> First think carefully about whether you need to rely on either. There aren't
> many reasons you need to work with this Windows API, and most of those are
> already wrapped up by higher level mechanisms in the Dolphin framework.
> Follow the reference chain from each to see if what you want to do is
> already available in a simpler, less error prone, form.
I more or less need to replicate the View>>subclassWindow(:) functions
on my own. The current implementation does no error checking for
SetWindowsLong if you try to change the wndProc. As I might get hwnds
from external applications I have to do the error checking as
SetWindowLong might return zero in this case.

> If you really need to, then use the one that reflects the signed/unsigned
> nature of the "long" you are trying to set. You'll have to refer to the
> Win32 Platform SDK docs to work that out.
See above. As far as I understood only unsigned longs are used.


CU,

Udo


>
> Regards
>
> Blair
>
>


Reply | Threaded
Open this post in threaded view
|

Re: SetWindowLong mistery

Chris Uppal-3
In reply to this post by Blair McGlashan-4
Blair,

> but in fact the "long" might be either signed or unsigned.

Ugh!

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: SetWindowLong mistery

Blair McGlashan-4
In reply to this post by Udo Schneider
"Udo Schneider" <[hidden email]> wrote in message
news:[hidden email]...

> Blair McGlashan wrote:
>> That wouldn't be possible with the current packaging system; since they
>> have the same class and selector name, one or other (whichever is loaded
>> last) will win out. I think what you really mean is that there are two
>> methods defined that both call the underlying SetWindowsLong API, namely:
>>
>> 1) #setWindowDWORD:nIndex:dwNewDWORD:
>> 2) #setWindowLong:nIndex:dwNewLong:
> You're right ... wrong copy&paste cycle.
>
>> Yes, if you look carefully you will see that the last parameter is
>> defined to be either signed or unsigned.
> Correct. Chris pointed this out as well ... I'm still not sure why this is
> neccessary ... according to MSDN dwNewLong is defined as being of datatype
> LONG which AFAIk translates to an unsigned long (or dword in Dolphin).

LONG is defined as a signed 32-bit integer in winnt.h, i.e.

    typedef long LONG;

In Dolphin signed and unsigned parameter types are handled slightly
differently in terms of error checking - see the class comment of
ExternalDescriptor for precise details. In the language/library of course,
Smalltalk does not recognise the concept of "unsigned" integers.

Perhaps more importantly is the handling of the return value - the old value
is returned. Its important this is treated as the correct type when
converting to a Smalltalk integer, and so where there is ambiguity we
generally define two functions to avoid correcting having to correct the
value at the call sites, which is error prone.

>
>> First think carefully about whether you need to rely on either. There
>> aren't many reasons you need to work with this Windows API, and most of
>> those are already wrapped up by higher level mechanisms in the Dolphin
>> framework. Follow the reference chain from each to see if what you want
>> to do is already available in a simpler, less error prone, form.
> I more or less need to replicate the View>>subclassWindow(:) functions on
> my own. The current implementation does no error checking for
> SetWindowsLong if you try to change the wndProc. As I might get hwnds from
> external applications I have to do the error checking as SetWindowLong
> might return zero in this case.

Usually in the past (e.g. in the late web applet plugin code) we have
managed that kind of thing by defining a specialised View subclass that
avoids attempting to subclass the windows of other threads/processes.

>
>> If you really need to, then use the one that reflects the signed/unsigned
>> nature of the "long" you are trying to set. You'll have to refer to the
>> Win32 Platform SDK docs to work that out.
> See above. As far as I understood only unsigned longs are used.
>

The ID associated with a window by GWL_ID is usually (though not entirely
consistently) considered to be a signed int.  Any user data could be either.
I agree, however, that the so called "Long" is usually an unsigned value,
and it would have been better if MS had defined the API as an opaque 32-bit
value (i.e. as a DWORD). I think SetWindowLong may predate Win32, though, so
it predates when the more logical approach taken in most later APIs.

Regards

Blair