Function to browse arrays

General Help regarding HMG, Compilation, Linking, Samples

Moderator: Rathinagiri

PeteWG
Posts: 138
Joined: Sun Mar 21, 2010 5:45 pm
Has thanked: 11 times
Been thanked: 39 times

Function to browse arrays

Post by PeteWG » Tue Mar 26, 2019 11:44 am

Hi all,

I'm looking for a "lean 'n elegant" yet capable function that browses an array in a grid and returns the number of row selected
(i.e. the last value of grid), something like `Function ABrowse( array ) --> nValue`

Ideally, the function must be able to handle arrays with two dimensions. (edit: and also one-dimensional!)
Also it should be made "as simple as possible and even simpler" ;) , i.e. without "_HMG_ ...[ 999 ]"
internals and suchlike "hacks", that besides being non-programmer-friendly, are not portable
between the two hmg variants.

It'd be great, if somebody has implemented something similar and would like to share his (master)work.

Note: I 'm aware of hmg_achoice() available in hmg extended. It's ok (and lean),
but support one-dimensional arrays only, so not suitable for the purpose!

PS: well, I know I could make such a function, but always I'm amazed to see the "miracles", some shining minds here, are able to create. :)

regards,
Pete

User avatar
dragancesu
Posts: 638
Joined: Mon Jun 24, 2013 11:53 am
DBs Used: DBF, MySQL, Oracle
Location: Subotica, Serbia
Has thanked: 19 times
Been thanked: 125 times

Post by dragancesu » Tue Mar 26, 2019 12:38 pm

GRID ?

PeteWG
Posts: 138
Joined: Sun Mar 21, 2010 5:45 pm
Has thanked: 11 times
Been thanked: 39 times

Post by PeteWG » Tue Mar 26, 2019 1:37 pm

:? GRID what?

User avatar
andyglezl
Posts: 1113
Joined: Fri Oct 26, 2012 7:58 pm
Location: Guadalajara Jalisco, MX
Has thanked: 32 times
Been thanked: 65 times
Contact:

Post by andyglezl » Tue Mar 26, 2019 2:18 pm

"and returns the number of row selected (i.e. the last value of grid)"
something like "Function ABrowse( array ) --> nValue"
Hola Pete

Con la traduccion de google, no me queda clara tu pregunta...

Para mi, nValue serían 2 valores diferentes:

nValue := returns the number of row selected
nValue := the last value of grid

Y en este caso, el array puede ser unidimencional ó multidimencional ya que se trata de filas.

Podrías ampliar un poco mas el dato ?
O tendrás un ejemplo (con funciones HMG)
*------------------------------------------------------------------------------------------------------------------
Hello Pete

With the translation of google, your question is not clear to me ...

For me, nValue would be 2 different values:

nValue: = returns the number of row selected
nValue: = the last value of grid

And in this case, the array can be unidimentional or multidimensional since it is rows.

Could you expand the data a little more?
Or you'll have an example (with HMG functions)
Andrés González López
Desde Guadalajara, Jalisco. México.

User avatar
serge_girard
Posts: 2235
Joined: Sun Nov 25, 2012 2:44 pm
DBs Used: 1 MySQL - MariaDB
2 DBF
Location: Belgium
Has thanked: 518 times
Been thanked: 111 times
Contact:

Post by serge_girard » Tue Mar 26, 2019 2:58 pm

Pete,

IMO grid is most suitable:

Code: Select all

// fill your array within a loop or someting             

aGRID := {}
AADD(aGRID, { cFLD1 , cFLD2, cFLD3, cFLDn } )


// grid
    ...
      ON DBLCLICK Edit_grid();
              
// fill the grid
FOR A = 1 TO LEN(aGRID)
     IF !EMPTY(aGRID [A] [1]) 
        ADD ITEM aGRID [A] TO Grid_1 OF Form_1
     ENDIF
NEXT A


FUNCTION edit_grid()
KEY := Column_Value( "Grid_1" ,  "Form_1" , 1 ) // last parameter is key
// KEY is the value you will need
// rest of function
return


