1. EuGrid: How to use onGotFocus for a "cell"?

Hi,

In EuGrid 1.33, a column has ComboBox with all the values defined in a Master.
As a cell for any row in that column gets focus, I would like to display the
corresponding code description in an EditText placed somewhere else on the
screen.

LatestACH is the underlying dataset.
There are 11 columns in dataset, out of which columns 2, 7, 8, 9 are used in
grid.
Column 10, 11 are used to store descriptions for the codes in column 1 and 2
resp.

Column 1 is Static and its description is loaded in column 10 only once.
Column 2 has a ComboBox for which description is stored in column 11.
As the ComboBox value is changed, I would like to store the corresp. description
in
column 11.

How to process GotFocus for a "cell"?

I am setting the required procedure in onEvent for EuGrid.
I tried to set up EditText for EGW_CELLCHANGE and/or EGW_CELLEDIT.
But in case of CELLCHANGE focus moves to next cell/row after the EditText is
setup.
And for CELLEIDT, even after selecting a new value in combo, description doesn't
change.


procedure EuGrid802_onEvent (integer self, integer event, sequence params)
atom rowkey, col_id
object datavalue
sequence currCell

rowkey = iff(params[2] > 0, params[2], 1) col_id = iff(params[3] > 0, params[3], 1)

if find(params[1], {EGW_LEFTBUTTONDOWN}) then void = EGW_SaveCellData(self, {rowkey, col_id}) datavalue = EGW_GetDataRow(self, rowkey) if sequence(datavalue) then setText(EditText806, datavalue[10]&" (ONEVNT-CLICK)") setText(EditText808, datavalue[11]&" (ONEVNT-CLICK)") else setText(EditText806, {}&" (ONEVNT-CLICK)") setText(EditText808, {}&" (ONEVNT-CLICK)") end if elsif params[1] = EGW_CELLCHANGE then void = EGW_SaveCellData(self, {rowkey, col_id}) datavalue = EGW_GetDataCellValue(self, rowkey, ACHDataCols[col_id]) if col_id = 2 then Formula if find(datavalue, ACHFormulae) then LatestACH[rowkey][11] = getMasCodeDesc(4, w32TextToNumber(datavalue), 1) set new formula desc setText(EditText806, LatestACH[rowkey][10]&" (ONEVNT-CELLCHANGE)") setText(EditText808, LatestACH[rowkey][11]&" (ONEVNT-CELLCHANGE)") else returnValue(w32True) Invalid Formula end if elsif col_id = 3 then Amount elsif col_id = 4 then Percentage end if elsif params[1] = EGW_CELLEDIT then void = EGW_SaveCellData(self, {rowkey, col_id}) datavalue = EGW_GetDataCellValue(self, rowkey, ACHDataCols[col_id]) if col_id = 2 then Formula if find(datavalue, ACHFormulae) then LatestACH[rowkey][11] = getMasCodeDesc(4, w32TextToNumber(datavalue), 1) set new formula desc setText(EditText806, LatestACH[rowkey][10]&" (ONEVNT-CELLEDIT)") setText(EditText808, LatestACH[rowkey][11]&" (ONEVNT-CELLEDIT)") end if end if end if

end procedure setHandler( EuGrid802, w32HEvent, routine_id("EuGrid802_onEvent"))

Regards, Rad. }}}

new topic     » topic index » view message » categorize

2. Re: EuGrid: How to use onGotFocus for a "cell"?

Rad wrote:
> 
> Hi,
> 
> In EuGrid 1.33, a column has ComboBox with all the values defined in a Master.
> As a cell for any row in that column gets focus, I would like to display the
> corresponding code description in an EditText placed somewhere else on the
> screen.
> 

Hi Rad,

The current version of EuGrid is a bit limited in how it handles messages for
its own child windows (which are non-win32lib). Should be better in version 
2.0 if I ever finish it.

However, I've come up with a way of processing changes to a combobox
selection - does this do what you want?

Cheers,

Phil

