/////////////////////////////////////////////////////////// // Object : DataWindow control // Method : Clicked!, MouseMove! & LButtonUp! events // Author : PowerObject! [Shekar C. Reddy] // Date : 4/14/2003 /////////////////////////////////////////////////////////// // Desc : Auto-Select rows in a dw by DRAGGING the mouse! /////////////////////////////////////////////////////////// // http://Groups.Yahoo.com/group/PowerObject/message/2842 // http://Groups.Yahoo.com/group/PowerObject/message/2825 /////////////////////////////////////////////////////////// I've tried this and the only way to do it in a FOOL-PROOF way is to code as under. I am saying "fool-proof" way because there are some issues with PBM_DWNMouseMove!. If we move/drag the mouse quickly, some rows do NOT get selected leaving some GAPS in the dragged range of rows if we have to select row-by-row as the user drags them!! So, the only way to ALWAYS select all the drag-selected rows is to select the "range" of dragged rows (Drag-Range!). This allows the user to drag-select rows as quickly as (s)he possibly can - WITHOUT any gaps in between: /////////////////////////////////////////////////////////// // dw Instance var /////////////////////////////////////////////////////////// long il_StartRow, il_PreviousRow /////////////////////////////////////////////////////////// // dw.Clicked! event /////////////////////////////////////////////////////////// IF row > 0 THEN This.SelectRow( 0, FALSE ) This.SelectRow( row, TRUE ) il_StartRow = row // Start the Drag-Selection mode END IF /////////////////////////////////////////////////////////// // dw.MouseMove! event (PBM_DWNMouseMove) /////////////////////////////////////////////////////////// long ll_Row, ll_EndRow // IF row <= 0 THEN // Not over a valid row RETURN END IF // IF il_StartRow <= 0 THEN // Row-Selection not initiated, yet RETURN END IF // IF il_PreviousRow = row THEN // MouseMove! on the same/previous row RETURN END IF // IF NOT KeyDown( KeyLeftButton! ) THEN // LMB not depressed - Not in Drag-Select mode RETURN END IF // This.SetRedraw( FALSE ) // Supress rendering // This.ScrollToRow( row ) // If you must scroll, do it right HERE! This.SelectRow( 0, FALSE ) // Unselect all rows, first!! // // The STEP-clause in PowerBuilder does NOT take a "var" for its value!!! // Determine the range of dragged rows (Drag-Range) IF il_StartRow < row THEN // Drag-Selection downwards ll_Row = il_StartRow // Start row to select ll_EndRow = row // End row to select ELSE // Drag-Selection upwards ll_Row = row // Start row to select ll_EndRow = il_StartRow // End row to select END IF // // Select the range of dragged rows (Drag-Range) FOR ll_Row = ll_Row TO ll_EndRow This.SelectRow( ll_Row, TRUE ) NEXT // This.SetRedraw( TRUE ) // Enable rendering // // Update the PreviousRow il_PreviousRow = row /////////////////////////////////////////////////////////// // dw.LButtonUp! event (PBM_DWNLButtonUp) /////////////////////////////////////////////////////////// il_StartRow = 0 // Stop the Drag-Selection mode il_PreviousRow = 0 // Init! HOW IT WORKS ------------ If we take a dw of 10 rows with the 5th row as the il_StartRow, the above code works as under (always selecting in a "top-to-bottom" direction without using the STEP clause of the FOR-NEXT: Drag-Select downwards to row 8: Select rows from 5-8 Drag-Select upwards to row 2: Select rows from 2-5 Thanks to SetRedraw(), the user does NOT notice the un-natural direction of row-selection (when the rows are drag-selected UPWARDS), which is done to eliminate redundant code. If desired, you may implement row- selection in a natural direction with one FOR-NEXT loop for each direction. Further, The code in the MouseMove! does not execute if the mouse is moved on the SAME/PREVIOUS row reducing redundant execution. By the way, have you noticed as of PowerBuilder 6.5, there is no PBM_DWNLButtonDown! event for a dw unlike the PBM_DWNLButtonUp! ? It is PBM_LButtonDown!. Further, have you taken a look at the If() PowerScript Expression function yet? http://groups.yahoo.com/group/PowerObject/files/PowerScript/If%28%29%20PowerScript-Function.txt /////////////////////////////////////////////////////////// GLOBAL FUNCTION any f_If( readOnly boolean ab_Expression, & readOnly any aa_TrueValue, readOnly any aa_FalseValue ) /////////////////////////////////////////////////////////// // Retuns NULL if ab_Expression is NULL - PowerObject! /////////////////////////////////////////////////////////// // Do NOT "recurse" f_If() here!! :~) - PowerObject! any la_Null ; // IF IsNull( ab_Expression ) THEN // Error SetNull( la_Null ) ; RETURN la_Null ; ELSEIF ab_Expression THEN RETURN aa_TrueValue ; END IF ; // RETURN aa_FalseValue ; Using the f_If() function, the above code ----------------------------------------- IF il_StartRow < row THEN // Drag-Selection downwards ll_Row = il_StartRow // Start row to select ll_EndRow = row // End row to select ELSE // Drag-Selection upwards ll_Row = row // Start row to select ll_EndRow = il_StartRow // End row to select END IF can be REDUCED to ----------------- ll_Row = f_If( il_StartRow < row, il_StartRow, row ) ll_EndRow = f_If( il_StartRow < row, row, il_StartRow ) Regards, --- PowerObject!