FUNCTION Column_Value( ControlName, ParentForm , nCol )
/******************************************************/
LOCAL aRet := {}
nCol := Iif( nCol == Nil .Or. nCol == 0 , 1 , nCol )
aRet := GetProperty (  ParentForm  , ControlName , 'Item' , GetProperty( ParentForm , ControlName , 'Value' ) )
RETURN( aRet [ nCol ] )	

If you need multiselect then things change a bit. Let me know if you can go further with this solution!

Serge

edk
Posts: 439
Joined: Thu Oct 16, 2014 11:35 am
Location: Poland
Has thanked: 127 times
Been thanked: 361 times

Post by edk » Tue Mar 26, 2019 3:07 pm

Is this something like that?

Code: Select all

#include "hmg.ch"

Function Main
Local i, xSel
Local aMultiArray:={1 , 2 , 'string' , Nil , { 5, 55, 555 }, .T. , { 7 ,  { '7a' , '7b' ,  { '7c' ,  {  77.77 , 777.777 } } } , 777 } , 8 }
Local aSingleArray:={1,2,3,4,5,6,7,8,9}
Local xNOTArray:= 1
Local aEmptyArray:={}
Local aTwoDimArray:=Array(10,10)

FOR i = 1 TO LEN( aTwoDimArray )
	FOR j = 1 TO LEN( aTwoDimArray [i] )
		aTwoDimArray [i][j] := ((i - 1) * 10) + j - 1
	NEXT j
NEXT i


DEFINE WINDOW Form_1 ;
	AT 0,0 ;
	WIDTH 450 ;
	HEIGHT 400 ;
	TITLE 'Hello' ;
	MAIN 

	DEFINE MAIN MENU
		DEFINE POPUP 'Matrix Browse'
			MENUITEM 'Single' ACTION ( xSel := MatrixBrowse( aSingleArray ), MsgBox ('Selected value ' + hb_valToStr( xSel )) )
			MENUITEM 'Two-dimensional array' ACTION ( xSel := MatrixBrowse( aTwoDimArray ), MsgBox ('Selected value ' + hb_valToStr( xSel )) )
			MENUITEM 'Multi-dimensional array' ACTION ( xSel := MatrixBrowse( aMultiArray ), MsgBox ('Selected value ' + hb_valToStr( xSel )) )
			MENUITEM 'Empty array' ACTION ( xSel := MatrixBrowse( aEmptyArray ), MsgBox ('Selected value ' + hb_valToStr( xSel )) )
			MENUITEM 'Not an Array' ACTION ( xSel := MatrixBrowse( xNOTArray ), MsgBox ('Selected value ' + hb_valToStr( xSel )) )
		END POPUP
	END MENU

END WINDOW

CENTER WINDOW Form_1

ACTIVATE WINDOW Form_1

Return

*******************************************************************************
Function MatrixBrowse ( aAnyArray )
Local nItems, aColumns, cFormName
Local nFormNo := 1
Public _xMatrixValue

IF .NOT. HB_isArray( aAnyArray )
	MsgStop ("The variable is not an array.")
	RETURN 
ENDIF

nItems := 1
FOR EACH _xMatrixValue IN aAnyArray
	IF hb_isArray( _xMatrixValue )
		nItems := MAX ( nItems, LEN( _xMatrixValue ) )  
	ENDIF
NEXT

_xMatrixValue := Nil

aColumns := Array ( nItems )
AEval( aColumns, { | x, y | aColumns [ y ] := "Column " + Alltrim(Str( y )) })

DO WHILE .T.
	cFormName := "_MatrixForm_" + Alltrim( Str ( nFormNo ) )
	IF !_IsWindowDefined ( cFormName )
		EXIT
	ENDIF
	nFormNo ++
ENDDO

