#lang scheme/base

; I require these, to make all my code break if it ever won't let me do the minimum.

(require scheme/gui/base
         scheme/class)

; Nothing to see here, don't mind me folks. <.<

(define my-frame% 
  ; define a special kind of frame.
  ; Sometimes it's necessary to derive a GUI class, to capture
  ; the events that the GUI normally sends to instances of that class.
  
  (class frame%
    ; just pass these on
    (init)
    (super-new)
    ; every my-frame% has its own message label thing!
    (define info (new message% (parent this) (label "Press a Key")))
    
    ; override the on-subwindow-char which gets key-press
    ; events when focus is on this frame, and everything 
    ; contained in this frame.
    (define/override (on-subwindow-char receiver event)
      (let ((code (send event get-key-code)))
        (cond
          ; ignore the 'release code, since it's kinda confusing to display
          ; comment the line below to see what it does.
          ((eq? code 'release) (void))
          (else
           ; set the label of our frame's message
           ; to the write representation (~s)
           ; of whatever key-code just happened
           (send info set-label
                 (format "~s" code)))))
      ; after we did that, pass this event onto
      ; the default on-subwindow-char handler
      ; that frame% comes with.
      (super on-subwindow-char receiver event))))

; tell a new frame to be shown
(send (new my-frame% (label "Keypress info thing")) show #t)

; since it's a my-frame%, key-code events will go to
; my-frame%'s handler for it, whereas if it was just a
; frame% it would never reach my custom handler.

; the program will (yield 'wait) automatically
; which waits until all frames are unshown, then exits.
; see "yield" for more specifics