Page 1 of 1

Dynamic Display in a Context Menu

Posted: Sun Oct 31, 2021 5:55 pm
by Red2
Hi All,

I want to DYNAMICALLY display the GRID (current row's) CELL value in my CONTEXTMENU.
So far I have NOT been able to do this using a MACRO.
MY QUESTION:
Is it possible to dynamically display a CELL's value in a CONTEXTMENU?

-------------------------------------------------
Google Spanish:
Quiero mostrar DINÁMICAMENTE el valor de CELDA de GRID (fila actual) en mi CONTEXTMENU.
Hasta ahora NO he podido hacer esto usando una MACRO.
MI PREGUNTA:
¿Es posible mostrar dinámicamente el valor de una CELDA en un CONTEXTMENU?
-------------------------------------------------


Below I attempt to display a CELL's value of the current GRID row.
This gives: Error BASE/1449 Syntax error: &
*********************
private DynamicGridRowValue := Get_Dynamic_State()
DEFINE CONTROL CONTEXTMENU StatesGrid OF DisplayForm
MenuItem "Print for " + &( DynamicGridRowValue ) ACTION Do_Something( .T. )
MenuItem "Do NOT Print for " + &( DynamicGridRowValue ) ACTION Do_Something( .F. )
END MENU

function Get_Dynamic_State() // Dynamic State lookup in the Grid:
local hdl := GetControlHandle( "StatesGrid", "DataBrowse" )
local lnRow := ListView_GetFirstItem( hdl )
return GetProperty( "DataBrowse", "StatesGrid", "Cell", lnRow, 2 ) // Column #2 value

Re: Dynamic Display in a Context Menu

Posted: Fri Jun 10, 2022 5:15 pm
by Red2
Hi All,

I now have a solution that displays a CONTEXT MENU
dynamically according to each GRID' Control's row.
(Unfortunately there is one exception).

What I did:
1) In the GRID's OnChange Event I call a function where I
DEFINE CONTROL CONTEXT MENU and add the MenuItems.
These are then generated specifically for that particular Row.
(Whenever OnChange is triggered this works great!)