DEFINE WINDOW &cFormName ;
	AT 0,0 ;
	WIDTH nItems * 100 + 50 ;
	HEIGHT MIN ( LEN( aAnyArray ) * 25 + 100, GetDesktopHeight() ) ;
	TITLE 'Matrix browse #' + Alltrim( Str ( nFormNo ) ) ;
	MODAL

	@ 5,5 GRID Grid_1 ;
	WIDTH nItems * 100 + 20 ;
	HEIGHT MIN ( LEN( aAnyArray ) * 25 + 20, GetDesktopHeight() - 80) ;
	HEADERS aColumns ;
	WIDTHS AFill ( Array (nItems), 100 );
	DYNAMICFORECOLOR AFill ( Array (nItems), { || if ( hb_isString(This.CellValue) .AND. This.CellValue = "{ SubArray }" , RED, BLACK )  } ) ;
	VIRTUAL ;
	ITEMCOUNT LEN( aAnyArray ) ;
	ON QUERYDATA QueryArray ( aAnyArray ) ;
	CELLNAVIGATION ;
	VALUE { 1, 1 } ;
	ON DBLCLICK OnKeyMatrixBrowse( aAnyArray, cFormName ) ;
	ON KEY OnKeyMatrixBrowse( aAnyArray, cFormName ) 
    
END WINDOW

CENTER WINDOW &cFormName

ACTIVATE WINDOW &cFormName

Return _xMatrixValue

*******************************************
Function OnKeyMatrixBrowse ( aArray, cFormName )
Local nRow := GetProperty(cFormName, 'Grid_1', 'CellRowFocused' )
Local nCol := GetProperty(cFormName, 'Grid_1', 'CellColFocused' )
Local lEnter := HMG_GetLastVirtualKeyDown() == VK_RETURN .OR. HMG_GetLastMouseMessage() == WM_LBUTTONDBLCLK
HMG_CleanLastVirtualKeyDown()
HMG_CleanLastMouseMessage()

IF lEnter
	IF GetProperty( cFormName, 'Grid_1', 'CellEx', nRow, nCol ) == '{ SubArray }'
		//show sub-Array
		MatrixBrowse( aArray [nRow] [nCol] )
	ELSE
		//Quit
		IF hb_isArray( aArray [nRow] )
			_xMatrixValue := aArray [nRow] [nCol]
		ELSEIF nCol == 1
			_xMatrixValue := aArray [nRow]
		ENDIF
		DoMethod (cFormName, 'Release')
	ENDIF
ENDIF
   
Return NIL
******************************************

Procedure QueryArray( aArray )
	
	IF !hb_isArray ( aArray [This.QueryRowIndex] )
	
		IF This.QueryColIndex == 1
			This.QueryData := hb_ValToStr( aArray [This.QueryRowIndex] )
		ELSE
			This.QueryData := ""
		ENDIF
		
	ELSEIF hb_isArray ( aArray [This.QueryRowIndex] [This.QueryColIndex] )
	
		This.QueryData := "{ SubArray }"
		
	ELSE	
	
		This.QueryData := hb_ValToStr( aArray [This.QueryRowIndex] [This.QueryColIndex] )
		
	ENDIF

Return

PeteWG
Posts: 138
Joined: Sun Mar 21, 2010 5:45 pm
Has thanked: 11 times
Been thanked: 39 times

Post by PeteWG » Tue Mar 26, 2019 6:03 pm

Hi guys,
thank you @(dragan, Andrés, Serge, edk) for your replies.

let me clarify a little the subject:

we have

Code: Select all

myarray := { {"ItemName", "ItemGroup" }, {"ItemName2", "ItemGroup2" }, {....} }
or

Code: Select all

myArray := { {"CustName",  2355.50 }, {"CustName",  9863.75}, {.....} }
or

Code: Select all

myArray := { { 29/02/2019, "xCode",  123 }, { 31/04/2019, "xCode2",  654}, { .... } } 
and then we do

Code: Select all

nVal := BrowseArray( myArray )
where nVal is either the row selected by user or zero if the dialog canceled.

Notes:
- sub-arrays can have one, two or more columns
- elements can be of any data type.

Now imagine a modal window with a cute grid and two buttons (OK, CANCEL)
User walk through rows, finds what he's looking for and press Ok button
(or double-clicks the row). That simple! (or not so much complicated, anyway).
Well, the whole thing has to be good-looking, e.g. the grid must be properly placed in a toolbox-style window,
grid columns must be content-fitted and headers can optionally specified. but these are cosmetics.
the most important: if possible, this brilliant function must be ready for use! :-)

@edk: your MatrixBrowse() is interesting. it coul serve as as good basis to create a really fine function.
problems I see:
- it needs adaptation to work with hmg extended
- this 'Multi-dimensional array' browse, although potentially useful, it doesn't seem to give expected result.

