#lang racket/base (require ffi/unsafe scheme/class "utils.rkt" "types.rkt" "const.rkt" "../../lock.rkt" "../../syntax.rkt") (provide (protect-out menu-item% id-to-menu-item)) ;; Menu itens are identified by 16-bit numbers, so we have ;; to keep a hash mapping them to menu items. (define ids (make-hash)) (define (id-to-menu-item id) (let ([wb (atomically (hash-ref ids id #f))]) (and wb (weak-box-value wb)))) (defclass menu-item% object% (define id (let loop () (let ([id (add1 (random #x7FFE))]) (let ([wb (atomically (hash-ref ids id #f))]) (if (and wb (weak-box-value wb)) (loop) (begin (atomically (hash-set! ids id (make-weak-box this))) id)))))) (define parent #f) (define label #f) (define checkable? #f) (define submenu #f) (define/public (set-parent p lbl chkbl? subm) (set! parent p) (set! label lbl) (set! checkable? chkbl?) (set! submenu subm) id) (define/public (set-label hmenu pos str) (if submenu (ModifyMenuW hmenu pos (bitwise-ior MF_BYPOSITION MF_STRING MF_POPUP) (cast (send submenu get-hmenu) _HMENU _UINT_PTR) str) (ModifyMenuW hmenu pos (bitwise-ior MF_BYPOSITION MF_STRING (GetMenuState hmenu pos MF_BYPOSITION)) id str))) (define/public (set-check hmenu pos on?) (void (CheckMenuItem hmenu pos (bitwise-ior MF_BYPOSITION (if on? MF_CHECKED MF_UNCHECKED))))) (define/public (get-check hmenu pos) (let ([s (GetMenuState hmenu pos MF_BYPOSITION)]) (not (zero? (bitwise-and s MF_CHECKED))))) (public [get-id id]) (define (get-id) id) (super-new))