2) I adapted code in the test.rar attachment that was posted by salamandra:
(https://www.hmgforum.com/viewtopic.php? ... rightclick)
Specifically, CREATE EVENT PROCNAME On_M_RClick()
and FUNCTION On_M_RClick().
In my FUNCTION On_M_RClick() I call the GRID's OnChange Event.

When a Grid Row already has Focus then a Right Click gives the
correct CONTROL CONTEXT MENU for that particular row.

The One (Problem) Exception:
The very first Right Click on a NEW row does not fire the OnChange event
so the CONTROL CONTEXT MENU that appears is from the PREVIOUS Grid row!
(Interestingly a second Right Click will SetFocus to this new Grid row and OnChange fires.)

I have tried many things in my On_M_RClick() code including
DoMethod( "DataBrowse", "BrowseStates", "SetFocus" )
and
Do Events
but have not been able here to simply set the Focus to this new Grid Row.

Question:
How can Row Focus be programmatically triggered within my function On_M_RClick()?

I would greatly appreciate the kind help of someone more experienced with this difficult exception?
Thank you!
Red2

Re: Dynamic Display in a Context Menu

Posted: Sun Jun 12, 2022 8:40 am
by serge_girard
Hi Red,

Maybe this can help you:

Code: Select all

   DEFINE WINDOW Form_ROUTE;

      ...
      ...

      @ 70,30 GRID Grid_ROUTE		;
         WIDTH  435			;
         HEIGHT 480			;
         HEADERS {'Dichter', 'Titel', 'Aktief' , 'Tekst file'};
         WIDTHS  { 200,       200 ,     25     , 300  } ;
         JUSTIFY {GRID_JTFY_LEFT, GRID_JTFY_LEFT, GRID_JTFY_LEFT, GRID_JTFY_LEFT};
         FONT "Arial" SIZE 09	   ;
         VALUE {1,1} ;
         ITEMS aRows ;
         CELLNAVIGATION ;
     		BACKCOLOR   {253,        254,         184       } ;
         DYNAMICBACKCOLOR { bColor1 , bColor1 , bColor2 , bColor1 } 

      Define_Control_Context_Menu("Form_ROUTE","Grid_ROUTE", 1, 1, '', '') // Needs to start definition for this control
  
      Define_Column_ToolTip("Form_ROUTE","Grid_ROUTE") 
   END WINDOW
   SET CONTROL Grid_ROUTE OF Form_ROUTE ONMOUSEEVENT Check_Grid_Events()
   SetProperty('Form_ROUTE','Grid_ROUTE', 'Value', 1 )
   SetProperty('Form_ROUTE','Grid_ROUTE', 'SetFocus', TRUE )
   SetProperty('Form_ROUTE','BT_S', 'Enabled', PROT )

   CENTER WINDOW Form_ROUTE

   ACTIVATE WINDOW Form_ROUTE
return




STATIC FUNCTION Check_Grid_Events()
/**********************************/
LOCAL aCell, nMsg := EventMsg()
STATIC cCtrlSelected := ""

IF nMsg == WM_RBUTTONDOWN
   aCell := GetCellClicked("Form_ROUTE", "Grid_ROUTE")
   IF EMPTY(aCell) .OR. aCell [1] == 0
      RETURN Nil
   ENDIF
   
   SetProperty("Form_ROUTE", "Grid_ROUTE", "Value", aCell)
   

   cKEY1 := aRows [ aCell [1], 1 ] + '#' + aRows [ aCell [1], 2 ] + '#' + aRows [ aCell [1], 4 ] // HIER
   Define_Control_Context_Menu("Form_ROUTE", "Grid_ROUTE", aCell[2], aCell[1], cKEY1, ALLTRIM(aRows [ aCell [1], 2 ]) )
ENDIF
RETURN Nil



STATIC FUNCTION GetCellClicked(cForm,cControl)
/********************************************/
LOCAL aRet, nIndex := GetControlIndex(cControl,cForm)
LOCAL aCellData := _GetGridCellData(nIndex)

aRet := {aCellData[1],aCellData[2]}
RETURN aRet






STATIC FUNCTION Define_Control_Context_Menu(cParentForm, cControl, nColumn, nRow, cKEY1, cKEY2)
/**********************************************************************************************/
IF IsControlContextMenuDefined( cControl, cParentForm )
   ReleaseControlContextMenu( cControl, cParentForm )
ENDIF

IF !EMPTY(cKEY1)
   DEFINE CONTROL CONTEXTMENU &cControl OF &cParentForm
      ITEM " Aktiveer    " + cKEY2     ACTION Aktiveer(cKEY1, 'J')
      ITEM " DesAktiveer " + cKEY2     ACTION Aktiveer(cKEY1, 'N')
      ITEM " Vernieuw    " + cKEY2     ACTION Vernieuw(cKEY1)
      ITEM " Open tekst  " + cKEY2     ACTION Open_RTF(cKEY1)
      ITEM " Verwijder   " + cKEY2     ACTION Aktiveer(cKEY1, 'X')
   END MENU
ENDIF


RETURN Nil





STATIC FUNCTION Define_Column_ToolTip(cParentForm,cControl)
/**********************************************************/
LOCAL nColumn := GetProperty(cParentForm,cControl, "CellColFocused")
LOCAL nRow    := GetProperty(cParentForm,cControl, "CellRowFocused")

_SetToolTip(cControl,cParentForm, 'Klik rechts voor opties' )

RETURN Nil
This gives tooltip on right click ('Klik rechts voor opties') and when you click right it will show options

Code: Select all

" Aktiveer    " + cKEY2 
" DesAktiveer " + cKEY2 
" Vernieuw    " + cKEY2 
" Open tekst  " + cKEY2 
" Verwijder   " + cKEY2 
Let me know if this is what you want!

Serge

Re: Dynamic Display in a Context Menu

Posted: Mon Jun 13, 2022 7:47 pm
by Red2
Hi Serge,

Thank you for kindly supplying your segment of code. I really appreciate it.

I am now figuring out how I can apply your code.
Unfortunately I will need time to work this out because:
1) My project is based on the HMG IDE.
2) My grid control uses a .DBF file rather than an array.