regards,
Pete

User avatar
dragancesu
Posts: 638
Joined: Mon Jun 24, 2013 11:53 am
DBs Used: DBF, MySQL, Oracle
Location: Subotica, Serbia
Has thanked: 19 times
Been thanked: 125 times

Post by dragancesu » Wed Mar 27, 2019 9:47 am

Hello Pete,

Maybe you need this, look at the example in the attachment

Program sbr_lov.prg contains the function for this lov_func () and lovs_func (), without and with string search
I use this to control data entry

This is a LOV - list of values
-----------------------------------------------------------
I liked Clipper, simple and powerful features
HMG and Windovs, it's a bit more complicated but better
And I needed time to get used to it
Attachments
budget.zip
(32.08 KiB) Downloaded 29 times

edk
Posts: 439
Joined: Thu Oct 16, 2014 11:35 am
Location: Poland
Has thanked: 127 times
Been thanked: 361 times

Post by edk » Wed Mar 27, 2019 1:03 pm

Here's the new version:
- multidimensional arrays browse has been improved
- option to hide column headers
- the size of the window and grid adapts to the size of array, it includes other ways of displaying the grid for different operating systems (tested on XP and Win10)
- works under HMG 3.4.4 and MiniGui 19.03
I added the ABrowse function (according to your guidelines).

Code: Select all


//#include "minigui.ch"

#include "hmg.ch"

Function Main
Local i, xSel
Local aMultiArray:={1 , 2 , 'string' , Nil , { 5, 55, 555 }, .T. , { 7 ,  { '7a' , '7b' ,  { '7c' ,  {  77.77 , 777.777 } } } , 777 } , 8 }
Local aSingleArray:={1,2,3,4,5,6,7,8,9}
Local xNOTArray:= 1
Local aEmptyArray:={}
Local aTwoDimArray:=Array(100,10)

FOR i = 1 TO LEN( aTwoDimArray )
	FOR j = 1 TO LEN( aTwoDimArray [i] )
		aTwoDimArray [i][j] := ((i - 1) * 10) + j - 1
	NEXT j
NEXT i


DEFINE WINDOW Form_1 ;
	AT 0,0 ;
	WIDTH 450 ;
	HEIGHT 400 ;
	TITLE 'Hello' ;
	MAIN 

	DEFINE MAIN MENU
		DEFINE POPUP 'Matrix Browse'
			MENUITEM 'One-dimensional array' ACTION ( xSel := MatrixBrowse( aSingleArray ), MsgBox ('Selected value ' + hb_valToStr( xSel )) )
			MENUITEM 'Two-dimensional array' ACTION ( xSel := MatrixBrowse( aTwoDimArray, .F. ), MsgBox ('Selected value ' + hb_valToStr( xSel )) )
			MENUITEM 'Multi-dimensional array' ACTION { || ( xSel := MatrixBrowse( aMultiArray ), MsgBox ('Selected value ' + hb_valToStr( xSel )) ) }
			MENUITEM 'Empty array' ACTION ( xSel := MatrixBrowse( aEmptyArray ), MsgBox ('Selected value ' + hb_valToStr( xSel )) )
			MENUITEM 'Not an Array' ACTION ( xSel := MatrixBrowse( xNOTArray ), MsgBox ('Selected value ' + hb_valToStr( xSel )) )
		END POPUP
		
		DEFINE POPUP 'ABrowse'
			MENUITEM 'One-dimensional array' ACTION ( xSel := ABrowse( aSingleArray ), MsgBox ('Selected row ' + hb_valToStr( xSel )) )
			MENUITEM 'Two-dimensional array' ACTION ( xSel := ABrowse( aTwoDimArray, .F. ), MsgBox ('Selected row ' + hb_valToStr( xSel )) )
			MENUITEM 'Multi-dimensional array' ACTION { || ( xSel := ABrowse( aMultiArray ), MsgBox ('Selected row ' + hb_valToStr( xSel )) ) }
			MENUITEM 'Empty array' ACTION ( xSel := ABrowse( aEmptyArray ), MsgBox ('Selected row ' + hb_valToStr( xSel )) )
			MENUITEM 'Not an Array' ACTION ( xSel := ABrowse( xNOTArray ), MsgBox ('Selected row ' + hb_valToStr( xSel )) )
		END POPUP
		
	END MENU

