Announcement

Collapse
No announcement yet.

Control gets old clicks when enabled -flush buffer?

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

  • Control gets old clicks when enabled -flush buffer?

    CONTROL DISABLE CBHNDL, %IDC_EXECUTE
    How do you flush the mouse buffer so if someone clicks on a disabled button control it isn't executed as soon as the button is enabled?
    Is there a flush mouse buffer command?
    How long is an idea?

  • #2
    That should not be occurring... a disabled control does not send WM_COMMAND and AFAIK sends exactly nothing.

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

    Comment


    • #3
      DOEVENTS fixes the problem, but not sure why needed.

      The DOEVENTS loop keeps extra keystrokes from executing the button
      when it is enabled and also gets the first page of the LISTVIEW
      to display immediately.
      'First page displays immediately and extra keystrokes not accepted if this is used
      FOR x = 1 TO 4IALOG DOEVENTS:NEXT
      Without DOEVENTS it can be executed many times and first page doesn't appear until done.
      %IDC_LISTVIEW = 2001 'listview
      %IDC_EXECUTE = 4007 'button

      'This has turned into a pretty nice listview
      '
      Code:
      FUNCTION DisplayRecordSet(hDlg AS DWORD) AS DWORD
        CONTROL DISABLE hDlg, %IDC_EXECUTE 'actually caller does this
        LOCAL row AS DWORD, col AS LONG, ColumnCount AS LONG
       
        LOCAL x AS LONG
       
        ColumnCount = slGetColumnCount
        IF ColumnCount THEN
          MOUSEPTR 11
          'CONTROL SHOW STATE hDlg, %IDC_LISTVIEW, %SW_HIDE
       
          LISTVIEW RESET hDLG, %IDC_LISTVIEW
          LISTVIEW SET STYLE hDlg, %IDC_LISTVIEW, %LVS_EX_GRIDLINES
          FOR col = 1 TO ColumnCount   'Insert columns with column names
            LISTVIEW DELETE COLUMN hDlg, %IDC_LISTVIEW,col
            LISTVIEW INSERT COLUMN hDlg, %IDC_LISTVIEW,col,slGetColumnName(col),100,0
          NEXT
        ELSE
          ? "No columns"
          EXIT FUNCTION
        END IF
       
        DO WHILE slGetRow
          INCR row
          LISTVIEW INSERT ITEM hDlg, %IDC_LISTVIEW,row, 0 , slF(1) 'Insert row, 0=no image
          FOR col = 2 TO ColumnCount                               'add text into columns
            LISTVIEW SET TEXT hdlg, %IDC_LISTVIEW, row, col,slF(col)
          NEXT
       
          IF row = 100 OR row MOD 1000 = 0  THEN          'refresh screen every so often
            '
            'First page displays immediately and extra keystrokes not accepted if this is used
            FOR x = 1 TO 4
              DIALOG DOEVENTS
              Message hDlg, "Records for far" + STR$(row)
             NEXT
          '
          END IF
        LOOP
        CONTROL SHOW STATE hdlg, %IDC_LISTVIEW, %SW_HIDE
        FOR col = 1 TO ColumnCount   'fit columns
          LISTVIEW FIT CONTENT hDlg, %IDC_LISTVIEW, col
        NEXT
        CONTROL SHOW STATE hDlg, %IDC_LISTVIEW, %SW_SHOW
       
        MOUSEPTR 1
        FUNCTION = row
       
      END FUNCTION
      Last edited by Mike Doty; 13 Oct 2008, 07:34 PM.
      How long is an idea?

      Comment


      • #4
        I'll try to work up another example without a listview to see if I can duplicate it.
        How long is an idea?

        Comment


        • #5
          Buffered mouse clicks?

          'Click button quickly after being disabled.
          'It appears clicks are buffered.
          Code:
          #PBFORMS CREATED V1.51
          '------------------------------------------------------------------------------
          #COMPILE EXE
          #DIM ALL
          'Created using PBWIN9
          '------------------------------------------------------------------------------
          '   ** Includes **
          '------------------------------------------------------------------------------
          #PBFORMS BEGIN INCLUDES
          %USEMACROS = 1
          #IF NOT %DEF(%WINAPI)
              #INCLUDE "WIN32API.INC"
          #ENDIF
          #IF NOT %DEF(%COMMCTRL_INC)
              #INCLUDE "COMMCTRL.INC"
          #ENDIF
          #INCLUDE "PBForms.INC"
          #PBFORMS END INCLUDES
          '------------------------------------------------------------------------------
          '------------------------------------------------------------------------------
          '   ** Constants **
          '------------------------------------------------------------------------------
          #PBFORMS BEGIN CONSTANTS
          %IDD_DIALOG1  =  101
          %IDC_BUTTON1  = 1001
          %IDC_LISTVIEW = 1002
          #PBFORMS END CONSTANTS
          '------------------------------------------------------------------------------
          '------------------------------------------------------------------------------
          '   ** Declarations **
          '------------------------------------------------------------------------------
          DECLARE CALLBACK FUNCTION ShowDIALOG1Proc()
          DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
          #PBFORMS DECLARATIONS
          '------------------------------------------------------------------------------
          '------------------------------------------------------------------------------
          '   ** Main Application Entry Point **
          '------------------------------------------------------------------------------
          FUNCTION PBMAIN()
              PBFormsInitComCtls (%ICC_WIN95_CLASSES OR %ICC_DATE_CLASSES OR %ICC_INTERNET_CLASSES)
              ShowDIALOG1 %HWND_DESKTOP
          END FUNCTION
          '------------------------------------------------------------------------------
          '------------------------------------------------------------------------------
          '   ** CallBacks **
          '------------------------------------------------------------------------------
          CALLBACK FUNCTION ShowDIALOG1Proc()
              SELECT CASE AS LONG CBMSG
                  CASE %WM_INITDIALOG
                      ' Initialization handler
                  CASE %WM_NCACTIVATE
                      STATIC hWndSaveFocus AS DWORD
                      IF ISFALSE CBWPARAM THEN
                          ' Save control focus
                          hWndSaveFocus = GetFocus()
                      ELSEIF hWndSaveFocus THEN
                          ' Restore control focus
                          SetFocus(hWndSaveFocus)
                          hWndSaveFocus = 0
                      END IF
                  CASE %WM_COMMAND
                      ' Process control notifications
                      SELECT CASE AS LONG CBCTL
          
                          CASE %IDC_BUTTON1
                              IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                                  CONTROL DISABLE CBHNDL, %IDC_BUTTON1
                                  CALL DisplayRecordSet(CBHNDL)
                                  BEEP
                                  CONTROL ENABLE CBHNDL, %IDC_BUTTON1
                              END IF
                      END SELECT
              END SELECT
          END FUNCTION
          '------------------------------------------------------------------------------
          '------------------------------------------------------------------------------
          '   ** Dialogs **
          '------------------------------------------------------------------------------
          FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
              LOCAL lRslt AS LONG
          #PBFORMS BEGIN DIALOG %IDD_DIALOG1->->
              LOCAL hDlg  AS DWORD
              DIALOG NEW hParent, "Dialog1", 25, 52, 527, 305, %WS_POPUP OR %WS_BORDER _
                  OR %WS_DLGFRAME OR %WS_SYSMENU OR %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX _
                  OR %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK _
                  OR %DS_NOFAILCREATE OR %DS_SETFONT, %WS_EX_CONTROLPARENT OR _
                  %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg
              CONTROL ADD BUTTON, hDlg, %IDC_BUTTON1, "Button1", 245, 30, 50, 15
              CONTROL ADD "SysListView32", hDlg, %IDC_LISTVIEW, "SysListView32_1", 80, _
                  95, 400, 145, %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %LVS_REPORT _
                  OR %LVS_SHOWSELALWAYS, %WS_EX_LEFT OR %WS_EX_CLIENTEDGE OR _
                  %WS_EX_RIGHTSCROLLBAR
          #PBFORMS END DIALOG
              DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
          #PBFORMS BEGIN CLEANUP %IDD_DIALOG1
          #PBFORMS END CLEANUP
              FUNCTION = lRslt
          END FUNCTION
          '------------------------------------------------------------------------------
          
          FUNCTION DisplayRecordSet(hDlg AS DWORD) AS DWORD
            LOCAL row AS DWORD, col AS LONG, ColumnCount AS LONG
            LOCAL x AS LONG, rows AS LONG
            'so you know it was called
          
              ColumnCount = 13
              rows = 10000
            IF ColumnCount THEN
              MOUSEPTR 11
              'CONTROL SHOW STATE hDlg, %IDC_LISTVIEW, %SW_HIDE
              LISTVIEW RESET hDLG, %IDC_LISTVIEW
              LISTVIEW SET STYLE hDlg, %IDC_LISTVIEW, %LVS_EX_GRIDLINES
              FOR col = 1 TO ColumnCount   'Insert columns with column names
                LISTVIEW DELETE COLUMN hDlg, %IDC_LISTVIEW,col
                LISTVIEW INSERT COLUMN hDlg, %IDC_LISTVIEW,col,"Col" + STR$(col),100,0
              NEXT
            ELSE
              ? "No columns"
              EXIT FUNCTION
            END IF
            row = 0
            DO WHILE row < rows
              INCR row
              LISTVIEW INSERT ITEM hDlg, %IDC_LISTVIEW,row, 0 , "ROW" + STR$(row) + " COLUMN 1"
              FOR col = 2 TO ColumnCount                               'add text into columns
                LISTVIEW SET TEXT hdlg, %IDC_LISTVIEW, row, col,"COLUMN" + STR$(col)
              NEXT
              'This fixes problem
              'IF row = 100 OR row MOD 1000 = 0  THEN          'refresh screen every so often
              '  FOR x = 1 TO 4
              '    DIALOG DOEVENTS
              '   NEXT
              'END IF
            LOOP
           ' CONTROL SHOW STATE hdlg, %IDC_LISTVIEW, %SW_HIDE
           ' FOR col = 1 TO ColumnCount   'fit columns
           '   LISTVIEW FIT CONTENT hDlg, %IDC_LISTVIEW, col
           ' NEXT
            'CONTROL SHOW STATE hDlg, %IDC_LISTVIEW, %SW_SHOW
            'DIALOG DOEVENTS
            'MOUSEPTR 1
            FUNCTION = row
          END FUNCTION
          How long is an idea?

          Comment


          • #6
            Code:
            CASE %IDC_BUTTON1
                                IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                                    CONTROL DISABLE CBHNDL, %IDC_BUTTON1
                                    CALL DisplayRecordSet(CBHNDL)
                                    BEEP
                                    CONTROL ENABLE CBHNDL, %IDC_BUTTON1
                                END IF
            The reason users are clicking on this button twice (or more?) is because the DisplayRecordSet() function is taking "too long" for them; and yes, those 'clicks' will queue up as described if the control is not disabled, so disabling is required..... unless.......

            You can disparage users from clicking again either showing the "WAIT" cursor or by running the 'displayrecordset' function as a "background" task in a separate thread of execution. See GUI + Worker Thread + Abort Demo 11-24-07. Disable the button, start the worker thread function, and re-enable the button when the thread function completes and posts the PWM_THREAD_COMPLETE message back to your dialog procedure.

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

            Comment


            • #7
              That you are doing the "displayrecordset" during the processing of a notification message (WM_COMMAND) is also why your screen does not update until everything is done unless you insert DIALOG DOEVENTS statements. (the calling thread processes additional notification messages,e.g. "update this control")

              By performing the 'display' from a separate thread of execution, this problem automatically goes away.

              If you are in fact catering to thousands of records (the 'MOD 1000' in the code suggests this), the famous "1/10 second" rule is almost certainly being broken.

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

              Comment


              • #8
                Amazing just how much you can figure out when sufficient code is posted, huh?
                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]
                http://www.talsystems.com

                Comment


                • #9
                  Separate thread coming soon.
                  The record sets could be huge and will soon be done using a virtual grid.
                  Filling the listview takes much longer than getting the data. I also
                  need to write some code to fill a disk file instead of memory when using SQLitening to return some record sets.

                  Also, the delete columns method used above is wrong and will be corrected.
                  Last edited by Mike Doty; 14 Oct 2008, 10:23 AM.
                  How long is an idea?

                  Comment


                  • #10
                    The record sets could be huge and will soon be done using a virtual grid
                    The Listview control using style LVS_OWNERDATA (virtual) can make your code really, really fast. I used this in the EDI Pal(tm) ANSI ASC X12 Viewer-Editor-Printer to correct user complaints about a control "loads too slow." (And it did - it was really pretty crummy).

                    (My "torture" test file results in 1.1 million rows).


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

                    Comment

                    Working...
                    X