If you want to add Multiselect functionality to a grid that emulates Windows Explorer behaviour, try the following:-
Subclass a grid into a suitable class library.
Add 4 new properties to the class,
[color blue].lMultiSelect[/color] with value of .F.
[color blue].nActiveRow[/color] with value of 0
[color blue].nLastRow[/color] with value of 0
[color blue].nRecs2Change[/color] with value of 0
and 1 new method
[color blue].mSelectRecords()[/color]
Ensure the [color blue].RecordSource[/color] of the grid is not indexed, so create it from a SELECT - SQL statement. The [color blue].RecordSource[/color] also requires an additional logical field, [color blue]selected[/color].
In the [color blue].AfterRowColChange()[/color] event of the grid, put
[color blue]THIS.mSelectRecords()[/color]
In the [color blue].mSelectRecords()[/color] event of the grid, put
[color blue]
LOCAL lcSelected,;
lcRecordSource
#DEFINE VK_lSHIFT 0x10 [/color][color green]&& Relocate to a header file[/color][color blue]
#DEFINE VK_lCONTROL 0x11 [/color][color green]&& Relocate to a header file[/color][color blue]
DECLARE INTEGER GetKeyState IN WIN32API INTEGER[/color][color green] && Relocate to where WinAPI calls are declared[/color]
[color blue]
WITH THIS
.nActiveRow = .ActiveRow[/color][color green] && Assign value to class property[/color][color blue]
lcSelected = .RecordSource + [.selected][/color][color green] && Assign value to local variable[/color][color blue]
lcRecordSource = .RecordSource[/color][color green] && Assign value to local variable[/color][color blue]
DO CASE
CASE GetKeyState(VK_lSHIFT) < 0 ;
OR GetKeyState(VK_lSHIFT) > 1[/color][color green] && Check for shift key press[/color][color blue]
DO CASE
CASE .nLastRow > .nActiveRow[/color][color green] && Last recd below current recd in grid[/color][color blue]
.nRecs2Change = .nLastRow - .nActiveRow[/color][color green] && Calculate no of recds to change[/color][color blue]
REPLACE (lcSelected) WITH .T. IN (lcRecordSource)[/color][color green] && Replace current recd[/color][color blue]
FOR i = 1 TO .nRecs2Change
REPLACE (lcSelected) WITH .T. IN (lcRecordSource)
SKIP IN (lcRecordSource)
ENDF
CASE .nLastRow < .nActiveRow[/color][color green] && Last recd above current recd in grid[/color][color blue]
.nRecs2Change = .nActiveRow - .nLastRow[/color][color green] && Calculate no of recds to change[/color][color blue]
REPLACE (lcSelected) WITH .T. IN (lcRecordSource)[/color][color green] && Replace current recd[/color][color blue]
GO .nLastRow IN (lcRecordSource)[/color][color green] && Goto the last recd[/color][color blue]
FOR i = 1 TO .nRecs2Change
REPLACE (lcSelected) WITH .T. IN (lcRecordSource)
SKIP IN (lcRecordSource)
ENDF
ENDC
.lMultiSelect = .T.
CASE GetKeyState(VK_lCONTROL) < 0 ;
OR GetKeyState(VK_lCONTROL) > 1[/color][color green] && Check for control key press[/color][color blue]
REPLACE (lcSelected) WITH .T. IN (lcRecordSource)
.lMultiSelect = .T.
OTHERWISE[/color][color green] && Neither shift or ctrl pressed[/color][color blue]
DO CASE
CASE .lMultiSelect
REPLACE (lcSelected) WITH .F. ;
ALL IN (lcRecordSource)[/color][color green] && Update all recds[/color][color blue]
CASE .nLastRow # 0
TRY
GO .nLastRow IN (lcRecordSource)
CATCH
GO BOTTOM IN (lcRecordSource)
ENDTRY
REPLACE (lcSelected) WITH .F. IN (lcRecordSource)
ENDCASE
GO .nActiveRow IN (lcRecordSource)[/color][color green] && Change new value[/color][color blue]
REPLACE (lcSelected) WITH .T. IN (lcRecordSource)
.lMultiSelect = .F.
ENDC
IF RECCOUNT(lcRecordSource) > 0
DO CASE[/color][color green] && Set colours according to OS[/color][color blue]
CASE UPPER(OS(1)) = [WINDOWS 5.00][/color][color green] && Win 2K[/color][color blue]
.SetAll([DynamicBackColor] ,;
"IIF(&lcSelected ,;
RGB(10,36,106) ,;
RGB(255,255,255))" ,;
[Column])
CASE UPPER(OS(1)) = [WINDOWS 5.01][/color][color green] && Win XP[/color][color blue]
.SetAll([DynamicBackColor] ,;
"IIF(&lcSelected ,;
RGB(49,106,197) ,;
RGB(255,255,255))" ,;
[Column])
CASE UPPER(OS(1)) = [WINDOWS 6.00][/color][color green] && Vista[/color][color blue]
.SetAll([DynamicBackColor] ,;
"IIF(&lcSelected ,;
RGB(51,153,255) ,;
RGB(255,255,255))" ,;
[Column])
CASE UPPER(OS(1)) = [WINDOWS 6.01][/color][color green] && Windows 7[/color][color blue]
.SetAll([DynamicBackColor] ,;
"IIF(&lcSelected ,;
RGB(51,153,255) ,;
RGB(255,255,255))" ,;
[Column])
ENDCASE
.SetAll([DynamicForeColor] ,;[/color][color green] && All OS[/color][color blue]
"IIF(&lcSelected ,;
RGB(255,255,255) ,;
RGB(0,0,0))" ,;
[Column])
.nLastRow = .nActiveRow [/color][color green]&& Mark current row for next time through[/color]
[color blue] ENDIF
ENDWITH[/color]
*!* *!* *!* *!* *!* *!* *!* *!* *!* *!* *!*
Left mouse click will select the current record only, shift + click followed by shift + click will select a block of records, and ctrl + click will select individual records, all selected records being highlighted.
Scrolling with the arrow keys does not select records.
You can programatically determine if there are multiple selected records with:-
[color blue]
IF THISFORM.grid1.lMultiSelect[/color]
[color green] *!* Code[/color][color blue]
ENDI
[/color]
You now have a scope clause available for copying, printing, deleting etc, expressed as:-
[color blue]
REPORT FORM reportname.frx FOR CURSORNAME.selected
[/color]
Have fun
FAQ184-2483 - answering getting answered.
Chris
![[pc2] [pc2] [pc2]](/data/assets/smilies/pc2.gif)
[link http://www.pdfcommander.com]PDFcommander.com[/link]
[link http://www.pdfcommander.co.uk]PDFcommander.co.uk[/link]