--
-- Demo of combo change handling
-- Phil Russell Jan 2007

include win32lib.ew include eugrid.ew

without warning

object void

constant GRID_DATA = { {"spring"}, {"summer"}, {"autumn"}, {"winter"}, {""}, {"spring"}, {"summer"}, {"winter"} }

constant COMBO_DEFAULT = { "spring", "summer", "autumn", "winter" }

constant Main = create( Window, "Processing Combo Selection", 0, 50, 50, 400, 250, 0 ) constant Selection = create( EditText, "", Main, 210, 10, 150, 25, 0 ) constant Grid = EGW_CreateGrid(Main, 10, 10, 200, 200, EGW_True) constant ColCombo = EGW_AddColumn(Grid, "Combo", 100, EGW_LAST, EGW_COMBO, 1)

void = EGW_SetColumnProperty(Grid, ColCombo, EGW_COL_LISTVALUES, COMBO_DEFAULT)

void = EGW_LoadData(Grid, GRID_DATA, EGW_REPLACE) *-------------------------------------------------* GetComboText: Get current selection from combobox (modified from win32lib)

*----------------------------------------------------* function GetComboText( atom hwnd )

integer textlength, cursel atom buffer sequence text text = {}

get current selection index cursel = w32Func(xSendMessage,{ hwnd, CB_GETCURSEL, 0, 0 })

if cursel >= 0 then textlength = w32Func( xSendMessage, {hwnd, CB_GETLBTEXTLEN, cursel, 0} )+1

if textlength > 0 then buffer = W32_acquire_mem(0, textlength ) textlength = w32Func( xSendMessage, {hwnd, CB_GETLBTEXT, cursel, buffer} ) text = peek( {buffer, textlength} ) W32_release_mem( buffer ) end if end if

return text

end function *-------------------------------------------------* onGridEvent: Grid event handler

*----------------------------------------------------* procedure onGridEvent (atom self, atom event, sequence parms) atom msg, wParam, lParam, row, col, hiword, cursel sequence cell object val

msg = parms[1] wParam = parms[2] lParam = parms[3]

Check combo for changes if msg=WM_COMMAND then cell = EGW_GetCurrentCell(Grid) row = cell[1] col = cell[2]

if col=ColCombo and row>0 then if W32_hi_word(wParam) = CBN_CLOSEUP then val = GetComboText(lParam) setText( Selection, sprintf("row=%d, value=%s", {row, val}) ) end if end if end if

end procedure *-------------------------------------------------* setHandler(Grid, w32HEvent, routine_id("onGridEvent"))

WinMain( Main, Normal ) <\eucode> }}}

new topic     » goto parent     » topic index » view message » categorize

3. Re: EuGrid: How to use onGotFocus for a "cell"?

Rad,

Having read your post a bit more carefully, try this which picks up
the combo focus event as well.

HTH,

Phil

--
-- Demo of combo change handling
-- Phil Russell Jan 2007

include win32lib.ew include eugrid.ew

without warning

object void

constant GRID_DATA = { {"spring"}, {"summer"}, {"autumn"}, {"winter"}, {""}, {"spring"}, {"summer"}, {"winter"} }

constant COMBO_DEFAULT = { "spring", "summer", "autumn", "winter" }

constant Main = create( Window, "Processing Combo Selection", 0, 50, 50, 420, 250, 0 ) constant Selection = create( EditText, "", Main, 210, 10, 200, 25, 0 ) constant Grid = EGW_CreateGrid(Main, 10, 10, 200, 200, EGW_True) constant ColCombo = EGW_AddColumn(Grid, "Combo", 100, EGW_LAST, EGW_COMBO, 1)

void = EGW_SetColumnProperty(Grid, ColCombo, EGW_COL_LISTVALUES, COMBO_DEFAULT)

void = EGW_LoadData(Grid, GRID_DATA, EGW_REPLACE) *-------------------------------------------------* GetComboText: Get current selection from combobox (modified from win32lib)