END WINDOW

CENTER WINDOW Form_1

ACTIVATE WINDOW Form_1

Return

*******************************************************************************
Function MatrixBrowse ( aAnyArray , lHeader )
Local nItems, aColumns, cFormName
Local nFormNo := 1
Local nGridMargins := 4, nButtonH := 28, nButtonW := 100, nHeaderH := 24, nCellH := 19, nCellW := 100, nMiddleOfForm 
Local nVScrollW := GetSystemMetrics( 2 /* SM_CXVSCROLL */ )
Local lVScrollVisible

Private _xMatrixValue

Default lHeader := .T.

IF WIN_OSISXP()
	#ifdef MG_VER_H_	//MiniGui
		nHeaderH := 20
		nCellH := 17
	#else
		nHeaderH := 20
		nCellH := 16
	#endif
ENDIF

IF .NOT. HB_isArray( aAnyArray )
	MsgStop ("The variable is not an array.")
	RETURN Nil
ENDIF

nItems := 1
FOR EACH _xMatrixValue IN aAnyArray
	IF hb_isArray( _xMatrixValue )
		nItems := MAX ( nItems, LEN( _xMatrixValue ) )  
	ENDIF
NEXT

_xMatrixValue := Nil

aColumns := Array ( nItems )
AEval( aColumns, { | x, y | aColumns [ y ] := "Column - " + Alltrim(Str( y )) + " -"  })

DO WHILE .T.
	cFormName := "_MatrixForm_" + Alltrim( Str ( nFormNo ) )
	IF !_IsWindowDefined ( cFormName )
		EXIT
	ENDIF
	nFormNo ++
ENDDO

lVScrollVisible := LEN( aAnyArray ) * nCellH + nGridMargins + IF( lHeader, nHeaderH, 0) + nButtonH + 4 /* space between grid/buttons/form */ > GetDesktopRealHeight()


DEFINE WINDOW &cFormName ;
	AT 0,0 ;
	WIDTH MIN( nItems * nCellW  + nGridMargins + IF( lVScrollVisible, nVScrollW, 0), GetDesktopRealWidth() )  ;
	HEIGHT MIN ( LEN( aAnyArray ) * nCellH + nGridMargins + IF( lHeader, nHeaderH, 0) + nButtonH + 4 /* space between grid/buttons/form */, GetDesktopRealHeight() ) ;
	MODAL ;
	NOSIZE ;
	NOSYSMENU ;
	NOCAPTION 
	
	ON KEY ESCAPE ACTION ThisWindow.Release
	
	DEFINE GRID Grid_1
		PARENT &CFormName
		ROW 0 
		COL 0
		WIDTH MIN ( nItems * nCellW  + nGridMargins + IF( lVScrollVisible, nVScrollW, 0) , GetDesktopRealWidth() ) 
		HEIGHT MIN ( LEN( aAnyArray ) * nCellH + nGridMargins + IF(lHeader, nHeaderH, 0) , GetDesktopRealHeight() - nButtonH - 4 /* space between grid/buttons/form */ )
		HEADERS aColumns
		WIDTHS AFill ( Array (nItems), nCellW )
		VALUE { 1, 1 }
		DYNAMICFORECOLOR AFill ( Array (nItems), { || if ( hb_isString(This.CellValue) .AND. Alltrim(This.CellValue) = "{ Inner array }" , RED, BLACK )  } )
		ONDBLCLICK (_xMatrixValue := GetMatrixValue ( aAnyArray, cFormName ), ThisWindow.Release)
		VIRTUAL .T.
		ITEMCOUNT LEN( aAnyArray )
		ONQUERYDATA QueryArray ( aAnyArray )
		SHOWHEADERS lHeader
		CELLNAVIGATION .T.
      END GRID
	
	
	nMiddleOfForm := (GetProperty( cFormName, 'WIDTH' ) / 2)
	nButtonW := MIN(nMiddleOfForm - 5, nButtonW)
	
	@ GetProperty( cFormName, 'HEIGHT' ) - nButtonH - 2, nMiddleOfForm - nButtonW - 5 BUTTON B_OK ;
	CAPTION "OK" ;
	ACTION (_xMatrixValue := GetMatrixValue ( aAnyArray, cFormName ), ThisWindow.Release) ;
	WIDTH nButtonW ;
	HEIGHT nButtonH
	
	@GetProperty( cFormName, 'HEIGHT' )  - nButtonH - 2, nMiddleOfForm + 5 BUTTON B_Cancel ;
	CAPTION "Cancel" ;
	ACTION ThisWindow.Release ;
	WIDTH nButtonW ;
	HEIGHT nButtonH
    
