Managing cell contents in EGrid32 - howto

Started by Dwight Scoles, October 03, 2006, 12:56:50 AM

Previous topic - Next topic

Dwight Scoles

In my current application I have a number of grids for display and entry of lists of related data.  Just getting started in PB8 I'm not in a position to attempt complicated overlaying of text boxes on top of List View controls.  So, am willing to use a full-function DLL like EGrid 32 to manage this data.

The help I need is really quite simple.  Yet, after a lot of searching I'm not finding the answeres in the EGrid32 chm help file or samples.

Questions:

1) I've gotten the function "EZ_SetCellCaption()" that was mentioned in a previous post to work. It is really great.  However, I can't find the prototype description for "EZ_GetCellCaption()" that would allow me to retrieve the cell contents.  I'm getting errors attempting to use either:
RetParam = EZ_GetCellCaption(ByVal HWND_FRMRULESENTRY_EGUSED, ByVal ToCol, ByVal ToRow , VarPtr(NewText))
- or -
RetParam = EZ_GetCellCaption(ByVal HWND_FRMRULESENTRY_EGUSED, ByVal ToCol, ByVal ToRow , NewText)
[error: 414 -- ")" expected]

Anybody have any clues?

2) I have attempted to use the SendMessage version (as close as I can tell  how), and end up with the system hanging (XP) or returning an error "referencing memory at "0x00000000". The memory could not be written".  

This is the code I try:
SendMessage HWND_FRMRULESENTRY_EGUSED, %EG_GETCELLTEXT, StrPtr(RetText), 0

So, I'd love to know what simple oversite there is to the code.

3) The grids I'm using display grids that are no more than 6 columns wide including row captions and 4 rows tall including column titles.  The row captions are set up in the properties structure.  When I attempt to use:

SendMessage(HWND_FRMRELATIONSHIPS_EGCHAIN, %EG_CLEARGRID, %EG_DONTRESETCOLSIZES, 0)

... this causes the column headings to revert back to A, B, C, etc.  What would be the appropriate way to clear a grid and retain the headings?

4) Is there a way to know how many rows are populated in a grid and loop through the rows up to that point?

5) There have been a couple of nice responses to previous posts which provided sample code (Thanks Elias! ) that included function calls such as mentioned above.  Can anyone tell me where the descriptions exist for those functions?  I've looked in the list of function declarations in the EGRID32PRO.INC file and was surprised not to find them.  I can't imagine how they get declared without being in there.  And, nothing comes up when I search for the functions I know about in the chm help (Egrid32.chm) or in the sample programs.  I know there are lots of great features in EGrid32, but am really finding myself lost when it comes to interpreting the sendmessage commands and getting them to work without compile errors.  So, the question is this:  Is there another place to look?  Especially is there a list of functions and possibly example code for them?

Thanks for all the help from the other EGrid32 people!

Dwight

Elias Montoya

Sounds like an outdated include file... ill send you an updated one as soon as i get some sleep, its 6 am here and i havent slept...

:)

Elias Montoya

Answer 1

Ok i got some sleep. :)

EZ_GetCellCaption returns a string parameter, here is the code:

'-------------------------------------------------------------------------------------------
' Gets the text for a cell under FullLine mode.
'-------------------------------------------------------------------------------------------
FUNCTION EZ_GetCellCaption(BYVAL Hgrid AS DWORD, BYVAL X AS LONG, BYVAL Y AS LONG) AS STRING
LOCAL Strp AS StringType
SendMessage Hgrid, %EG_INTERNALSELECTTL, X, Y
SendMessage Hgrid, %EG_GETCELLCAPTION, 0, VARPTR(Strp)
FUNCTION = PEEK$(Strp.Sptr, Strp.Length)
END FUNCTION
'-------------------------------------------------------------------------------------------


So, the syntax should be:

TextInCell$ = EZ_GetCellCaption(HWND_FRMRULESENTRY_EGUSED, X, Y)

Answer 2

In newest version of Egrid32 (demo not yet released, only full version for registered users)
This two commands works the same, and still support previous syntax. EG_GETCELLTEXT works for
design mode text and EG_GETCELLCAPTION works for full line mode.


Answer 3

It is possible to keep headings if you are using Full Line mode, By setting the header texts
and clearing the grid using the EG_CLEARGRID with the EG_CLEARFULLLINEMODE option parameter.

If you are using Design mode and want to clear text in cells, but not in headers, it wont
let you. Right now Headers are considered also as cell contents, But i think it would be a
good idea to add a parameter option to allow this. :)

