home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 16 / CD_ASCQ_16_0994.iso / news / 4611 / fw16d.ins / SOURCE / CLASSES / MENU.PRG < prev    next >
Text File  |  1994-06-10  |  9KB  |  317 lines

  1. #include "FiveWin.ch"
  2.  
  3. #define MF_ENABLED       0
  4. #define MF_GRAYED        1
  5. #define MF_DISABLED      2
  6. #define MF_BITMAP        4
  7. #define MF_CHECKED       8
  8. #define MF_POPUP        16  // 0x0010
  9. #define MF_BYPOSITION 1024  // 0x0400
  10. #define MF_SEPARATOR  2048  // 0x0800
  11. #define MF_HILITE      128  // 0x0080
  12. #define MF_UNHILITE      0
  13.  
  14. static oLastItem
  15. static hClass
  16.  
  17. //----------------------------------------------------------------------------//
  18.  
  19. CLASS TMenu
  20.  
  21.    DATA   hMenu
  22.    DATA   aItems
  23.    DATA   oWnd
  24.    DATA   lSysMenu, lPopup
  25.  
  26.    METHOD New( lPopup, oWnd )  CONSTRUCTOR
  27.    METHOD ReDefine( cResName, lPopup ) CONSTRUCTOR
  28.    METHOD NewSys( oWnd )       CONSTRUCTOR
  29.    METHOD Add( oMenuItem )
  30.    METHOD Command( nCommand )
  31.  
  32.    METHOD LastItem() INLINE oLastItem
  33.  
  34.    METHOD GetMenuItem( nItemId ) INLINE  SearchItem( ::aItems, nItemId )
  35.  
  36.    METHOD Activate( nRow, nCol, oWnd )
  37.  
  38.    METHOD Refresh() INLINE ::oWnd:SetMenu( Self )
  39.  
  40.    METHOD Reset() INLINE If( ::lSysMenu, GetSystemMenu( ::oWnd:hWnd, .t. ),;
  41.                          DestroyMenu( ::hMenu ) ), ::hMenu := CreateMenu(),;
  42.                          ::aItems := {}
  43.  
  44.    METHOD Release() INLINE ReleaseItems( ::aItems )
  45.  
  46.    METHOD End() INLINE If( ::oWnd != nil, SetMenu( ::oWnd:hWnd, 0 ),),;
  47.                            DestroyMenu( ::hMenu )
  48.  
  49.    METHOD Hilite( nPopUp ) INLINE ;
  50.                            HiliteMenuItem( ::oWnd:hWnd, ::hMenu, nPopUp - 1,;
  51.                                            nOr( MF_HILITE, MF_BYPOSITION ) )
  52.  
  53.    METHOD UnHilite( nPopUp ) INLINE ;
  54.                            HiliteMenuItem( ::oWnd:hWnd, ::hMenu, nPopUp - 1,;
  55.                                            nOr( MF_UNHILITE, MF_BYPOSITION ) )
  56.    METHOD AddMdi()
  57.  
  58. ENDCLASS
  59.  
  60. //----------------------------------------------------------------------------//
  61.  
  62. METHOD New( lPopup, oWnd ) CLASS TMenu
  63.  
  64.    DEFAULT lPopup := .f.
  65.  
  66.    ::hMenu    = If( lPopup, CreatePopupMenu(), CreateMenu() )
  67.    ::aItems   = {}
  68.    ::lSysMenu = .f.
  69.    ::lPopup   = lPopup
  70.  
  71.    if oWnd != nil
  72.       oWnd:SetMenu( Self )
  73.    endif
  74.  
  75. return nil
  76.  
  77. //----------------------------------------------------------------------------//
  78.  
  79. METHOD ReDefine( cResName, lPopup ) CLASS TMenu
  80.  
  81.    local hMenu := LoadMenu( GetResources(), cResName )
  82.    local n
  83.  
  84.    ::hMenu    = hMenu
  85.    ::aItems   = {}
  86.    ::lSysMenu = .f.
  87.    ::lPopup   = lPopup
  88.  
  89.    if lPopup
  90.       // Windows does not provides a way of storing only Popups in resources
  91.       // so we are going to create one on the fly copying it from the
  92.       // one placed at resources
  93.       ::hMenu = CreatePopupMenu()
  94.       MenuClone( ::hMenu, hMenu )
  95.       DestroyMenu( hMenu )
  96.    endif
  97.  
  98.    ResBuild( Self )
  99.  
  100. return nil
  101.  
  102. //----------------------------------------------------------------------------//
  103.  
  104. METHOD NewSys( oWnd ) CLASS TMenu
  105.  
  106.    local n
  107.  
  108.    if oWnd != nil
  109.       ::oWnd  = oWnd
  110.       ::hMenu = GetSystemMenu( oWnd:hWnd, .f. )
  111.    endif
  112.    ::aItems   = {}
  113.    ::lSysMenu = .t.
  114.  
  115. return nil
  116.  
  117. //----------------------------------------------------------------------------//
  118.  
  119. METHOD Add( oMenuItem ) CLASS TMenu
  120.  
  121.    AAdd( ::aItems, oMenuItem )
  122.  
  123.    oMenuItem:oMenu = Self
  124.  
  125.    if oMenuItem:bAction:ClassName() == "TMENU"
  126.       if oMenuItem:hBitmap == 0
  127.          AppendMenu( ::hMenu, MF_POPUP, oMenuItem:bAction:hMenu,;
  128.                      oMenuItem:cPrompt )
  129.       else
  130.          AppendMenu( ::hMenu, nOR( MF_POPUP, MF_BITMAP ),;
  131.                      oMenuItem:bAction:hMenu, oMenuItem:hBitmap )
  132.       endif
  133.    else
  134.       if oMenuItem:cPrompt != nil
  135.          AppendMenu( ::hMenu,;
  136.                      nOR( If( oMenuItem:lActive, MF_ENABLED,;
  137.                           nOR( MF_DISABLED, MF_GRAYED ) ),;
  138.                           If( oMenuItem:lChecked, MF_CHECKED, 0 ) ),;
  139.                      oMenuItem:nId, oMenuItem:cPrompt )
  140.       else
  141.          if oMenuItem:hBitmap != 0
  142.             AppendMenu( ::hMenu, MF_BITMAP,;
  143.                         oMenuItem:nId, oMenuItem:hBitmap )
  144.          else
  145.             AppendMenu( ::hMenu, MF_SEPARATOR, oMenuItem:nId, "" )
  146.          endif
  147.       endif
  148.    endif
  149.  
  150. return nil
  151.  
  152. //----------------------------------------------------------------------------//
  153.  
  154. METHOD Command( nCommand ) CLASS TMenu
  155.  
  156.    local oMenuItem := ::GetMenuItem( nCommand )
  157.  
  158.    if oMenuItem != nil
  159.       if ValType( oMenuItem:bAction ) == "B"
  160.          oLastItem = oMenuItem
  161.          Eval( oMenuItem:bAction )
  162.       endif
  163.    endif
  164.  
  165. return nil
  166.  
  167. //----------------------------------------------------------------------------//
  168.  
  169. METHOD Activate( nRow, nCol, oWnd ) CLASS TMenu
  170.  
  171.    if oWnd != nil
  172.       oWnd:oPopup = Self
  173.       TrackPopup( ::hMenu, 1, nRow, nCol, 0, oWnd:hWnd )
  174.  
  175.       // We cannot release here oWnd:oPopup since it has not
  176.       // beeing processed the command yet !!!
  177.       // We release oWnd:oPopup after processing the :Command()
  178.       // at TWindow::Command()
  179.  
  180.       SysRefresh()
  181.       oWnd:oPopup = nil
  182.    endif
  183.  
  184. return nil
  185.  
  186. //----------------------------------------------------------------------------//
  187.  
  188. static function SearchItem( aItems, nId )
  189.  
  190.    local n      := 1
  191.    local lFound := .f.
  192.    local oReturn
  193.  
  194.    if hClass == nil
  195.       hClass = TMenu():ClassH()
  196.    endif
  197.  
  198.    while n <= Len( aItems ) .and. ! lFound
  199.       if aItems[ n ]:nId == nId
  200.          return aItems[ n ]
  201.       else
  202.          if aItems[ n ]:bAction:ClassH() == hClass
  203.             if aItems[ n ]:bAction:hMenu == nId
  204.                return nil
  205.             else
  206.                oReturn = SearchItem( aItems[ n ]:bAction:aItems, nId )
  207.                if oReturn != nil
  208.                   exit
  209.                endif
  210.             endif
  211.          endif
  212.       endif
  213.       n++
  214.    end
  215.  
  216. return oReturn
  217.  
  218. //----------------------------------------------------------------------------//
  219.  
  220. static function ReleaseItem( aItems )
  221.  
  222.    local n := 1
  223.    local oItem
  224.  
  225.    if hClass == nil
  226.       hClass = TMenu():ClassH()
  227.    endif
  228.  
  229.    while n <= Len( aItems )
  230.       oItem = aItems[ n ]
  231.       if oItem:bAction != nil
  232.          if oItem:bAction:ClassH() == hClass
  233.             ReleaseItem( oItem:bAction:aItems )
  234.          endif
  235.       endif
  236.       oItem:Release()
  237.       n++
  238.    end
  239.  
  240. return nil
  241.  
  242. //----------------------------------------------------------------------------//
  243.  
  244. static function ResBuild( oMenu )
  245.  
  246.    local n
  247.    local hMenu := oMenu:hMenu
  248.    local hSubMenu
  249.    local oSubMenu, oMenuItem
  250.  
  251.    for n = 1 to GetMItemCount( hMenu )
  252.          oMenuItem          = TMenuItem()
  253.          oMenuItem:nId      = GetMItemID( hMenu, n - 1 )
  254.          oMenuItem:cPrompt  = GetMenuString( hMenu, n - 1, MF_BYPOSITION )
  255.          oMenuItem:cMsg     = ""
  256.          oMenuItem:lChecked = lAnd( GetMenuState( hMenu, n - 1, MF_BYPOSITION ), MF_CHECKED )
  257.          oMenuItem:lActive  = lAnd( GetMenuState( hMenu, n - 1, MF_BYPOSITION ), MF_ENABLED )
  258.          oMenuItem:oMenu    = oMenu
  259.          oMenuItem:hBitmap  = 0
  260.          AAdd( oMenu:aItems, oMenuItem )
  261.          if ( hSubMenu := GetSubMenu( hMenu, n - 1 ) ) != 0
  262.             oSubMenu          = TMenu()
  263.             oSubMenu:hMenu    = hSubMenu
  264.             oSubMenu:lSysMenu = .f.
  265.             oSubMenu:aItems   = {}
  266.             oMenuItem:bAction = oSubMenu
  267.             ResBuild( oSubMenu )
  268.          endif
  269.    next
  270.  
  271. return nil
  272.  
  273. //----------------------------------------------------------------------------//
  274.  
  275. static function MenuClone( hTarget, hSource )
  276.  
  277.    local n
  278.    local hSubTarget, hSubSource
  279.  
  280.    for n = 1 to GetMItemCount( hSource )
  281.       hSubSource = GetSubMenu( hSource, n - 1 )
  282.       if hSubSource != 0
  283.          hSubTarget = CreatePopupMenu()
  284.          MenuClone( hSubTarget, hSubSource )
  285.       endif
  286.       if lAnd( GetMenuState( hSource, n - 1, MF_BYPOSITION ), MF_SEPARATOR )
  287.          AppendMenu( hTarget, MF_SEPARATOR, GetMItemId( hSource, n - 1 ), "" )
  288.       else
  289.          AppendMenu( hTarget,;
  290.                      nLoByte( GetMenuState( hSource, n - 1, MF_BYPOSITION ) ),;
  291.                      If( hSubSource != 0, hSubTarget,;
  292.                          GetMItemId( hSource, n - 1 ) ),;
  293.                      GetMenuString( hSource, n - 1, MF_BYPOSITION ) )
  294.       endif
  295.    next
  296.  
  297. return nil
  298.  
  299. //----------------------------------------------------------------------------//
  300.  
  301. METHOD AddMdi() CLASS TMenu
  302.  
  303.    MENUITEM "&Window"
  304.    MENU
  305.       MENUITEM "&Tile Vertical"   ACTION ::oWnd:Tile()
  306.       MENUITEM "&Tile Horizontal" ACTION ::oWnd:Tile( .t. )
  307.       MENUITEM "&Cascade"         ACTION ::oWnd:Cascade()
  308.       MENUITEM "&Next Window"     ACTION ::oWnd:NextWindow()
  309.       MENUITEM "&Arrange Icons"   ACTION ::oWnd:ArrangeIcons()
  310.       MENUITEM "&Iconize All"     ACTION ::oWnd:IconizeAll()
  311.       MENUITEM "&Close All"       ACTION ::oWnd:CloseAll()
  312.    ENDMENU
  313.  
  314. return nil
  315.  
  316. //----------------------------------------------------------------------------//
  317.