Announcement

Collapse
No announcement yet.

Superclassing Common Controls

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

  • Superclassing Common Controls

    In controls where messages are sent as %WM_NOTIFY can they be superclassed and if so, are the same variables used to extract the hdr.code.

    Also are there any caveats to superclassing. Do they go out of scope when the program ends or need they be destroyed in the %WM_DESTROY event.

    Bob Mechler

  • #2
    WM_NOTIFY is unaffected by either superclassing or subclassing, as is not sent to the control, it is sent to the owner of the control.

    Speaketh SDK:
    WM_NOTIFY Message

    --------------------------------------------------------------------------------

    The WM_NOTIFY message is sent by a common control to its parent window when an event has occurred or the control requires some information.
    What is it you want to do with what control? Subclassing and/or superclassing may be total overkill, as the Common (capital C) Controls send a lot more notification messages ("opportunities") than do common (small c) controls.

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

    Comment


    • #3
      Q1: In controls where messages are sent as %WM_NOTIFY can they be superclassed
      A1: Yes

      Q2: and if so, are the same variables used to extract the hdr.code.
      A2: Yes

      Q3: Also are there any caveats to superclassing.
      A3: same as subclassing, need to handle instance data correctly if multple instances, superclassing gives you wm_create wm_nccreate messages, and lastly pointed out by Dominic Mitchell, be aware when forming superclass or subclass chains.

      Q4: Do they go out of scope when the program ends or need they be destroyed in the %WM_DESTROY event.
      A4: Yes, when program ends. From Win32Api Help file: "All window classes that an application registers are unregistered when it terminates."
      Last edited by Jules Marchildon; 23 Jun 2008, 08:08 PM.

      Comment


      • #4
        My goal is to build a toolbox of ready made, application/program specific controls where just CONTROL ADD "NCusip" etc will do all the work of filtering of keystrokes allowed and providing in the callback a lookup to another file with it's own lookup window. I hope this can be done by simply calling a function that already does this and return the value to the super class procedure. Currently I have to place another control on the screen and show it when the field is active and hide it when it's not.

        For common controls like ListView,TreeView and Tab I tried looking in Poffs on how to handle the WM_Notify events. I guess I could create a popup style dialog the exact size of the common control and do my work there. If I make is a child window, I think it can be tabbed into but I'm not sure where it will go when I exit. A simple sample is needed or just verify that there is something in Poffs or the Forum and I'll continue to hunt.

        Instead of hunting by topic I may just look for posts by the names of people whose code has proven to do various jobs well and I can understand it.

        Thanks,

        Bob Mechler

        Comment


        • #5
          Bob, looking back through the forum it looks as if you have been chasing this one down for years! Had you considered using message cracker type of approach? As in James Fuller's post #11 on this thread:http://www.powerbasic.com/support/pbforums/showthread.php?t=36073&highlight=classless

          Comment


          • #6
            I have done this kind of thing for years... making a 'child control' which is actually a full-blown window with its own child windows.

            If you want a practical example of doing this... take a look at MDI applications. The "child controls" of the frame window are full-blown windows, each with their own window procedure.


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

            Comment


            • #7
              Both reasonable suggestions for future study but seems to be overkill for what I want. JC Fuller's code is over my head as are the MDI code.

              Just need an example of a superclassed ListView where I can trap some keystrokes and columnclicks that normally are accessible during the dialog callback. I tried using the CALL listviewcb as I added the control approach but it ignored the WM_NOTIFY messages.

              I probably just haven't looked hard enough.

              Thanks,

              Bob Mechler

              Comment


              • #8
                As I said before... WM_NOTIFY is sent to the PARENT of the listview, not the listview itself. Superclassing does nothing and in any case not necessary to get clicks and keys.

                All the keystrokes and clicks ARE accessible in the dialog callback procedure:

                WM_NOTIFY/NM_CLICK
                WM_NOTIFY/NM_DBLCLK
                WM_NOTIFY/LVN_KEYDOWN
                WM_NOTIFY/NM_CHAR
                WM_NOTIFY/NM_RCLICK

                (There is no 'Key up' notification available from listview)

                DDT "CONTROL ADD... CALL" procedure is only called on WM_COMMAND... which listview does not send to anything. So you will have to pick up WM_NOTIFY in the owner procedure.

                Or, don't use a listview control. Listviews normally don't process any keystrokes except up-down and left-right arrows anyway.

                It really sounds like you are trying to do something the long way.
                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]
                http://www.talsystems.com

                Comment


                • #9
                  LOCAL kp AS LV_KEYDOWN PTR
                  see kp below. I just needed the up arrow actually.
                  Code:
                        CASE %WM_NOTIFY
                          SELECT CASE CBCTL
                            CASE %IDM_LISTVIEW
                               CONTROL HANDLE CBHNDL, %IDM_LISTVIEW TO hctrl&
                               my_LpLvNm = CBLPARAM
                               SELECT CASE @my_LpLvNm.hdr.code
                                 CASE %NM_DBLCLK
                                   I = ListView_GetNextItem(BYVAL hctrl&, -1, %LVNI_SELECTED)
                                   IF I > -1 THEN
                                     VKEY = 20
                                     GETKEY = -1
                                   END IF
                                 CASE %NM_CLICK
                                   I = ListView_GetNextItem(BYVAL hctrl&, -1, %LVNI_SELECTED)
                                   IF I > -1 THEN
                                     GETKEY = -1
                                   END IF
                                 CASE %LVN_COLUMNCLICK
                                   LV_COLUMNID = @my_LpLvNm.iSubItem
                                   VKEY = 21
                                 'CASE ELSE
                                  ' VKEY = 22
                               END SELECT
                               kp = CBLPARAM
                               SELECT CASE @kp.hdr.code
                                 CASE %LVN_KEYDOWN
                                   SELECT CASE @kp.wVKEY
                                     CASE %VK_DOWN
                                       GETKEY = -1 'needed to refresh hot fields when not at bottom
                                     CASE %VK_UP
                                       GETKEY = -1 'needed to refresh hot fields when not at top
                                   END SELECT
                               END SELECT
                          END SELECT
                          FUNCTION = 0: EXIT FUNCTION
                  Last edited by BOB MECHLER; 24 Jun 2008, 03:50 PM.

                  Comment


                  • #10
                    WM_NOTIFY wParam :

                    Parameters

                    [wparam] idCtrl
                    Identifier of the common control sending the message. This identifier is not guaranteed to be unique. An application should use the hwndFrom or idFrom member of the NMHDR structure (passed as the lParam parameter) to identify the control.
                    I have no idea how CBCTL is correct in this code. On WM_COMMAND it's LOWRD(wParam) but that is not ALWAYS true on WM_NOTIFY (as documened by Microsoft, above).


                    Using DDT I think I would...
                    Code:
                    CASE %WM_NOTIFY
                             my_LpLvNm = CBLPARAM
                            IF @my_lplvmn.hdr.idFrom = %IDM_LISTVIEW THEN 
                                  hCtrl = @my_lplvmn.hdr.hWndfrom 
                                 ......
                    Michael Mattias
                    Tal Systems (retired)
                    Port Washington WI USA
                    [email protected]
                    http://www.talsystems.com

                    Comment


                    • #11
                      Originally posted by Michael Mattias View Post
                      I have no idea how CBCTL is correct in this code.
                      PB help system says:

                      Code:
                      Therefore, CBCTL is functionally equivalent to LO(WORD, wParam&) in a conventional Callback Function, and equivalent to LO(WORD, CBWPARAM) in a DDT Callback Function

                      Comment


                      • #12
                        Yes, that is what CBCTL is all right... the problem is, on WM_NOTIFY LOWRD(wparam) is not guaranteed to be the identifier of the sending control!
                        Michael Mattias
                        Tal Systems (retired)
                        Port Washington WI USA
                        [email protected]
                        http://www.talsystems.com

                        Comment


                        • #13
                          LOCAL my_LpLvNm AS NM_LISTVIEW PTR
                          is what I used for the notification messages.

                          Thanks though for pointing out the code changes that would be more reliable. In the past I always used the same id for the listview, something I'm getting away from now. The code was taken directly from an example and has never falied, not saying in a more involved program it might not.

                          Bob Mechler

                          Comment


                          • #14
                            >The code was taken directly from an example ..

                            Old code never dies, it just gets cut to the clipboard.
                            Michael Mattias
                            Tal Systems (retired)
                            Port Washington WI USA
                            [email protected]
                            http://www.talsystems.com

                            Comment

                            Working...
                            X