I am carefully delving into this.
Thanks again for your generosity and help.
Red2

Re: Dynamic Display in a Context Menu

Posted: Mon Jun 13, 2022 9:05 pm
by serge_girard
I never use grid+dbf, except when dbf is loaded into an array. This way I keep dbf free. And of course filters in order to minimise number of records and paging.

Success!

Re: Dynamic Display in a Context Menu

Posted: Tue Jun 14, 2022 6:06 pm
by Red2
Hi Serge,

Thank you. I really appreciate your knowledge and the code you shared.
Yes, you understood what I wanted.

I adapted your STATIC FUNCTION Check_Grid_Events() code.
Now when a Grid row is Right-Clicked it correctly displays the
CONTEXT MENU message that is specific to that individual Grid row.
This is exactly what I wanted.

In testing I encounter one issue, however.
When the grid's HEADER is Right-Clicked an (unwanted) CONTEXT MENU appears.
It erroneously displays the CONTEXT MENU from the last actual Grid Row that had focus.

Apparently

Code: Select all

laCell := GetCellClicked( "DataBrowse", "BrowseStates" ) 
ONLY acknowledges actual Grid data row cell focus, not a HEADER click.

Question:
What can I do in FUNCTION Check_Grid_Events() to trap when the HEADER is clicked?
(The Grid's OnHeadClick event happens AFTER this Check_Grid_Events call).

Thanks again,
Red2

Re: Dynamic Display in a Context Menu

Posted: Tue Jun 14, 2022 9:39 pm
by serge_girard
Hi Red,

I am about leaving my home for a holiday for 3 weeks so at the moment I cannot help further.
I might think that best way is to check aRet := {aCellData[1],aCellData[2] content.

Good luck !


Serge

PS It is not my code! I found it somewhere in the samples or whatever...

Re: Dynamic Display in a Context Menu

Posted: Thu Jun 16, 2022 2:04 pm
by Red2
Hi All,

Thank you Serge. Have a great holiday. You have been 100% helpful!

My Question:
Can anyone with more experience suggest a way to Release/Cancel an activated
CONTEXT MENU Definition AFTER no MenuItem was selected?
Mi pregunta:
¿Puede alguien con más experiencia sugerir una forma de Release/Cancel una
CONTEXT MENU Definition activada DESPUÉS de que no se seleccionó ningún MenuItem?

I see two ways to prevent the CONTEXT MENU appearing after the Header is Right-Click.
  • More complicated: Hook into the very beginning of the CONTEXT MENU event.
    When it fires and a Right-Click is inside the Header Line, Cancel the event.

    More promising: After the CONTEXT MENU event finishes simply Release its Definition.
    This will work. My code Defines the CONTEXT MENU each time a Grid line is Right-Clicked.
At the end of my ACTION code I added:

Code: Select all

IF ( IsControlContextMenuDefined( "BrowseStates", "DataBrowse" ) )
	ReleaseControlContextMenu( "BrowseStates", "DataBrowse" )
ENDIF
BUT, this is sufficient if, and ONLY if, the user actually selects a MenuItem.
The issue: If nothing is selected then the ACTION never fires.

Thank you all for your kind help,
Red2

Re: Dynamic Display in a Context Menu

Posted: Mon Jun 20, 2022 4:24 pm
by Red2
It seems that Serge's code along with the following two additions is the best solution HMG will allow.
#1 - In the Grid's OnChange event release any CONTEXTMENU
#2 - When the CONTEXTMENU ACTION fires make sure the code finishes by releasing any CONTEXTMENU.
Altogether this displays what I want, generally.

So, on a Right-Click Check_Grid_Events() creates a row-specific CONTEXTMENU.
It will then be removed by the user's next action UNLESS the user immediately clicks
inside the Grid's Header where it will still appear (not having been removed).

Unfortunately I do not see how to eliminate this one "bug".
I am forced to accept this possibility to get a CONTEXTMENU that is specifically customized to each Grid Row.

If anyone can suggest another solution please do. I would greatly appreciate your ideas!
Thanks again,
Red2