As an easy workaround for now, you can use EG_SETSTRINGDATA to quickly restore header texts,
it is very easy to do this.

Answer 4

Yes. There is. But the way depends on wich grid mode are you running Egrid32, since you talk about
EG_GETCELLCAPTION, i assume you are using Full Line mode, so ill give you a solution for this:

' define the data pointers
LOCAL EGDT EGRID32DATATYPE

' Get the pointers
SendMessage(Hgrid, %EG_GETDATALOCATIONS, VARPTR(EGDT), 0)

' Create arrays pointing to data.
DIM RowIndex(EGDT.ROWS) AS DWORD AT EGDT.GRIDX     ' For indexes (if grid was sorted)
DIM RowData(EGDT.ROWS) AS LONG AT EGDT.ROWLINES    ' For pointer verification
DIM RowTexts(EGDT.ROWS) AS STRING AT EGDT.ROWLINES ' For text consults

' Loop trough all the rows.
LOCAL Index AS LONG
FOR Index = 1 TO EGDT.ROWS
IF RowData(RowIndex(Index)) THEN                      ' If there is a pointer, there is a string.
 IF (LEN(RowTexts(RowIndex(Index))) < EGDT.COLS) THEN ' But Ignore separators
  Msgbox RowTexts(RowIndex(Index))
 END IF
END IF
NEXT Index
   

Answer 5

I know the search system doesnt work very good in the help file, and it is a shame because
i worked on that help file lots and lots of hours. as A tip for searches, Do searches for full
words, for example, if you are looking for help about EG_GETDATALOCATIONS, making a search for
"GETDATALOCATIONS" will return 0 matches. It is awful but its like that. :(

Instead, enter the full word "EG_GETDATALOCATIONS" Et voila. The search engine will find the info.
I may convert help file to some other format, because i know how bad is this one... sorry about that.
but trust me, all the topics are there.

Elias :)

Dwight Scoles

Thanks for the feedback Elias.  I will try each of the items you have suggested and share the results in a later update.

Regards,
Dwight

Dwight Scoles

Hi Elias... I hope your project is letting you get a break once in a while.

I am performing "proof of concept" on the various techniques that will be needed in my project.  The main entry form contains a number of text boxes and then two grids.  After displaying the form and the grids as you instructed in a previous post, the first grid gets three fields filled with string data for testing using the following code:

' populate the rows of the table -- test                                    
  For ToCol = 1 To 3
     ToRow = 1
     NewText = Using$("Test Value #",ToCol)
     RetParam = EZ_SetCellCaption(ByVal HWND_FRMRULESENTRY_EGUSED, ByVal ToCol, ByVal ToRow , NewText)
  Next ToCol


This works fine using your EZ_SetCellCaption() routine you provided.

Here is the issue:  When I attempt to clear out these same cells after entry of data in other parts of the form, the first cell in the first row (1,1) is left with the contents "Test Value #1" displayed in the grid.  This one value does not clear out. The code is here:


FUNCTION EZ_SetCellCaption(BYVAL Hgrid AS DWORD, BYVAL X AS LONG, _
                   BYVAL Y AS LONG, NewText AS STRING) AS LONG
SendMessage Hgrid, %EG_INTERNALSELECTTL, X, Y
FUNCTION = SendMessage(Hgrid, %EG_SETCELLTEXT, STRPTR(NewText), LEN(NewText))
END FUNCTION

Sub EZ_ClearGrid(ByVal Hgrid As Dword)

' local variables
 Local MaxRows As Long
 Local MaxCols As Long
 Local iCol As Long
 Local iRow As Long
 Local RetVal As Long
 Local NewText As String
 
 ' define the data pointers
 Local EGDT As EGRID32DATATYPE

 ' Get the pointers
 SendMessage(Hgrid, %EG_GETDATALOCATIONS, VarPtr(EGDT), 0)
 MaxRows = EGDT.ROWS                                      
 MaxCols = EGDT.COLS
 
 ' Loop to clear data from cells using max extents
 NewText = ""
 For iRow = 1 To MaxRows
  For iCol = 1 To MaxCols  
       RetVal = SendMessage(Hgrid, %EG_CELLCLEARTEXT, iCol, iRow)
