Announcement

Collapse
No announcement yet.

Why ANSI and UNICODE versions of SendMessage?

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

  • Why ANSI and UNICODE versions of SendMessage?

    The PBWin10 include files have these two declarations for SendMessage - one for ANSI and one for UNICODE.
    Code:
    DECLARE FUNCTION SendMessageA LIB "User32.dll" ALIAS "SendMessageA" _
        (BYVAL hWnd AS DWORD, BYVAL dwMsg AS DWORD, BYVAL wParam AS DWORD, _
        BYVAL lParam AS LONG) AS LONG
    
    DECLARE FUNCTION SendMessageW LIB "User32.dll" ALIAS "SendMessageW" _
        (BYVAL hWnd AS DWORD, BYVAL dwMsg AS DWORD, BYVAL wParam AS DWORD, _
        BYVAL lParam AS LONG) AS LONG
    Even though all of the arguments are numeric (no string arguments), I assume the reason for having ANSI/UNICODE versions of the API is that the wParam/lParam may be pointers to structures which contain strings.

    Would there be any other reasons?

  • #2
    > may be pointers to structures which contain strings

    Or, pointers to strings themselves.

    i.e., instead of "BYVAL lparam AS LONG" you might use "BYVAL lparam AS ASCIIZ PTR" (ANSI API) or "BYVAL lparam as WSTRINGZ PTR" (OEM API).

    (examples: WM_SETTEXT or CB_ADDSTRING messages).

    MCM

    Comment


    • #3
      Don't really know, but if sendmessage ever called for class info, desktop names, thread names, security info, module filenames, system error messages, sounds etc might explain it.

      Could even be linked to when you do HWND_BROADCAST.

      Edit: I don't think it would matter what wParam/lParam pointed to unless SendMessage actually did something with them on occasion. I'm leaning toward error handling though for things that might generate application GPFs.
      Last edited by Larry Charlton; 12 Mar 2012, 12:21 PM.
      LarryC
      Website
      Sometimes life's a dream, sometimes it's a scream

      Comment


      • #4
        I don't think it would matter what wParam/lParam pointed to unless SendMessage actually did something with them on occasion.
        It does. As Windows is all unicode, it has to convert ansi strings to unicode.
        Forum: http://www.jose.it-berater.org/smfforum/index.php

        Comment


        • #5
          Edit: I don't think it would matter what wParam/lParam pointed to unless SendMessage actually did something with them on occa
          Internal conversions Wide/ANSI aside, when a param is used, it is always used for 'something!'

          The SendMessageA and SendMessageW functions are used so when either wParam or lparam are a (message-dependent) "pointer to a string", the operatiing system will know what kind of string (ANSI or Wide) it is.

          Check your SDK reference for WM_SETTEXT and/or CB_ADDSTRING. If there were only one "SendMessage" function, how could Windows possibly know if you are sending a Wide string or an ANSI string?

          MCM

          Comment


          • #6
            That's interesting, learn stuff every day Went and bought Windows Internals. What I think I'm reading is that the conversion is done for internal OS API's like registry and file I/O. Is there any way to tell why (what OS feature) or when unicode conversions are done, other than just assuming if there's an A version of a function some conversion must happen?

            check your SDK reference for WM_SETTEXT and/or CB_ADDSTRING. If there were only one "SendMessage" function, how could Windows possibly know if you are sending a Wide string or an ANSI string?
            Wow! I created a unicode window, then called SetWindowTextA with an ascii string and it worked! I'm sorry but that's just a bit amazing to me. I assume the function used tells windows whether to convert incomming and RegisterClass tells windows whether to convert when delivering the message to a window or is it smarter than that? i.e. does it look at source and destination and only convert if they're different? What would happen with HWND_BROADCAST in a app with multiple mixed windows. Would there only be two versions of the message or would it convert for each ASCII window?

            I also assume this "magic" only works for standard windows messages? i.e. WM_USER+x messages, you're on your own? I have to hit the road and I'll search later, but is there any guidance on creating two versions of API calls for WM_USER+x messages?
            Last edited by Larry Charlton; 12 Mar 2012, 06:32 PM.
            LarryC
            Website
            Sometimes life's a dream, sometimes it's a scream

            Comment


            • #7
              >WM_USER+x messages, you're on your own?

              Um, yeah. Tht's why they are called USER messages: the meaning of wparam and lparam are USER-defined.

              > but is there any guidance on creating two versions of API calls for WM_USER+x >messages?

              Um, you could try...


              Code:
              %WM_SEND_ANSI   =  %WM_USER+1 
              %WM_SEND_WIDE  =  %WM_USER+2 
              
              
                 SendMessage  hWnd, WM_SEND_ANSI , %NULL, BYVAL STRPTR(AnsiStringVar) 
                  OR 
                 SendMessage  hWnd, WM_SEND_WIDE , %NULL, BYVAL STRPTR(WideStringVar) 
              
              
              
              ...
              FUNCTION WndProc
              
              LOCAL psz AS ASCIIZ PTR, pwsz AS WSTRINGZ PTR 
              
              LOCAL X AS  {STRING|WSTRING|ASCIIZ * something|WSTRINGZ * something}  
              
               SELECT CASE AS LONG wMSg 
                 CASE %WM_SEND_ANSI, %WM_SEND_WIDE 
                    IF wMsg = %WM_SEND_ANSI THEN 
                       psz =  lparam 
                       X =  @psz     '   
                   ELSE
                     pwSz = lparam
                     X = @pwSz
                  END IF 
              
              ...
              Why on earth you'd want to mix ANSI and WIDE like this in a single application is, well, a mystery to me.

              MCM

              Comment


              • #8
                Or did you mean creating two functions for others to call?

                I think I'd just create two functions with different param definitions.

                (SendMessage/WM_USER does not enter this discussion at all).

                Comment

                Working...
                X