Announcement

Collapse
No announcement yet.

Message argument data types

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Message argument data types

    I was looking in MSDN to see what it says for the data types of the four arguments of a message. Expecting to see DWord, Long, Long, Long, instead I saw

    Code:
    LRESULT CALLBACK WindowProc(      
        HWND hwnd,
        UINT uMsg,
        WPARAM wParam,
        LPARAM lParam
    );
    So then I went to the MSDN page that lists data types:

    http://msdn.microsoft.com/en-us/library/aa383751(VS.85).aspx

    Each of the data types were listed as other data types which were listed as other data types ... the data trail looking like this:

    hwnd --> handle --> pvoid no mention of 32 bit unsigned Int
    uint --> unsign Int w/range of 4G (implies 32 bits)
    wparam --> unit_ptr --> unsigned Int (doesn't say range or bits)
    lparam --> long_ptr --> long signed long (long is not on the list)

    That was pretty unsatisfying in that it never quite said what I expected. I certainly didn't expect lparam to be different.

    I checked with Support and they said:

    ...they use HWND which is a unsigned 32-bit integer, which is the same as a DWord. We recommend a DWord because Windows returns a window handle as a DWord and if this is converted to a Long integer it could result in a negative value. This is probably not a problem because if you ever use this Long Integer negative value with any command that wants a DWord it will be converted to a DWord and become positive again.
    And in the Help topic on CB I found

    Code:
       The implied parameters are:
      FUNCTION DlgCallback(BYVAL hDlg AS DWORD  _
           BYVAL  wMsg AS LONG   _
           BYVAL wParam AS LONG _
           BYVAL lParam AS  LONG)
    Also, in most of the non-MSDN documentation I read, all Long's are typically used!

    Even in the distributed PowerBASIC applications I see a mixture of DWord and Long for handles.

    My plan is to stick with the DWord-Long-Long-Long.

    Are there any words of wisdom on this?
    Last edited by Gary Beene; 16 Mar 2009, 08:30 PM.

  • #2
    My plan is to stick with the DWord-Long-Long-Long.
    Use whatever you wish, but DWORD, DWORD, DWORD, LONG is more correct. The profusion of LONGs comes from adaptation of VB code, that uses it because the VB compiler doesn't support DWORDs.
    Forum: http://www.jose.it-berater.org/smfforum/index.php

    Comment


    • #3
      Jose,

      Thanks for the response.

      Your comment on

      DWord, DWord, DWord, Long

      seems the right match for the

      DWord, Unsigned Int, Unsigned Int, Long

      that's on MSDN.

      I might have expected PowerBASIC (and the whole world) to use it as the preferred typing as well.

      I guess the weight of history, plus the data type conversion that's built into language compilers takes the risk out of the choice.

      Comment


      • #4
        Originally posted by Charles Petzold
        Programming Windows (Fifth Edition, page 49, under New Data Types)

        "Others are less obvious. For example, the third and fourth parameters to WinProc are defined as WPARAM and LPARAM, respectively. The origin of these names requires a bit of history. When Windows was a 16 bit system, the third parameter to WinProc was defined as a WORD, which was a 16 bit unsigned short integer, and the fourth parameter was defined as a LONG, which was a 32 bit signed long integer. That's the reason for the "W" and "L" prefixes on the word "PARAM". In 32 bit versions of Windows, however, WPARAM is defined as a UINT and LPARAM is defined as a LONG (which is still a C long data type), so both parameters to the windows procedure are 32 bit values."
        And there you have it.
        Furcadia, an interesting online MMORPG in which you can create and program your own content.

        Comment


        • #5
          OK my aging brain can't remember where I saw this, or if it is just a figment, but isn't there a performance hit using dword instead of long? Maybe it is in an entirely different context ??

          James

          Comment


          • #6
            DWORD/LONG is only signficant if you do arithmetic or numeric comparisons other than equality.

            You never ever do arithmetic or numeric comparisons other than equality on any handle. Ever.

            You can compare LONG/DWORD for equality with either SELECT CASE *AS LONG* or with the new (9x) BITSE function, or using the BITS??? function available prior to 9x.

            It's the same 32 bits... LONG/DWORD only discriminates as to the handling of bit 31 in arithmetic operations.

            That said, if a function returning a handle is DECLARED to return a a particular datatype, any return value (eg an error code) needs to be consistent with that.

            Let's use an example from the WIN32API.INC file supplied with PB/WIN 9.0.0 ('"Last Update: 27 January 2005")

            Code:
            DECLARE FUNCTION GetFileAttributes LIB "KERNEL32.DLL" _ 
                  ALIAS "GetFileAttributesA" (lpFileName AS ASCIIZ) AS LONG
            This function might return...
            %INVALID_FILE_ATTRIBUTES = &HFFFFFFFF???

            Oops, mismatch. (A LONG will never test equal to &hFFFFFFFF???)

            Don't worry, I reported this about a month ago.

            MCM
            Michael Mattias
            Tal Systems (retired)
            Port Washington WI USA
            [email protected]
            http://www.talsystems.com

            Comment


            • #7
              but isn't there a performance hit using dword instead of long? Maybe it is in an entirely different context ??
              I believe PB phrases it as the compiler's artithmetic is optimized for LONG.

              However, if the value in question is a HANDLE it is moot, since as pointed out above you never ever do arithmetic on a handle. Ever.

              MCM
              Michael Mattias
              Tal Systems (retired)
              Port Washington WI USA
              [email protected]
              http://www.talsystems.com

              Comment


              • #8
                Originally posted by Gary Beene View Post
                Also, in most of the non-MSDN documentation I read, all Long's are typically used!

                Even in the distributed PowerBASIC applications I see a mixture of DWord and Long for handles.

                My plan is to stick with the DWord-Long-Long-Long.

                Are there any words of wisdom on this?
                As pointed out above, those values are just 32-bit values, which internally can be either LONGs or DWORDs, so just think of them being represented internally as either-or.

                The reason you see code like that is because Windows was written [presumably mostly] in C, which has strict type-checking like PB does, except that it takes it perhaps a step further. C also allows you to define your own data types in terms of another, and will then enforce use of your defined data type if it's called for. This is useful to help make code more readable, as it then becomes self-documenting.

                Suppose you come back a number of months after you've written some code and see that some function you don't recognize returns a long value. You'll probably have to glance through its source to jog your memory and find out that it does x and returns a handle to a window, whereas seeing a return type defined as HWND tells you immediately that it returns this. It could also tell you a function requires an HWND as a parameter, and again, C would then require that that parameter be passed to the function as an HWND.

                You can, to an extent, simulate this behavior in PB with macros, and I'd actually recommend it, although PB will still compile if, in this example, you passed a DWORD instead of an HWND. C conventions aside, it helps to make your code more maintainable.
                Last edited by Eric Cochran; 17 Mar 2009, 10:03 AM.
                Software: Win XP Pro x64 SP2, PB/Win 8.04, PB/CC 4.04
                Hardware: AMD Athlon 64 3200+ (Clock speed 2.00 GHz) on a Gigabyte K8N Pro nForce3-150 mobo, 1 GB PC3200/DDR400 RAM, GeForce 7300 GT 256 MB DDR2 video

                Comment


                • #9
                  but isn't there a performance hit using dword instead of long? Maybe it is in an entirely different context ??
                  I wondered about that too, so I ran a test. The LONG's are faster in all 3 instances. btw, no difference in speed was noted making the api call itself as LONG or DWORD.

                  Probably this is academic since: why would a test on a handle be in a tight loop? But, for general knowledge and for when ya just never know.
                  Code:
                  #COMPILE EXE
                  #DIM ALL
                  DECLARE FUNCTION GetModuleHandle LIB "KERNEL32.DLL" ALIAS "GetModuleHandleA" (lpModuleName AS ASCIIZ) AS DWORD
                  
                  FUNCTION PBMAIN () AS LONG
                      LOCAL modHndlL, ii AS LONG, modHndlDw AS DWORD
                      LOCAL t AS QUAD, run1, run2, run3, run4, run5, run6 AS QUAD
                      
                      modHndlDw = GetModuleHandle("d:\dwordVsLong.exe") '< whatever you call this program
                      modHndlL  = GetModuleHandle("d:\dwordVsLong.exe")
                      TIX t
                      FOR ii = 1 TO 1000000
                         IF modHndlL <> 0 THEN
                            !nop
                         END IF
                      NEXT
                      TIX END t
                      run1 = t
                  
                      TIX t
                      FOR ii = 1 TO 1000000
                         IF modHndlDw <> 0 THEN
                            !nop
                         END IF
                      NEXT
                      TIX END t
                      run2 = t
                  
                      TIX t
                      FOR ii = 1 TO 1000000
                         IF modHndlL = 0 THEN
                            !nop
                         END IF
                      NEXT
                      TIX END t
                      run3 = t
                  
                      TIX t
                      FOR ii = 1 TO 1000000
                         IF modHndlDw = 0 THEN
                            !nop
                         END IF
                      NEXT
                      TIX END t
                      run4 = t
                  
                      TIX t
                      FOR ii = 1 TO 1000000
                         IF modHndlL THEN
                            !nop
                         END IF
                      NEXT
                      TIX END t
                      run5 = t
                  
                      TIX t
                      FOR ii = 1 TO 1000000
                         IF modHndlDw THEN
                            !nop
                         END IF
                      NEXT
                      TIX END t
                      run6 = t
                  
                      ? "LONG/DWORD difference using <>       : " & STR$((run2 / run1) * 100, 5) & "%" & $CRLF & _
                        "LONG/DWORD difference using =         : " & STR$((run4 / run3) * 100, 5) & "%" & $CRLF & _
                        "LONG/DWORD difference using boolian: " & STR$((run6 / run5) * 100, 5) & "%"       
                  
                  END FUNCTION
                  Attached Files

                  Comment

                  Working...
                  X