*----------------------------------------------------* function GetComboText( atom hwnd )

integer textlength, cursel atom buffer sequence text text = {}

get current selection index cursel = w32Func(xSendMessage,{ hwnd, CB_GETCURSEL, 0, 0 })

if cursel >= 0 then textlength = w32Func( xSendMessage, {hwnd, CB_GETLBTEXTLEN, cursel, 0} )+1

if textlength > 0 then buffer = W32_acquire_mem(0, textlength ) textlength = w32Func( xSendMessage, {hwnd, CB_GETLBTEXT, cursel, buffer} ) text = peek( {buffer, textlength} ) W32_release_mem( buffer ) end if end if

return text

end function *-------------------------------------------------* onGridEvent: Grid event handler

*----------------------------------------------------* procedure onGridEvent (atom self, atom event, sequence parms) atom msg, wParam, lParam, row, col, hiword, cursel sequence cell object val

msg = parms[1] wParam = parms[2] lParam = parms[3]

Check combo for changes if msg=WM_COMMAND then cell = EGW_GetCurrentCell(Grid) row = cell[1] col = cell[2]

if col=ColCombo and row>0 then if W32_hi_word(wParam) = CBN_CLOSEUP then val = GetComboText(lParam) setText( Selection, sprintf("Change: row=%d, value=%s", {row, val}) ) elsif W32_hi_word(wParam) = CBN_SETFOCUS then val = EGW_GetDataCellValue(Grid, row, 1) setText( Selection, sprintf("Focus: row=%d, value=%s", {row, val}) ) end if end if end if

end procedure *-------------------------------------------------* setHandler(Grid, w32HEvent, routine_id("onGridEvent"))

WinMain( Main, Normal ) <\eucode> }}}

new topic     » goto parent     » topic index » view message » categorize

4. Re: EuGrid: How to use onGotFocus for a "cell"?

Phil Russell wrote:
> The current version of EuGrid is a bit limited in how it handles messages for
> its own child windows (which are non-win32lib). Should be better in version
> 2.0 if I ever finish it.

Well, since you're here...

Phil, what types of incentives would it take to complete V2.0?  :)  Money,
clothes, magazine subscriptions?

I'm working on adding a database file editor to FROG that uses EuGRID.  I've
already hacked EuGrid by adding a routine to get the edit control of the current
cell.  I needed to do some specific key handling for numeric fields which
involved getting the current value of the control.

So if you need more ideas for V2.0:
* Way to get the value of the current cell, not just the value from the
underlying dataset.  I could send you my change as noted above if that helps.
* Mask editing would be REALLY nice.  I.E. I set a column/cell property of say,
EGW_EDIT_MASK and give it '##/##/####' which would obviously imply a date.
* A native Date cell type with multiple formatting options (MDY, YMD, CYMD,
etc.) and link to the Windows date selector.
* A native Time cell type
* A message sent when the user pages down and the last row in the grid comes
into focus.  The reason is in my database editor I don't load the entire file. 
So now I have a check for the pagedown key and then load another page of records.
 The problem is is that I don't know if the last row is displayed.  Maybe there's
another way to accomplish this?

BTW, I also modified the xControls demo in EuGrid to work with the new version
of xControls.  I wanted to make sure they were still compatible.  I can send you
the code, if interested.

Jonas Temple
http://www.innovativesys.net

new topic     » goto parent     » topic index » view message » categorize

5. Re: EuGrid: How to use onGotFocus for a "cell"?

Hi Phil,

Thanks for the code. I could successfully incorporate it in my system as
follows:

procedure EuGrid802_onEvent (integer self, integer event, sequence
params)--params is ( int iMsg, atom wParm, atom lParm )
atom rowkey, col_id
object datavalue
sequence currCell

	currCell = EGW_GetCurrentCell(self)
	rowkey = iff(currCell[1] > 0, currCell[1], 1)
	col_id = iff(currCell[2] > 0, currCell[2], 1)
	
	if params[1] = EGW_CELLEDIT then
		if find(col_id, {3, 4}) then
			if not find(params[2], valAmtChars) then
				returnValue(w32True) -- Invalid Amt Char
			end if
		end if
	elsif params[1] = WM_COMMAND then
		if col_id = 2 then
		-- Check combo for changes
			if W32_hi_word(params[2]) = CBN_CLOSEUP then
				datavalue = GetComboText(params[3])
