1. EuGrid: How to use onGotFocus for a "cell"?
- Posted by Rad <radhx at rediffmail.com> Feb 19, 2007
- 505 views
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. }}}
2. Re: EuGrid: How to use onGotFocus for a "cell"?
- Posted by Phil Russell <pg_russell at lineone.net> Feb 20, 2007
- 503 views
- Last edited Feb 21, 2007
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)
integer textlength, cursel atom buffer sequence text text = {}
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
msg = parms[1] wParam = parms[2] lParam = parms[3]
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> }}}
3. Re: EuGrid: How to use onGotFocus for a "cell"?
- Posted by Phil Russell <pg_russell at lineone.net> Feb 20, 2007
- 489 views
- Last edited Feb 21, 2007
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)
integer textlength, cursel atom buffer sequence text text = {}
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
msg = parms[1] wParam = parms[2] lParam = parms[3]
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> }}}
4. Re: EuGrid: How to use onGotFocus for a "cell"?
- Posted by Jonas Temple <jtemple at yhti.net> Feb 21, 2007
- 498 views
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
5. Re: EuGrid: How to use onGotFocus for a "cell"?
- Posted by Rad <radhx at rediffmail.com> Feb 21, 2007
- 497 views
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.
6. Re: EuGrid: How to use onGotFocus for a "cell"?
- Posted by Jonas Temple <jtemple at yhti.net> Feb 21, 2007
- 504 views
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
7. Re: EuGrid: How to use onGotFocus for a "cell"?
- Posted by Rad <radhx at rediffmail.com> Feb 22, 2007
- 524 views
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.
8. Re: EuGrid: How to use onGotFocus for a "cell"?
- Posted by Phil Russell <pg_russell at lineone.net> Feb 22, 2007
- 503 views
- Last edited Feb 23, 2007
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