Announcement

Collapse
No announcement yet.

Divider Doubleclick disable

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

  • Divider Doubleclick disable

    Does someone have a way to disable the dividerbar in a listview header? I haven't tried subclassing the header unless that is the only way.

    I'm having a problem with the data being thinner than the header. When you double click the divider it makes the column fit the data instead of the header.

    I can trap the %HDN_DIVIDERDBLCLICK message and send a SendMessage(hwndLV, %LVM_SETCOLUMNWIDTH, iCol, %LVSCW_AUTOSIZE_USEHEADER) but this results in a dance from the width of the data to the width of the header. I would be happy with just double click the header and resize it myself.

    Something ideal would be similar to the Function=%True to disable the %HDN_BEGINTRACK message.

    Frank

  • #2
    Frank, in my programs I use the SetFixedHeader sentence to avoid resize some specific colums. See the use in my recent sample added, last week, in Source Code Library in this Forum. Specifically on %WM_INITDIALOG code inside the CALLBACK FUNCTION (lines 312 to 320).
    I hope it can help you.
    Jordi

    Comment


    • #3
      Hi Jordi,

      Thank you for looking into it. Yes, I downloaded your sample last week but to show you the problem... change 'Part Date' column title to 'Part Number Date' on line #233 to make it longer. Now double click on the divider for that column. The title no longer fits in the column because the double click adjusts the size of the column to the data and not the header.

      Comment


      • #4
        Frank,
        If your app. use Common control 6, usually done via a manifest,
        then add the HDS_NOSIZING style to the listview header...

        Code:
        LOCAL hListviewHeader AS DWORD
        hListviewHeader = SendDlgItemMessage(hDlg, %Listview, %LVM_GETHEADER, 0, 0)
        SetWindowLong(hListviewHeader, %GWL_STYLE, GetWindowLong(hListviewHeader, %GWL_STYLE) OR %HDS_NOSIZING)

        Comment


        • #5
          Frank,

          When you are ready to subclass, Pierre has posted code for that too

          (Works for either version of Common control)
          Rgds, Dave

          Comment


          • #6
            Thanks Pierre. I looked at the styles in PB Help but didn't look at MSDN styles. HDS_NOSIZING has got me closer.

            Thanks Dave. I already have a ton of Pierre subclassing samples. I just didn't go there yet

            Comment


            • #7
              Hi Frank,

              Just to be clear, That link is to code which uses Subclassing to handle these messages in a Listview control.
              Code:
               
              CASE %HDN_DIVIDERDBLCLICKW 'Left double click on divider
              
              CASE %HDN_TRACKW, %HDN_BEGINTRACKW, %HDN_ENDTRACKW 'Divider dragging
              Rgds, Dave

              Comment


              • #8
                Also,

                A listview control, by itself, include another control, wich is a header control.
                This is why HDS_NOSIZING is not seen in listview style,
                it's a header style, you got to deal with this embedded control directly.

                If you want to completely disable the header, you may use the following...
                Code:
                LOCAL hListviewHeader AS DWORD
                hListviewHeader = SendDlgItemMessage(hDlg, %Listview, %LVM_GETHEADER, 0, 0)
                EnableWindow(hListviewHeader, %FALSE)

                Comment


                • #9
                  Yes, Frank I posted this recently...
                  Code:
                    hListViewHeader = SendMessageA(hListView, %LVM_GETHEADER, 0, 0)
                    DisableXPThemeControl hListViewHeader
                    SetWindowLongA hListViewHeader, %GWL_STYLE, GetWindowLongA(hListViewHeader, %GWL_STYLE) OR %HDS_FLAT OR %HDS_NOSIZING 'OR %HDS_HOTTRACK
                  No need to subclass for this to work. You just need the header handle.

                  See it in action here.

                  You will also have to Disable the XPTheme for the Header so Windows theming does not overwrite your changes.

                  Code:
                  '------------------------------------------------------------------------------
                  'Purpose: by calling SetWindowTheme with an empty string your control
                  '         (button/checkbox/combo etc) will not be painted with the XP Theme.
                  '
                  'Example: LOCAL hButton AS DWORD
                  '         hButton = GetDlgItem( hWnd, %IDOK )
                  '         lRes = DisableXPThemeControl ( hbutton )
                  '         InvalidateRect hButton,BYVAL %NULL,%TRUE
                  '------------------------------------------------------------------------------
                  FUNCTION DisableXPThemeControl(BYVAL hControl AS DWORD) AS LONG
                    LOCAL hLib AS DWORD, pProc AS DWORD, lRes AS LONG
                    hLib = LoadLibraryA("UxTheme.dll")
                    IF hLib THEN
                       pProc = GetProcAddress(hLib, "SetWindowTheme")
                       IF pProc THEN
                          CALL DWORD pProc USING SetWindowTheme(hControl, " ", " ")  TO lRes
                          FUNCTION = lRes
                       END IF
                       FreeLibrary hLib
                    END IF
                  END FUNCTION
                  NOTE:
                  Without the XPTheme the header will be thinner. It's size is based on the font size you are using. Easy fix. Create a larger font for the header.

                  Comment


                  • #10
                    Dave, the link you posted in #5 is really what I was looking for. My opening question was not exactly what I wanted. I thought getting rid of the divider would solve my problem but it doesn't. Thank you Jim but I sent you down the wrong path.

                    It did bring me to something I don't understand. If I am trying to change the behavior of the header, why do I subclass the listview? I see that the notification I want to change is '%HDN_' and immediately think Header. I know the Listview is the parent but it just doesn't seem logical.

                    Frank

                    Comment


                    • #11
                      Frank,

                      The HDN_ notification messages are sent to the Header control's Parent window (aka the Listview control).

                      Subclassing the Listview gives access to those messages, which don't normally make it as far as the regular message procedure for the Dialog.
                      Rgds, Dave

                      Comment


                      • #12
                        Thank You Dave

                        I think what was confusing me is that I was looking at another of Pierre's programs that subclass a couple of listboxs. In that program it captures the WM_CHAR message. Still it subclasses the listbox not the dialog which would be the listboxs parent. In my program I am subclassing the parent where Pierre is subclassing the control. It makes sense but then again it doesn't. Im sure some day the concept will make sense.

                        This is what the final code looks like, of course comments are welcome.
                        Code:
                        CALLBACK FUNCTION ListviewSubclass() AS LONG
                          LOCAL pNMH AS NMHEADER PTR
                        
                          'if the divider bar between header columns is double clicked we want to
                          'eat that message and send a fit header message to size the column to the
                          'header not the data.
                        
                          SELECT CASE CB.NMCODE
                          CASE %HDN_DIVIDERDBLCLICKA, %HDN_DIVIDERDBLCLICKW
                            pNMH = CB.LPARAM
                            ListView_FitHeader(hListview, @pNMH.iItem)
                            EXIT FUNCTION
                          END SELECT
                        
                          FUNCTION = CallWindowProc(OldLvProc, CB.HNDL, CB.MSG, CB.WPARAM, CB.LPARAM)
                        END FUNCTION

                        Comment


                        • #13
                          Frank,
                          That looks fine or you could handle it in you main callback by utilizing the %WM_NOTIFY and pick up the %HDN_DIVIDERDBLCLICK under pNmHdrCD where pNmHdrCD is NMCUSTOMDRAW PTR.

                          Like this with the Header handle via subroutine called by %WM_NOTIFY:
                          Code:
                          '_________________________________________________________________
                          '
                          '   SUB NotifyCommand Process
                          '_________________________________________________________________
                          
                          SUB NotifyCommand(BYVAL wParamX AS LONG, BYVAL lParamX AS LONG)
                          
                            LOCAL pNmHdrCD                 AS NMCUSTOMDRAW PTR
                          
                            pNmHdrCD = lParamX    'for CustomDraw LV Header  NMCUSTOMDRAW
                          
                            IF @pNmHdrCD.hdr.hwndFrom = hListViewHeader THEN 'Message from listview header
                          
                                SELECT CASE @pNmHdrCD.hdr.code
                                    CASE %HDN_DIVIDERDBLCLICK
                                        SendMessageA(hListView, %LVM_SETCOLUMNWIDTH, 0, %LVSCW_AUTOSIZE_USEHEADER)
                                        SendMessageA(hListView, %LVM_SETCOLUMNWIDTH, 1, %LVSCW_AUTOSIZE_USEHEADER)
                                        'add the rest of the columns you have here...
                                END SELECT
                            END IF
                          END SUB
                          No need to subclass.

                          Comment


                          • #14
                            Hi Jim,

                            I want to subclass the control to catch and ignore the default processing. If I don't, the column changes to the size of the data and then changes to the size of the header. The double resize is annoying to me.

                            Frank

                            Comment


                            • #15
                              Yes Frank,
                              I have seen that same behavior before which caused me to disable the divider. Thanks for your method.

                              Comment

                              Working...
                              X