LatestACH[rowkey][11] = getMasCodeDesc(4, w32TextToNumber(datavalue), 1) --
set new formula desc
				setText(EditText806, LatestACH[rowkey][10])
				setText(EditText808, LatestACH[rowkey][11])
			elsif W32_hi_word(params[2]) = CBN_SETFOCUS then
				datavalue = EGW_GetDataCellValue(self, rowkey, ACHDataCols[col_id])
LatestACH[rowkey][11] = getMasCodeDesc(4, w32TextToNumber(datavalue), 1) --
set new formula desc
				setText(EditText806, LatestACH[rowkey][10])
				setText(EditText808, LatestACH[rowkey][11])
			end if
		end if
	elsif params[1] = WM_SETFOCUS then
		if not (col_id = 2) then
			setText(EditText806, LatestACH[rowkey][10])
			setText(EditText808, LatestACH[rowkey][11])
		end if
	elsif params[1] = EGW_CELLCHANGE then
		if col_id = 2 then -- Formula
			void = EGW_SaveCellData(self, {rowkey, col_id})
			datavalue = EGW_GetDataRow(self, rowkey)
			datavalue = datavalue[ACHDataCols[col_id]]
			if not find(datavalue, ACHFormulae) then
				setText(EditText808, "Invalid Formula Code: " & datavalue)
				returnValue(w32True) -- Invalid Formula Code
			end if
		end if
	end if

	setText(StatusBar776, "Row, Col: "&sprintf("%d, %d", {rowkey, col_id}))
end procedure
setHandler( EuGrid802, w32HEvent, routine_id("EuGrid802_onEvent"))


I have one more question.

How can I trap w32HChange and w32HLostFocus for EGW_EDIT cells?

For each key-stroke used in EGW_EDIT cell, I want to invoke an existing function
(Amount Handler) which will format the entered value. Then I will  set it back to
EGW_EDIT cell.

(I am using this function for win32lib EditText controls for formatting amount
fields)

I could not apply this function using EGW_CELLEDIT event but I could format the
EGW_EDIT cell on EGW_CELLCHANGE event by -

1] Save and extract EGW_EDIT value using SaveCellData() and GetDataCellValue().
2] move the entered EGW_EDIT value to an EditText control.
2] invoke the amount handler function by means of setHandler() for EditText.
3] update the underlying dataset column with formatted value.
4] reload the grid.

Like EGW_SaveCellData(), can there be EGW_LoadCellData() in future verion of
EuGrid
for loading individual cell data instead of entire grid?

Regards,
Rad.

new topic     » goto parent     » topic index » view message » categorize

6. Re: EuGrid: How to use onGotFocus for a "cell"?

Rad wrote:
> I have one more question.
> 
> How can I trap w32HChange and w32HLostFocus for EGW_EDIT cells?

I use the following:

if msg=EGW_KEYCHAR then
            
        -- Get the field type information for this column
        col_index = find(cur_cell[2], fe_gridcolumns)
        if col_index then
            
            -- Don't allow a numeric field to go over it's maximum size
            if fe_columns[col_index][fe_precision] then
                rtn_value = validNumberKey(cur_cell[1], cur_cell[2], wParam)
            else
                rtn_value = 0
            end if
            
            -- Enable the save button for valid keys
            if rtn_value = 0 then
                setEnable(FESavePB, True)
            end if
            
        -- This should never happen, but just in case, don't allow the key
        else
            returnValue(1)
        end if


The validNumber routine gets the value of the edit cell.  This is accomplished
with a new routine I added to eugrid (right before EGW_GetCurrentCell):

