Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

@Source: Event and Screen

Statements exclusive to Screen files.

Event

Event StandardName
    ...
EndEvent

Event 'Label' KeyNumber ["Text"]
    ...
EndEvent

Two forms: standard event (bare, unquoted name) or a custom event attached to a function key (quoted name + key number, 1-24, i.e. F1-F24; F13-F24 via Shift).

Standard events

EventWhen it fires
EnterOn pressing Enter (with no function key active). CurrentInput() identifies which Input had focus, decoded from the cursor position after EXFMT.
CloseFixed to F3 in the generated DSPF (CF03) — always runs (even empty) and ends the screen; doesn’t require a declaration to attach the key.
LoadOnce, before the first display — typically contains the For Each/LoadRow() that fills the DataGridView (the grid is reset on entry). Page Up/Down are native scrolling over what’s already loaded; this event only runs again with Refresh/Refresh Keep or F5 (see below).
RefreshOn pressing F5, if F5 is declared in the .warpcfg’s @FunctionKeys and isn’t taken by a custom Event 'Name' 5. Runs Event Refresh (if it exists) and then reloads the DataGridView (if the Screen has one with an Event Load). See Refresh and Refresh Keep.
InitOnce, the first time this screen starts, before the first display. Does nothing if not declared. The only place in a Screen where Member(...) is valid — see Reports with Member()/Export().

Custom events

Event 'FindCustomer' 4
    Message("F4 was pressed", Info)
EndEvent

By default, the label shown on the screen’s function-key line is the event name (F4=FindCustomer).

Key text

After the key number you can add an optional quoted text, which is what is shown on that line (F4=Find):

Event 'FindCustomer' 4 "Find"
    Message("F4 was pressed", Info)
EndEvent
  • Only allowed on key-bound events (1-24); it cannot be empty or longer than 20 characters (E00344).
  • If omitted, the event name is used.
  • The event name becomes the name of an RPG subprocedure, so it must be an identifier (letters, digits and _, starting with a letter); otherwise it is error E00357. Text with spaces goes in the third value: Event 'Name' 6 "Text with spaces".
  • The Event text takes precedence over any text declared for that same key in the project’s .warpcfg @FunctionKeys (see Project), just as the name did before.

Key color

At the end you can add a color, with or without text: Green, White, Red, Blue, Yellow, Pink or Turquoise (the same as Style):

Event 'Delete' 7 "Delete" Red
    Message("Record deleted", Info)
EndEvent

Event 'Find' 4 Blue
    Message("F4 was pressed", Info)
EndEvent
  • Text and color are both optional; without text the event name is used (F4=Find in the second example).
  • The key’s color takes precedence over Function Keys Color (from @Properties or @Screen). It also applies to each set of the F24 rotation.
  • An invalid color gives E00347.
  • Keys declared only in @FunctionKeys have no color of their own; they use Function Keys Color.

Message

Message(text, Error|Warning|Info)

Shows a message on the screen’s message line: Error (red), Warning (yellow), Info (normal text color). Shown on the next screen refresh and cleared after one cycle.

LoadRow / RefreshSelectRow / For Each Row

Exclusive to screens with a DataGridView — see the full guide: DataGridView.

StatementUse
LoadRow()No arguments. Takes the current values of the variables bound to each Column and appends a row to the grid. Valid in the body of any Event of a Screen (directly, inside If, Case, While, For or For Each) and in any Procedure. In Event Load the grid is reset on entry; in any other Event or Procedure the rows are appended to the existing ones. Not allowed in a Function or outside an Event/Procedure (E00198). A For Each that loads the grid must declare Index.
RefreshSelectRow()No arguments. The reverse of LoadRow(): re-reads the row under the cursor and writes each column (including Hidden ones) back into its bound variable. Valid in any Event of a Screen with a DataGridView.
For Each Row ... EndForIterates over every row already loaded into the subfile (not the table), writing each Column into its bound variable before every iteration. No Index/Where/When None.

CurrentInput

&Control = CurrentInput()

Returns the Name of the Input/DataGridView (from @Layout) that currently has focus. For a DataGridView, it matches if the cursor lands anywhere in its rectangle (header, attention row, or any data row), not just an exact cell. Valid in any Event, Procedure or Function of a Screen (a Procedure called from an event sees the position as well), because the driver computes the cursor position after every screen read. It is not valid in loose top-level @Source statements (they never run) nor outside a Screen: that is error E00192. If the Procedure is invoked from Event Init (before the first read), the cursor has no position yet and CurrentInput() returns empty.

Cursor

If Cursor(&Codigo)
    &Aviso = "Code help"
EndIf

It is true when the cursor is on the control bound to &Codigo, either an Input or a visible column of the @Layout’s DataGridView. Use it as a direct condition; do not combine it with = 1, since the result is already a condition.

  • For an Input it compares the field’s row and column range.
  • For a grid column it compares the data rows and that column’s column range. A Hidden column never matches.
  • Same scope as CurrentInput(): Event, Procedure or Function of a Screen (E00192 elsewhere). If invoked from Event Init there is no position yet and it is false.
  • Errors: E00336 (argument count), E00337 (argument is not a &variable), E00338 (the variable is not that of any Input or grid column).

Example inside a Procedure (see example/screens/SFOCUS01.warp):

Procedure PideAyuda()
    If Cursor(&Cod)
        &Aviso = "Code help"
    Else
        If Cursor(&Descrip)
            &Aviso = "Description help"
        EndIf
    EndIf
EndProc

Refresh and Refresh Keep: reload the DataGridView

Refresh
Refresh Keep

Argument-less statements that reload the screen’s DataGridView. The reload is not immediate: code after the Refresh in the same event keeps running, and when the driver starts its next loop the subfile is cleared and Event Load runs again.

  • Refresh goes back to the first row.
  • Refresh Keep keeps the row where the user was (clamped to the new total if the grid ended up with fewer rows).

Rules:

  • Only valid in a Screen; in any other source type they give E00335. If the Screen has no DataGridView, they do nothing.
  • They can be called from any Event or Procedure.
  • They are not reserved words: an Event Refresh and a field named Refresh keep working.
  • Limitation: the reload repeats the first-load sequence. A Refresh inside Event Load is evaluated again on every loop.

Example (see example/screens/SREFRSH01.warp):

Event Enter
    Refresh Keep
EndEvent

F5 behavior change

If F5 is declared in @FunctionKeys and no custom event claims it, F5 runs Event Refresh (if it exists) and then reloads the DataGridView (if the Screen has one with an Event Load). Previously it only called Event Refresh. So Event Refresh is the place to prepare data (for example, clear a filter) before the reload.

SetFocus: place the cursor

&Variable.SetFocus()

Puts the cursor on the Input whose variable is &Variable the next time the screen is shown. It is a statement: it returns no value.

  • Only valid in a Screen (E00331).
  • The variable must be the variable of some Input in @Layout (E00332).
  • It takes no arguments (E00333).
  • It is not an expression and cannot be used inside one (E00334).
  • If there are several SetFocus in the same loop, the first one wins.
  • It can be used in Event Init to set the initial focus.
Event Init
    &Cod.SetFocus()
EndEvent

Event Enter
    If &Cod = ""
        &Aviso = "Code is missing"
        &Cod.SetFocus()
    EndIf
EndEvent

Full example: example/screens/SFOCUS01.warp.

Implementation (for the advanced reader): the compiler writes the field’s row and column into hidden CSRLOC fields and resets them to zero after each read. On screens with a DataGridView it uses the grid’s CSRLOC fields. In popups the coordinates are relative to the window.