''' other option... RetVal = EZ_SetCellCaption(ByVal Hgrid, ByVal iCol , ByVal iRow , NewText)
  Next iCol
 Next iRow

' (NOTE: Both the EG_CELLCLEARTEXT and the EZ_SetCellCaption() produce the same result... row 1, column 2 & 3 are cleared but cell 1,1 retains its text value)
 
End Sub

Sub ClearRuleForm()
' Fill a Rule record buffer with blanks & call ShowRuleForm
' other code to clear fields as neded
.
.
.
   EZ_ClearGrid(HWND_FRMRULESENTRY_EGUSED)
   SendMessage HWND_FRMRULESENTRY_EGUSED, %EG_MOVECURSOR, 1, 1            
   SendMessage HWND_FRMRULESENTRY_EGUSED, %EG_REFRESHALL, 0, 0  
.
.
' other code for other field clearing                
End Sub




A couple of points of interest...
1) Remember, column 2 & 3 do get cleared out of their text contents in row 1 leaving cell 1,1 with its data.
2) If I run the EZ_ClearGrid command immediately after filling the grid instead of after I run the app to fill in other form fields with data, all three grid fields in row 1 clear out.
3) If I type in a value in row 2, column 1 while running the app...  then the clear routine works fine on the grid.  Row 1, col 1 does clear out then.  In other words the issue is only in evidence when I do not touch the data in the grid.
4) The same results occur whether the EZ_ClearGrid routine is constructed using the EZ_SETCELLCAPTION() routine or using the EG_clearcelltext command.

Any clues?

Thanks for the assistance.  Your help is getting me closer with each cycle :!:

Dwight

Elias Montoya

As i mentioned in my previous reply "EG_GETCELLTEXT works for
design mode text and EG_GETCELLCAPTION works for full line mode."

Watching at your Function EZ_SetCellCaption(), it gives the impression
that you are trying to change a line in FullLine mode, but the function
itself makes a call to EG_SETCELLTEXT. It wont work like that.

Ok thats for point #1, for #2... as i mentioned in my previous post,
the example i gave was for FullLine mode, Yet, you say that the EZ_SetCellCaption() works for filling cells?

Just to clarify... Egrid32 has 3 Running modes:

1.- Design mode, Under this mode, every cell is independend of others.
they can have special settings and can be moved freely. This mode does
not support sorting. in this mode most functions are available. This mode requires EG_SETCELLTEXT to assign text to cells. The parameter EG_CLEARDESIGNMODE is required for EG_CLEARGRID to clear grid contents under this mode.

2.-FullLine mode, Under this mode every cell's text is bundled to the side's cell's text. This mode supports sorting, but cells cannot be moved freely (independently). This mode requires EG_SETCELLCAPTION to assign text to individual cells. The parameter EG_CLEARFULLLINEMODE is required for EG_CLEARGRID to clear grid contents under this mode.

3.- Virtual mode, Under this mode, the text displayed in the cells is updated in real time by requesting it to parent dialog everytime Egrid32 needs to display it.

Under modes 2 and 3, text from mode 1 can be displayed if the cells have the EG_PRIORITY flag set to true.

'==============================================
I will try to reproduce the other one, if you have a small snippet reproducing the issue please send it to me to save time.

Elias :)

Elias Montoya

Please try this and let me know the results.... :)


Sub EZ_ClearGrid(ByVal Hgrid As Dword)

' local variables
 Local MaxRows As Long
 Local MaxCols As Long

 ' define the data pointers
 Local EGDT As EGRID32DATATYPE

 ' Get the pointers
 SendMessage(Hgrid, %EG_GETDATALOCATIONS, VarPtr(EGDT), 0)
 MaxRows = EGDT.ROWS                                      
 MaxCols = EGDT.COLS

 SendMessage(hGrid, %EG_INTERNALSELECTTL, 1, 1)
 SendMessage(hGrid, %EG_INTERNALSELECTBR, MaxCols, MaxRows)
 SendMessage(hGrid, %EG_AREACLEARTEXT, 0, 0)
 
End Sub

Elias Montoya

Hello Dwight, i got your e-Mail, ill post answer here for help of others:
I made a test in firefly, I added an Egrid32 to a form, It is empty
at the beggining.

Then i added a button, and named it "Populate". This button adds 3 strings to the grid.

After that i added a Button named "Erase", this calls your function to
erase the grid.

Here is the code:

'-------------------------------------------------------------------------------------------
' Sets the text for a cell under FullLine mode.
'-------------------------------------------------------------------------------------------
Function EZ_SetCellText(ByVal Hgrid As Dword, ByVal X As Long, _
                  BYVAL Y AS LONG, NewText AS STRING) AS LONG
SendMessage Hgrid, %EG_INTERNALSELECTTL, X, Y
FUNCTION = SendMessage(Hgrid, %EG_SETCELLTEXT, STRPTR(NewText), LEN(NewText))
END FUNCTION
'-------------------------------------------------------------------------------------------


' ------------------------------------------------------------------------------------------
' Clears all cells of a grid except for the column header row
'------------------------------------------------------------------------------------------------------------------------
Sub EZ_ClearGrid(ByVal Hgrid As Dword)


' local variables
Local MaxRows As Long
Local MaxCols As Long
Local iCol     As Long
Local iRow    As Long
Local RetVal    As Long
Local NewText As String
Local MISCMSG As String


' define the data pointers
Local EGDT As EGRID32DATATYPE


' Get the pointers
SendMessage(Hgrid, %EG_GETDATALOCATIONS, VarPtr(EGDT), 0)
MaxRows = EGDT.ROWS                                    
MaxCols = EGDT.COLS
MISCMSG = Using$("CLEARING GRID LROW:### LCOL:###",MAXROWS,MAXCOLS)
MsgBox  MISCMSG
'
SendMessage(hGrid, %EG_INTERNALSELECTTL, 1, 1)
SendMessage(hGrid, %EG_INTERNALSELECTBR, MaxCols, MaxRows)
SendMessage(hGrid, %EG_AREACLEARTEXT, 0, 0)


End Sub


'------------------------------------------------------------------------------------------------------------------------
Function FORM1_COMMAND1_BN_CLICKED ( _
                                  ControlIndex     As Long,  _  ' index in Control Array
                                  hWndForm         As Dword, _  ' handle of Form
                                  hWndControl      As Dword, _  ' handle of Control
                                  idButtonControl  As Long   _  ' identifier of button
                                  ) As Long
                                 
EZ_SetCellText(HWND_FORM1_EGRID321, 1, 1, "Test Text #1")
EZ_SetCellText(HWND_FORM1_EGRID321, 2, 1, "Test Text #2")
EZ_SetCellText(HWND_FORM1_EGRID321, 3, 1, "Test Text #3")
SendMessage(HWND_FORM1_EGRID321, %EG_REFRESHALL, 0, 0)

End Function


'------------------------------------------------------------------------------------------------------------------------
Function FORM1_COMMAND2_BN_CLICKED ( _
                                  ControlIndex     As Long,  _  ' index in Control Array
                                  hWndForm         As Dword, _  ' handle of Form
                                  hWndControl      As Dword, _  ' handle of Control
                                  idButtonControl  As Long   _  ' identifier of button
                                  ) As Long
Call EZ_ClearGrid(HWND_FORM1_EGRID321)
SendMessage(HWND_FORM1_EGRID321, %EG_REFRESHALL, 0, 0)  
End Function



The result is that all 3 strings are erased correctly. So, im venturing to
guess what is going on in your app;

1.- Maybe something is changing the internal selection Just before clearing the grid, and then not all grid is covered... or...

2.- Maybe some code is triggered after clearing the grid, a code that restores the text in the first cell. or...

3.- Maybe the grid is not being refreshed after performing changes...
Egrid32 requires programmer to refresh grid after any programmer-level
changes are made.

Try checking if the grid is correctly cleared right after it was cleared,
use this code (check remarks):
'-------------------------------------------------------------------------------------------
' Sets the text for a cell under FullLine mode.
'-------------------------------------------------------------------------------------------
Function EZ_SetCellText(ByVal Hgrid As Dword, ByVal X As Long, _
                  BYVAL Y AS LONG, NewText AS STRING) AS LONG
SendMessage Hgrid, %EG_INTERNALSELECTTL, X, Y
FUNCTION = SendMessage(Hgrid, %EG_SETCELLTEXT, STRPTR(NewText), LEN(NewText))
END FUNCTION
'-------------------------------------------------------------------------------------------


' ------------------------------------------------------------------------------------------
' Clears all cells of a grid except for the column header row
'------------------------------------------------------------------------------------------------------------------------
Sub EZ_ClearGrid(ByVal Hgrid As Dword)


' local variables
Local MaxRows As Long
Local MaxCols As Long
Local iCol     As Long
Local iRow    As Long
Local RetVal    As Long
Local NewText As String
Local MISCMSG As String


' define the data pointers
Local EGDT As EGRID32DATATYPE


' Get the pointers
SendMessage(Hgrid, %EG_GETDATALOCATIONS, VarPtr(EGDT), 0)
MaxRows = EGDT.ROWS                                    
MaxCols = EGDT.COLS

SendMessage(hGrid, %EG_INTERNALSELECTTL, 1, 1)
SendMessage(hGrid, %EG_INTERNALSELECTBR, MaxCols, MaxRows)
SendMessage(hGrid, %EG_AREACLEARTEXT, 0, 0)

' THE FOLLOWING COMMAND REFRESHES THE BEFORE DISPLAYING MSGBOX,
' IF THE GRID IS CORRECTLY CLEARED, THEN SOME OTHER CODE IS EXECUTED
' AFTER THIS, ADDING TEXT TO FIRST CELL.

SendMessage(hGrid, %EG_REFRESHALL, 0, 0)  

MISCMSG = Using$("CLEARING GRID LROW:### LCOL:###",MAXROWS,MAXCOLS)
MsgBox  MISCMSG


End Sub


BTW, What version of Egrid32 are you using?
I hope this helps...

P.S.
If you want to send me the code, ill take a look at it and ill be able to
help in a second.

Elias :)

Dwight Scoles

The reason for the direct email was that I was sending screen-shot pictures and was not sure if that was appropriate or how to include them in the forum.  :?:  I'm using version 3.16.09 Demo that came with FireFly, I believe.

I'm certain you are right that I'm doing something that is messing up the code.  I do use the message box at every single step and so there is nothing happening in between as far as I can tell.  It just does not clear out the one cell.

As I mentioned, if I run the clear grid immediately after I populate the grid, all of the cells clear up fine just like in your code.

If I click on a grid cell and put text in cell row 2, column 1, then row 1 clears up fine, but then row 2 cell 1 does not.

I'll send you the FireFly application as I don't know which "code" to send you that is created by FireFly.  I just click the "compile and run" button so am really quite a novice yet.  This code uses EGrid 32 and Tsunami and is built totally in FireFly.

The best to you

:)
Dwight

Elias Montoya

I was finally able to reproduce it!! yes the text is "not cleared".

It is not a bug in Firefly or in Egrid32, it is actually a behaviour i
created on purpose.

It is caused because user (us in this case :P) press SAVE before
the edition of a cell finishes. THe procedure calls the erasing subroutine
and since the button does not cause Egrid32 to lose focus, the edition
is still active (still with the text iin it).

Then when edition finishes, Egrid32 updates the text that was being
edited.

The solution is very simple, Before calling the erasing subroutine, use
the EG_CLOSEEDITION command. It will Force Egrid32 to close editions
before clearing the grid, eliminatine also the text of the cells that were being edited.

Et voila. :)

Elias :)

Dwight Scoles

Elias,

Gracias. Muy buen :!:

I added the following code before the clear functionality:

SendMessage Hgrid, %EG_CLOSEEDITION, 1, 0          ' close any open cells

This works great!

For anyone who might be interested, the resulting routine is here (newbie code)...

' ------------------------------------------------------------------------------------------
' Clears all cells of a grid except for the column header row
'------------------------------------------------------------------------------------------------------------------------
Sub EZ_ClearGrid(ByVal Hgrid As Dword)
' This routine clears the grid sent in as a parameter

' local variables
 Local MaxRows As Long
 Local MaxCols As Long
 
 SendMessage Hgrid, %EG_CLOSEEDITION, 1, 0          ' close any open cells
 

 ' define the data pointers
 Local EGDT As EGRID32DATATYPE

 ' Get the pointers
 SendMessage(Hgrid, %EG_GETDATALOCATIONS, VarPtr(EGDT), 0)
 MaxRows = EGDT.ROWS                                      
 MaxCols = EGDT.COLS

 '
 SendMessage(hGrid, %EG_INTERNALSELECTTL, 1, 1)
 SendMessage(hGrid, %EG_INTERNALSELECTBR, MaxCols, MaxRows)
 SendMessage(hGrid, %EG_AREACLEARTEXT, 0, 0)  

 ' move to the first cell in the grid on the way out
 SendMessage HWND_FRMRULESENTRY_EGUSED, %EG_MOVECURSOR, 1, 1            
 SendMessage Hgrid, %EG_REFRESHALL, 0, 0                  

End Sub


I appreciate the help.  Tomorrow I'll be off to the Western Union office  :D

Dwight