--*------------------------------------------------------*
-- EGW_GetCurrentCellValue - Get the value in the cell's edit control
--*------------------------------------------------------*
function EGW_GetCurrentCellValue ( integer grid, sequence cell )
    integer control, col, datacol, index

    -- Get index for column id in cell
    col = EGW_GetColumnIndex( grid, cell[COL_ID])

    -- If a valid cell then save changes
    if length(GridData[grid])>0 and cell[ROW]>0 and col>0 then

        -- Get underlying data column for grid column
        datacol = GridCol[grid][col][EGW_COL_DATACOL]

        -- Get edit control for column
        control = EGW_GetEditControlForCell ( grid, cell )

        if datacol > 0 and control > 0 then
            return EGW_GetText( GridControl[grid][control][HWND] )
        end if
        
    end if

    return 0

end function


The above routine gets the cell's value BEFORE it's saved to the underlying
dataset.  My validNumberKey routine returns 0 if the key should be allowed.

> Like EGW_SaveCellData(), can there be EGW_LoadCellData() in future verion of
> EuGrid
> for loading individual cell data instead of entire grid?

You can do this via the EuGrid routine:

boolean = EGW_SetDataCellValue ( integer id, atom row, atom datacol, object
value )

Jonas Temple
http://www.innovativesys.net

new topic     » goto parent     » topic index » view message » categorize

7. Re: EuGrid: How to use onGotFocus for a "cell"?

Thanks Jonas. I will try out the code and get back.

Jonas Temple wrote:
> 
> > Like EGW_SaveCellData(), can there be EGW_LoadCellData() in future verion of
> > EuGrid
> > for loading individual cell data instead of entire grid?
> 
> You can do this via the EuGrid routine:
> 
> boolean = EGW_SetDataCellValue ( integer id, atom row, atom datacol, object
> value )
> 

What I meant was updating the Grid Cell, not the underlying Dataset cell.

At present, to update the a single Grid Cell (after using amount handler
function), I am using EGW_SetDataCellValue() and then reloading entire grid to
reflect the change.

Regards
Rad.

new topic     » goto parent     » topic index » view message » categorize

8. Re: EuGrid: How to use onGotFocus for a "cell"?

Rad wrote:
> 
> Thanks Jonas. I will try out the code and get back.
> 
> Jonas Temple wrote:
> > 
> > > Like EGW_SaveCellData(), can there be EGW_LoadCellData() in future verion
> > > of
> > > EuGrid
> > > for loading individual cell data instead of entire grid?
> > 
> > You can do this via the EuGrid routine:
> > 
> > boolean = EGW_SetDataCellValue ( integer id, atom row, atom datacol, object
> > value )
> > 
> 
> What I meant was updating the Grid Cell, not the underlying Dataset cell.
> 
> At present, to update the a single Grid Cell (after using amount handler
> function),
> I am using EGW_SetDataCellValue() and then reloading entire grid to reflect
> the change.
> 
> Regards
> Rad.

Rad, 

There isn't really a 'current cell' to update - a bit of trickery occurs
to make it look like each cell contains a window.

The way it works is that an image of the grid is generated and painted onto
the screen. When you click on a grid cell then the appropriate edit control 
is sized to the cell, made visible, placed on top of the cell area, 
text set to the underlying data cell value, and given the input focus. 

There are only a few actual child windows which are continually reused 
e.g. three text edit fields (one for each text justification type), one 
combo box, and one list box. Buttons and checkboxes are emulated. This makes
it a bit tricky to handle stuff like focus events as e.g. what appears to be
tabbing from cell to cell is really just the same window being moved around.

Anyway, Jonas's suggestion is correct.  It may seem like overkill to repaint 
the grid just to update a particular value, but only the *visible* part of 
the grid is ever generated i.e. the overhead is the same for a grid 
containing 10 rows as it is for one containing 10,000. Given that a typical
grid will only display 40-50 cells, the drawing effort is minimal.

HTH,

Phil

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu