Announcement

Collapse
No announcement yet.

Control gets old clicks when enabled -flush buffer?

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

  • Michael Mattias
    replied
    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

    Leave a comment:


  • Mike Doty
    replied
    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, 09:23 AM.

    Leave a comment:


  • Michael Mattias
    replied
    Amazing just how much you can figure out when sufficient code is posted, huh?

    Leave a comment:


  • Michael Mattias
    replied
    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

    Leave a comment:


  • Michael Mattias
    replied
    Code:
    CASE %IDC_BUTTON1
                        IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
    [COLOR="Red"]                        CONTROL DISABLE CBHNDL, %IDC_BUTTON1
                            CALL DisplayRecordSet(CBHNDL)
                            BEEP
                            CONTROL ENABLE CBHNDL, %IDC_BUTTON1[/COLOR]
                        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

    Leave a comment:


  • Mike Doty
    replied
    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

    Leave a comment:


  • Mike Doty
    replied
    I'll try to work up another example without a listview to see if I can duplicate it.

    Leave a comment:


  • Mike Doty
    replied
    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, 06:34 PM.

    Leave a comment:


  • Michael Mattias
    replied
    That should not be occurring... a disabled control does not send WM_COMMAND and AFAIK sends exactly nothing.

    Show failing code.

    Leave a comment:


  • Mike Doty
    started a topic Control gets old clicks when enabled -flush buffer?

    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?
Working...
X