END WINDOW

#ifdef MG_VER_H_	//MiniGui
	CENTER WINDOW &cFormName
#else
	CENTER WINDOW &cFormName DESKTOP
#endif

ACTIVATE WINDOW &cFormName

Return _xMatrixValue

*******************************************
Function GetMatrixValue ( aArray, cFormName )
Local nRow := GetProperty(cFormName, 'Grid_1', 'Value' ) [1]
Local nCol := GetProperty(cFormName, 'Grid_1', 'Value' ) [2]
Local _xMatrixValue :=  Nil
Local xCellValue

IF hb_isNumeric ( nRow ) .AND. nRow > 0 .AND. nRow <= LEN( aArray )
	
	xCellValue := GetProperty( cFormName, 'Grid_1', 'Cell', nRow, nCol )

	IF hb_isString( xCellValue) .AND. Alltrim( xCellvalue ) == '{ Inner array }'
		//show Inner Array
		_xMatrixValue := MatrixBrowse( aArray [nRow] [nCol] )

	ELSE 
		IF hb_isArray( aArray [nRow] )
			_xMatrixValue := aArray [nRow] [nCol]
		ELSEIF nCol == 1
			_xMatrixValue := aArray [nRow]
		ENDIF
	ENDIF
ENDIF
   
Return _xMatrixValue
******************************************

Procedure QueryArray( aArray )
	
	IF !hb_isArray ( aArray [This.QueryRowIndex] )
	
		IF This.QueryColIndex == 1
			This.QueryData := hb_ValToStr( aArray [This.QueryRowIndex] )
		ELSE
			This.QueryData := ""		//Nil
		ENDIF
		
	ELSEIF hb_isArray ( aArray [This.QueryRowIndex] [This.QueryColIndex] )
	
		This.QueryData := "{ Inner array }"
		
	ELSE	
	
		This.QueryData := hb_ValToStr( aArray [This.QueryRowIndex] [This.QueryColIndex] )
		
	ENDIF

Return

*******************************************************************************
Function ABrowse ( aAnyArray , lHeader )
Local nItems, aColumns
Local nGridMargins := 4, nButtonH := 28, nButtonW := 100, nHeaderH := 24, nCellH := 19, nCellW := 100, nMiddleOfForm 
Local nVScrollW := GetSystemMetrics( 2 /* SM_CXVSCROLL */ )
Local lVScrollVisible

Local _nMatrixValue

Default lHeader := .T.

IF WIN_OSISXP()
	#ifdef MG_VER_H_	//MiniGui
		nHeaderH := 20
		nCellH := 17
	#else
		nHeaderH := 20
		nCellH := 16
	#endif
ENDIF

IF .NOT. HB_isArray( aAnyArray )
	MsgStop ("The variable is not an array.")
	RETURN 0
ENDIF

nItems := 1
FOR EACH _nMatrixValue IN aAnyArray
	IF hb_isArray( _nMatrixValue )
		nItems := MAX ( nItems, LEN( _nMatrixValue ) )  
	ENDIF
NEXT

_nMatrixValue := 0

aColumns := Array ( nItems )
AEval( aColumns, { | x, y | aColumns [ y ] := "Column - " + Alltrim(Str( y )) + " -"  })

lVScrollVisible := LEN( aAnyArray ) * nCellH + nGridMargins + IF( lHeader, nHeaderH, 0) + nButtonH + 4 /* space between grid/buttons/form */ > GetDesktopRealHeight()

DEFINE WINDOW _ABrowseForm_ ;
	AT 0,0 ;
	WIDTH MIN( nItems * nCellW  + nGridMargins + IF( lVScrollVisible, nVScrollW, 0), GetDesktopRealWidth() )  ;
	HEIGHT MIN ( LEN( aAnyArray ) * nCellH + nGridMargins + IF( lHeader, nHeaderH, 0) + nButtonH + 4 /* space between grid/buttons/form */, GetDesktopRealHeight() ) ;
	MODAL ;
	NOSIZE ;
	NOSYSMENU ;
	NOCAPTION 
	
	ON KEY ESCAPE ACTION ThisWindow.Release
	
	DEFINE GRID Grid_1
		PARENT _ABrowseForm_
		ROW 0 
		COL 0
		WIDTH MIN ( nItems * nCellW  + nGridMargins + IF( lVScrollVisible, nVScrollW, 0) , GetDesktopRealWidth() ) 
		HEIGHT MIN ( LEN( aAnyArray ) * nCellH + nGridMargins + IF(lHeader, nHeaderH, 0) , GetDesktopRealHeight() - nButtonH - 4 /* space between grid/buttons/form */ )
		HEADERS aColumns
		WIDTHS AFill ( Array (nItems), nCellW )
		VALUE 1
		DYNAMICFORECOLOR AFill ( Array (nItems), { || if ( hb_isString(This.CellValue) .AND. Alltrim(This.CellValue) = "{ Inner array }" , RED, BLACK )  } )
		ONDBLCLICK (_nMatrixValue := This.Value, ThisWindow.Release)
		VIRTUAL .T.
		ITEMCOUNT LEN( aAnyArray )
		ONQUERYDATA QueryArray ( aAnyArray )
		SHOWHEADERS lHeader
		CELLNAVIGATION .F.
      END GRID
	
	
	nMiddleOfForm := _ABrowseForm_.WIDTH / 2
	nButtonW := MIN(nMiddleOfForm - 5, nButtonW)
	
	@ _ABrowseForm_.HEIGHT - nButtonH - 2, nMiddleOfForm - nButtonW - 5 BUTTON B_OK ;
	CAPTION "OK" ;
	ACTION (_nMatrixValue := _ABrowseForm_.Grid_1.Value, ThisWindow.Release) ;
	WIDTH nButtonW ;
	HEIGHT nButtonH
	
	@ _ABrowseForm_.HEIGHT - nButtonH - 2, nMiddleOfForm + 5 BUTTON B_Cancel ;
	CAPTION "Cancel" ;
	ACTION ThisWindow.Release ;
	WIDTH nButtonW ;
	HEIGHT nButtonH
    
END WINDOW

#ifdef MG_VER_H_	//MiniGui
	CENTER WINDOW _ABrowseForm_
#else
	CENTER WINDOW _ABrowseForm_ DESKTOP
#endif

ACTIVATE WINDOW _ABrowseForm_

Return _nMatrixValue

#ifdef MG_VER_H_	//MiniGui

	#pragma BEGINDUMP
	#include <hbapi.h>
	#include <windows.h>

	HB_FUNC (GETDESKTOPREALWIDTH) 
	{
	RECT Rect;
	SystemParametersInfo ( SPI_GETWORKAREA, 0, &Rect, 0 );
	hb_retni ((Rect.right - Rect.left));
	}


	HB_FUNC (GETDESKTOPREALHEIGHT) 
	{
	RECT Rect;
	SystemParametersInfo ( SPI_GETWORKAREA, 0, &Rect, 0 );
	hb_retni ((Rect.bottom - Rect.top));
	}

	#pragma ENDDUMP

#endif


PeteWG
Posts: 138
Joined: Sun Mar 21, 2010 5:45 pm
Has thanked: 11 times
Been thanked: 39 times

Post by PeteWG » Thu Mar 28, 2019 6:25 am

dragancesu wrote:
Wed Mar 27, 2019 9:47 am
Program sbr_lov.prg contains the function for this lov_func () and lovs_func (), without and with string search
Thanks Dragan! Always useful to see how other developers do things; that's a good way to attain or refresh knowledge.
I liked Clipper, simple and powerful features
Our old good Clipper! those were the days... 8-)


regards,
Pete

Post Reply