Announcement

Collapse
No announcement yet.

Understanding messages - more questions than answers!

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

  • Understanding messages - more questions than answers!

    In John Montenigro's last post he mentioned questions about messages.

    Even after reading (a lot) recently on the topic, I also seem to be missing a few points that would help me understand how messages and PowerBASIC interact.

    Like John, I'd rather read about it first, then post questions so that I'm asking from a position of having worked on it first, rather than abusing the help of the folks here.

    But his post flagged my ongoing lack of having read the right materials to complete my understanding of the topic.

    So I decided to write this message more to help me clarify what questions I'm trying to answer on my own, rather than ask for any detailed responses.

    As I understand it, here's the list of procedures in the loop:

    1. subclassing redirected window procedure (if used)
    2. control callback function
    3. dialog callback function
    4. DDT default callback funciton
    5. window procedure for the dialog/control class
    6. Windows OS default window procedure

    And here are the kinds of questions I'm still looking for answers in the online documentation. (I've order a couple of the books I've seen recommended, so I'm hoping they will help out).

    1. Is the procedure list above a complete/correct list of procedures that are involved?

    2. Which notifications and messages documented for classes on MSDN, are available to the procedures on the list, and in what order (especially if a subclassed control is involved)? Why aren't all MSDN notifications available to one of my dialogs/controls? Does the window procedure for the control class selectively allow some notifications/messages through to my own callback functions?

    3. Are some notifications/messages not received by a PB dialog or child control? If not, why is that? How would we know which ones are or are not available for processing within our PB app?

    4. Does a PB app shield the dialog/control callbacks from any messages received by the PB app (such as via the DDT engine default callback function)?

    5. This seems true: All messages sent by the Windows OS to a window control/dialog) are not normally available in their corresponding PB callback function, else there wouldn't be a need for subclassing.

    6. Once a PB callback does what it wants, and returns TRUE, what does PB do with the message? Does it call the default window class procedure for the control/dialog window class for further processing? If so, what does the default window procedure do? Nothing, or does it simply do more if False is returned and less if True is returned?

    9. Does the DDT engine default callback procedure actually do anything, of does it simply call the window procedure of the window class for the control/dialog?

    10. Is there some kind of "app" level message processing added by the compiler? Or is each dialog a separate entity that processes it's own messages? Perhaps the compiler adds a default callback to each dialog?

    I wrote this message more to help me clarify what questions I'm trying to answer on my own, rather than ask for any detailed responses.

    However, if there's an apparent fundamental point of misunderstanding that my questions highlight, I'd appreciate feedback.

    Dominic had read a (wrong) comment I made and was going to provide some clarification. I'm looking forward to his, and any other comments that seem appropriate.

    In the meantime, I'll keep reading/experimenting until I get past the questions I've raised.

  • #2
    Gary,

    I found tons of info in the SDK:
    ms-help://MS.PSDKXPSP2.1033/winui/winui/windowsuserinterface/windowing/messagesandmessagequeues.htm

    This isn't a URL really, just an index into the files on my hard drive. I have H2viewer set for the SDK, and this is the "address" it showed.


    It'll take me awhile to wade through it, but so far, I'm getting answers..
    Last edited by John Montenigro; 22 Feb 2009, 01:48 PM.

    Comment


    • #3
      Messages are overrated.
      Over the years i seen lot's of new people misunderstanding things and take the wrong approach.

      Subclassing controls for example, i barely have/had the need for that.
      It is usually done to get some dumb message which was already present in the parent's windowprocedure anyway.

      Don't let the MSDN overwhelm you but focus on the message or need you have since all other processing will go right by default.

      The few messages you'll most likely need over the years are really problematic at first.
      Like WM_PAINT, it works together with WM_ERASEBKGND and has the odd BeginPaint() EndPaint() + prevent further processing indicator.

      Like WM_SETCURSOR, why on earth did ms translate the control's WM_LBUTTON... and such to WM_SETCURSOR in the parent?
      also the WM_SETCURSOR is created for what it suposed to do, set a cursor.
      Good example, by default it will maintain itself.

      Then we have the trouble understanding dialogboxes (like DDT in PB) and SDK style windows.
      I strongly believe people get confused due the internal calls the compiler provides.
      It won't learn you anything since you'll never read about certain behaviour this way.
      Besides it would be a better choice imo to use SDK for this support.

      I have seen so much crap due misinterpretation and lazy investigation, to me the fun is over stressing that example code should be solid.

      If you must know, i bought a few of Dan Appleman's winapi books and read them over and over until i finally understood the stuff.
      This may indicate how much effort one should put in reading, even if it's simply the MSDN online.
      At the end you'll discover you have read so much but in practise need so little.

      Here is my jolly response to your list

      1. subclassing redirected window procedure (if used)
      where do you need it for?
      If you think tou need it, you probably won't
      But there are exceptions.

      2. control callback function
      A bit of a waste thing.
      Better use a single function to handle a single specific message.

      3. dialog callback function
      A normal thing to have.
      Abort further processing is usually done by providing a non-zero value.
      This is inherent to the dialogbox system but differs from SDK style where you can skip the DefWindowProc()

      4. DDT default callback funciton
      Seems like #3

      5. window procedure for the dialog/control class
      Seems like #3 but for controls it is hidden.
      It is hidden because it processes it's own behaviour and by default it is unwanted to interfere.

      By subclassing it you can mess with the behaviour but is usually not needed.
      For custom controls it is neater to superclass, same problems wit messing with it's default behaviour but we assume you know what you are doing.

      6. Windows OS default window procedure
      ?
      A SDK variant of the windowprocedure??
      hellobasic

      Comment


      • #4
        First, it is important to distinguish between OOP classes and Window classes.

        Object oriented programming is a level above the core Windows API, and using PB you need to be concerned with Window classes. Window classes simply refer to a specific window type (ie. button control, listbox control, dialog box, custom window class).

        A window class starts with a definition of a single universal window procedure for the class (type) which processes all messages sent to it.

        Window procedures process four parameters, common to messages:

        (1) The handle to the specific instance of the window class (ie. multiple button controls, share one universal window procedure, but each instance of the button control has its own handle). This allows the window procedure to differentiate which actual window (control) it is dealing with.

        (2) The current message being processed. The operating system defines a number of universal messages (ie. WM_ prefix used) which many window classes will deal with. Messages like WM_PAINT , WM_SIZE, etc are common among window classes.

        Default processing for these universal messages is provided in the Windows API via the DefWindowProc API function. A class though can process it in its own way if it chooses.

        There can also be messages unique to the window class. These messages usually have a unique prefix for the message constant (ie. BM_ is used for button class messages).

        (3,4) wParam and lParam are simply two possible parameters that a message can use to pass data. Each message uses these parameters in their own way. Read the API docs to see each message uses these parameters.

        Now it should be noted that messages can move in two directions. Some messages are sent by the operating system to the window class and some messages are a means of a window class communicating with another window class (usually a parent window).

        For example, Windows will send the WM_LBUTTONDOWN message to a window when the left mouse button is pressed down over it and the window may in turn send a message to its parent window (ie. WM_COMMAND) to notify it that an action has occurred. This is why some messages are refered to as Notification messages in the API docs. These messages are where a child window sends a message to its parent that something has occurred.

        This two way message communication is necessary because normally you don't have access to the window procedure to a predefined system window class (ie. button control). You would not know something occurred, because you can't access the controls window procedure, because it is in the operating system itself.

        Now of course one could subclass a controls window procedure to preprocess messages sent to it, but that would be messy if you had to do that for every single system window class (controls).

        Windows provides a better means, which is notification messages. A window class (control) can notify its parent that something has happened. The two most often used notification messages are:

        WM_COMMAMD
        WM_NOTIFY

        The child window classes sends its parent a message telling it something has occurred.

        Since the parent window class is either a Dialog or a custom window class (used in SDK style coding), you have access to its window (or dialog) procedure.

        Custom window classes are ones you write yourself, so your app has direct access to their window procedure, so you can process these notification messages.

        While you don't have access to a dialogs window procedure (its in the operating system), Dialogs were designed to forward messages to whats called a dialog procedure. Dialog procedures are similiar to a window procedure, but with a slight difference, You have access to the dialogs dialog procedure so you can process the notification messages sent to it from child windows (controls).

        Now to add a wrench to all of this, some messages are not sent directly to a window classes window procedure. Some messages are sent instead to the applications message que, which is them forwarded to the apps message loop (ie. GetMessage or PeekMessage API function used to get the messages from the que). The message loop is necessary for all apps. DDT emulates the message loop with its own unique DIALOG GET EVENTS command, but it is basically the same thing under the hood.

        All apps must have a message loop or it will not respond to user input.

        The messages forwarded to the message loop by the operating syste are user input messages (mouse, keyboard) and some others like WM_PAINT.

        Windows provides two APIs for sending messages to windows.

        SendMessage sends a message directly to the windows window procedure.

        PostMessage puts a message in the apps message que and windows does a first in, first out method for feeding those messages to the message loop. This is why you can click on an app which appears busy and rather than immediately having the app respond, it sometimes waits a bit (while busy) before the message input gets to the app. This is because, unless the message loop is currently requesting the next message, that message must wait in the message que.

        To be continued ....
        Chris Boss
        Computer Workshop
        Developer of "EZGUI"
        http://cwsof.com
        http://twitter.com/EZGUIProGuy

        Comment


        • #5
          When learning PB, you need to first determine whether a specific message is one that is sent to a windows window procedure or whether it is a notification message sent from child windows to their parent.

          If the message is one sent to the window (ie. WM_PAINT), then you simply don't have access to it (unless you subclass the control). The control does the work of handing it.

          You only subclass a control, when you want to change its normal behavior somehow, otherwise it does all the work for you and you need only concern yourself with the notification messages it sends to its parent.

          The messages you most likely need to be concerned with are the notification messages (ie. WM_COMMAND, WM_NOTIFY) the controls are sending to their parent window (ie. dialog). Most of your window message processing is for notification messages.

          Now another message type you will use a lot are the messages unique to the control class (they won't use the WM_ prefix, but a unique prefix unique to the window class, like buttons use BM_). These messages are used to send requests to the window class (control) to do something or return some info about itself.

          These messages are not the universal WM_ messages , but are the ones with the unique class prefix (ie. BM_).

          These type messages are what you need to use to make controls do things or get data back.

          The SendMessage API function is what you will use to send such messages to controls or other window classes.

          DDT provides the CONTROL SEND command which does the same thing.

          When learning to use a control, the first thing you must do is read the API docs and see what notification messages it sends to its parent window. The docs will explain the meaning of the notification message and what the parameters wparam and lParam are passing.

          Next read the API docs about the class specific messages (ie. BM_ for buttons) which are used to make the controls do things or to request data back. Each message is unique, so you need to read the API docs to see how it works and how it returns data. Do not assume messages are similiar. Each message is unique and you must understand how it works, otherwise you will have problems.
          Chris Boss
          Computer Workshop
          Developer of "EZGUI"
          http://cwsof.com
          http://twitter.com/EZGUIProGuy

          Comment


          • #6
            Edwin/Chris,

            Thanks so much for taking the time to provide responses. I'm definitely in the reading mode and I already begin to see how "read a lot/use a little" can be the end result.

            The problem during a learning phase is often that you don't know what is very important or what is not so important. That is, of course, where the practice comes in.

            Thanks again for your help.

            John,
            I'll follow the lead you gave also. Thanks!

            Comment


            • #7
              The problem during a learning phase is often that you don't know what is very important or what is not so important
              Look at the problem the other way: Instead of asking, "is this notification message important?" ask yourself, "about what do I wish to be notified, and what message will do that?"

              I think you'll find the point of diminishing returns comes fairly quickly.. 90% of your applications may never need to do anything with more than the same small handful of notification messages.
              Michael Mattias
              Tal Systems Inc. (retired)
              Racine WI USA
              [email protected]
              http://www.talsystems.com

              Comment


              • #8
                Michael,

                Learning primarily the parts I need to know, as I go along, is definitely a very practical way to learn. But I like to know how the things I use most often fit into the big picture.

                As I've probably indicated, when I started with PowerBASIC it irritated the fool out me that there wasn't a big picture, organized listing of available messages and an indication of which ones were most useful to PowerBASIC programmers. I've read there are 1000+ messages, but can't imagine that most programmers use but a fraction of those.

                I feel better now that I have made my own message/notification list (drawn from MSDN, of course, but put in a format of my choosing). The test of my home-made list is whether any messages appear in the forum that aren't on my list. That number is shrinking fast, so I think I'm homing in on the big picture, organized listing that I wanted.

                As you noted, I can see now that my apps will likely use a small handful of notification messages. But I'm glad that I've spent the time to walk through a bigger list and to see where the "most used, 100+ messages" came from, and which messages are still there for potential use in the future.

                Interesting data point - in all of the samples distributed with PowerBASIC, there are only about 50 messages/notifications used (CB.MSG values). And of those, only a handful were used frequently in the sample apps.

                Comment


                • #9
                  Learning primarily the parts I need to know, as I go along, is definitely a very practical way to learn. But I like to know how the things I use most often fit into the big picture.
                  Welcome to SDK and MSDN, it remains impractical to learn.
                  While the 'big picture' is you don't to know hundreds of message, the few you need are steep to understand right away.
                  There are topics on this matter but i also know that i keep seeing the same mistakes being made over and over.
                  For example the the memory dc and selectobject stuff.
                  people do not deselect since they do not get the picture.
                  What can we do?

                  As I've probably indicated, when I started with PowerBASIC it irritated the fool out me that there wasn't a big picture, organized listing of available messages and an indication of which ones were most useful to PowerBASIC programmers.
                  It has nothing to do with PowerBASIC unless you like environments like VB where things are more simple (but also restrictive unf.)
                  PowerBASIC uses a custom variant to the dialogbox principles, not really my choice but ok..
                  It's great that we can use ordinary windowprocedures and not some dumb windowsystem!
                  Better struggle to learn than a form like in VB.

                  I've read there are 1000+ messages, but can't imagine that most programmers use but a fraction of those.
                  Oh no, it is even worse imo, imo most people will use programming tools for simple single dialog ("hey it works") hobby stuff.

                  I am aware of a basic language and forum where this appears even more (and they s..., there is no reasoning to improvement tips).

                  You are better of with PowerBASIC since it (still) provides low level Windows stuff.
                  We had to wait for classes very long but it's there and it is a supurb addition, sorry, could not resist
                  hellobasic

                  Comment


                  • #10
                    Learning messages

                    Coming from Unix to DOS and then to Windows I learnt a very long history of messages, and the older you are growing the more complications are increasing (subjectively). Experience in this case is really a 'cloudy' expression. So, what i always do is generating a message loop in my DLL debugger filtering only messages i'm just interested in, and diplaying most illustrative results in a small helper window. So, you get a quick overview of the sequence of messages. This often helps even finding a time related bug. Just placing the debugger's "dbg" commands at the right places in code i get the desired results quickly and as a code progress related record.
                    Norbert Doerre

                    Comment

                    Working...
                    X