Announcement

Collapse
No announcement yet.

Control Send

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

  • Control Send

    Please add your comments and suggestions as a Reply to this thread.





    PB/WIN - CONTROL SEND statement

    Purpose
    Send a message to a control.
    Syntax
    CONTROL SEND hDlg, id&, Msg&, wParam&, lParam& [TO lResult&]
    Remarks
    hDlg refers to the dialog that owns the control.

    id& is the unique control identifier as assigned to the control with a CONTROL ADD statement.

    Msg& is the message you want to send the control.

    wParam& is the first message parameter. lParam& is the second message parameter. The values of wParam& and lParam& are message-dependent. By default, PowerBASIC passes these parameters BYVAL. If the target control is expected to return or alter the values passed in the wParam& and lParam& parameters, pass them using VARPTR or the return values will be discarded. For example:

    Code:
    ' Retrieve an Edit control's Current Selection
    CONTROL SEND CB.HNDL, %ID_EDIT1, %EM_GETSEL, VARPTR(Sel1&), VARPTR(Sel2&)
    CONTROL SEND does not return from execution until the control's callback has processed the message. This synchronous behavior is quite different to the behavior of CONTROL POST, which simply places the message in the control's message queue (for processing at a later time) and immediately returns. On this basis, CONTROL SEND can receive a return value from the message, but CONTROL POST cannot.

    TO
    The return value from the message can optionally be assigned to lResult&.

    If CONTROL SEND sends a message that arrives back in the same callback as the message originated, care should be exercised to ensure that critical STATIC and GLOBAL variables are not unexpectedly altered by the second message processing code in the callback. This is known as re-entrant code design.
    Restrictions
    To send a custom message to a dialog, use a message value in the range of (%WM_USER + 500) to (%WM_USER + &H07FFF), or use the RegisterWindowMessage API to obtain a unique message value from the operating system. Using messages with a numeric value of less then %WM_USER + 500 may conflict with Windows Common Control messages.
    See AlsoReferencesExamples
    ' Programmatically click a button:

    CONTROL SEND hDlg, %ID_BTN1, %BM_CLICK, 0, 0
    Last edited by Gary Beene; 28 Oct 2014, 07:07 PM.

  • #2
    I think you should add a paragraph somewhere like..

    "CONTROL SEND is used to communicate with controls which are not supported by DDT keywords and statements. When using CONTROL SEND, the Msg&, wparam&, lparam& and lresult& values are defined solely by the publisher of the control. It is a 'low-level' interface with non-DDT controls. "

    You may or may not want to make some kind of reference to the Windows' 'SendMessage()' function.
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      Might it be useful to say that the command is functionally equivalent to the API command:

      Code:
      lResult& = SendMessage ( GetDlgItem( hDlg, id& ), Msg&, wParam&, lParam& )
      Last edited by George Bleck; 28 Aug 2014, 10:09 AM.
      <b>George W. Bleck</b>
      <img src='http://www.blecktech.com/myemail.gif'>

      Comment


      • #4
        Like George points out CONTROL SEND is indeed simply a wrapper for CONTROL HANDLE (GetDlgItem) + SendMessage.

        Here is a disassembly of one CONTROL SEND line:
        Code:
        mov ecx, x                  / /
        mov eax, x                 | |
        call ...                   | |
          push edx                 | |
          push eax                 | |
          push ecx                 | |       
          call USER32.GetDlgItem   | | CONTROL HANDLE
            ...                    | |
          pop edx                  | |
          retn                     |  \
        push eax                   |
        push x                     |   
        push x                     |
        push x                     |
        call USER32.SendMessageA    \  CONTROL SEND
        So if you already have the CONTROL HANDLE you should use SendMessage directly to avoid the unnecessary overhead of repeatedly calling GetDlgItem (plus SendMessage also takes less to type than CONTROL SEND )

        You can do that and maintain DDT style by using a MACRO such as this:
        Code:
        MACRO FUNCTION CONTROL_SENDDIRECT (hCtrl, dwMsg, wParam, lParam) = SendMessage (hCtrl, dwMsg, wParam, lParam)
        Last edited by Wayne Diamond; 26 Jan 2015, 12:54 PM.
        -

        Comment


        • #5
          >So if you already have the CONTROL HANDLE you should use SendMessage

          All optimization is application specific. Storing the value returned by CONTROL HANDLE costs the memory to store it and of course synchronization code if the procedure is to be used re-entrantly (multiple dialogs sharing the dialog procedure). So I would think "may use SendMessage" would be more appropos than "should use."

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

          Comment


          • #6
            Michael, far out... I give up! As you know I edited it in response to you going out of your way to tell me this bit of apparent wisdom, where you made it clear you didn't know the inner workings of what you were trying to tell me about:
            Originally posted by Michael Mattias View Post
            First, in the consistency arena, if you are going to reference the CONTROL HANDLE statement you should probably use the CONTROL SEND statement instead of the SendMessage() function.
            So either I'm 1) using CONTROL SEND, in which case I'm redundantly calling CONTROL HANDLE each and every single time (please tell me WHY i should? an explanation would be nice thankyou!),
            or 2) I'm calling SendMessage, but not using "DDT style" in the process (and we all know how users like to read through source code before using software).

            And you're not happy with either! And I even provided a DDT-style version to try to make you happy.

            Originally posted by Michael Mattias View Post
            Storing the value returned by CONTROL HANDLE costs the memory to store it
            Yes variables cost memory to store. And we're talking 32 bits here. Am i committing a crime or something here... what am i missing?

            Originally posted by Michael Mattias View Post
            and of course synchronization code if the procedure is to be used re-entrantly
            Look at the disassembly for CONTROL SEND.
            Look at the disassembly for SendMessage.
            Now explain how re-entrancy issues are possible for one but not the other.
            Please explain how it is possible for SendMessage to be thread-safe, but not if GetDlgItem is called immediately before it. (That is also effectively what you're asking, as that is all that CONTROL SEND is)

            I won't be responding though, so you can use that as an escape clause.
            Last edited by Wayne Diamond; 26 Jan 2015, 02:04 PM.
            -

            Comment


            • #7
              As I mentioned in the PM, this is not the thread about which I suggested CONTROL SEND should be used instead of SendMessage().

              Those comments were about your comments at the CONTROL REDRAW statement here .. http://www.powerbasic.com/support/pb...ad.php?t=55627
              Michael Mattias
              Tal Systems (retired)
              Port Washington WI USA
              [email protected]
              http://www.talsystems.com

              Comment

              Working...
              X