'====================================================================
' Richedit with Menu, PopupMenu and Accelerators, modeless dialog as main.
'====================================================================

'% review

uses dialogs
'namespace


% DS_CENTER=0x0800
% SWP_NOZORDER=4
% ENM_MOUSEEVENTS=0x20000
% EM_SETEVENTMASK=0x445
% EN_MSGFILTER=0x700
% TPM_LEFTALIGN=0
% TPM_TOPALIGN=0
% TPM_RETURNCMD=0x100
% TPM_HORPOSANIMATION=0x0400

'Notification messages
type MSGFILTER  
  NMHDR nmhdr 
  uint msg  
  sys wParam  
  sys lParam 
end type 

! GetDlgItem lib "user32.dll" (sys hDlg, int nIDDlgItem) as sys
! IsDialogMessage lib "user32.dll" alias"IsDialogMessageA" (sys hDlg, lpMsg) as bool
! ClientToScreen lib "user32.dll" (sys hWnd, LPPOINT lpPoint) as bool

declare sub initMenu(hDlg)

==============================================

'MAIN CODE
=============================================
 
'dim nCmdline as asciiz ptr, hInstance as sys
'&nCmdline = GetCommandLine
'hInstance = GetModuleHandle(NULL)

% IDC_RICHEDIT	101

sys hMenu 
sys hMenuPopup
sys hAccel

function DlgProc( sys hDlg, uint uMsg, sys wParam, lParam ) as int callback

   POINT pt
   
   select case uMsg
  
     case WM_INITDIALOG
        hMenu = initMenu(hDlg)

        'Richedit should receive mouse events notifications
        SendMessage GetDlgItem(hDlg,IDC_RICHEDIT),EM_SETEVENTMASK,0,ENM_MOUSEEVENTS                

        'Create PopupMenu for right click
        PopupMENU(hMenuPopup)
        BEGIN
           MENUITEM "Undo" tab "Ctrl+Z",1200
           MENUITEM "Redo" tab "Ctrl+Y",1502
           MENUITEM "SEPARATOR"
           MENUITEM "Copy " tab " Ctrl+C",1202
           MENUITEM "Paste " tab " Ctrl+Vl",1203
           MENUITEM "Cut " tab " Ctrl+X",1201
           MENUITEM "SEPARATOR"
           MENUITEM "Select All " tab " Ctrl+A",1204
        ENDMenu

        ShowWindow(hDlg, SW_NORMAL)

     case WM_COMMAND
        select case loword(wParam)
          case IDCANCEL, 1180
             DestroyWindow( hDlg, null )
          case 1909
             mbox "Oxgen Menu Template"
          case 101 'Richedit
#ifdef review
  printl
  print loword(wParam) & chr(13) & chr(10) 'id
  print hiword(wParam) & chr(13) & chr(10) 'event
#endif    
          case else
             mbox loword(wParam) & " clicked!"
        end select

      case WM_SIZE      
         RECT rcClient
      
         // Calculate remaining height and size edit
         GetClientRect(hDlg, &rcClient)
         sys hRichEdit = GetDlgItem(hDlg, IDC_RICHEDIT)
         SetWindowPos(hRichEdit, NULL, 0, rcClient.top, rcClient.right, rcClient.bottom, SWP_NOZORDER)

     case WM_NOTIFY
        'RightClick in Richedit
        NMHDR lpnmhdr at lParam
        if lpnmhdr.code=EN_MSGFILTER then
           MSGFILTER lpmsgfilter at lParam
           if lpmsgfilter.msg=WM_RBUTTONDOWN then

             'Get Mouse position
              pt.x=loword(lpmsgfilter.lParam)
              pt.y=hiword(lpmsgfilter.lParam)
              ClientToScreen hDlg, @pt                              

              int i = TrackPopupMenu( hMenuPopup,
                                TPM_LEFTALIGN or
                                TPM_RETURNCMD or
                                TPM_TOPALIGN or
                                TPM_HORPOSANIMATION,
                                pt.x,
                                pt.y,
                                0,
                                hDlg,
                                0 )

              MessageBox( hDlg, "Selected ID = "& i, "From TrackPopupMenu", 0 )
            endif
        endif
      
     case WM_CLOSE
        DestroyWindow( hDlg )

     case WM_DESTROY
        'not assigned to a window
        DestroyMenu(hMenuPopup)
        DestroyAcceleratorTable( hAccel )
        PostQuitMessage( null )
                
   end select

   return 0
end function


sub winmain()

   init_common_controls
   LoadLibrary("RICHED20.DLL")
   
   sys hDlg, bRet
   MSG Msg

   sys lpdt  
   'provide memory for DLGTEMPLATE structure etc    
   'dyn::init(lpdt, nBytes)
   dyn::init(lpdt)  '1024

   Dialog( 1,  0, 0, 200, 100, "Memory based modeless dialog using OxygenBasic", lpdt,
                WS_OVERLAPPEDWINDOW or DS_CENTER )
   RichEdit( "Richedit", IDC_RICHEDIT, 0, 0, 200, 100, ES_AUTOHSCROLL or WS_HSCROLL )

   hDlg = CreateModelessDialog( null, @DlgProc, 0, lpdt )

   while (bRet := GetMessage(&Msg, NULL, 0, 0)) != 0
     if bRet = -1 then
       'show an error message
       print "Error in Message Loop"
       end
     else
       if TranslateAccelerator( hDlg, hAccel, @Msg ) = 0 then     
         if not IsDialogMessage(hDlg, &Msg) then
           TranslateMessage(&Msg)
           DispatchMessage(&Msg)
         end if
       end if
     end if
   wend

end sub

winmain()

===========================================================

sub initMenu(sys hDlg)
   ' a la .rc file
   MENU(hMenu)

   BEGIN
     POPUP "&File"
     BEGIN
       POPUP "&New"
       BEGIN
         MENUITEM "&Empty file",1100
         POPUP "By template &file..."
         BEGIN
           MENUITEM "Template 1",1102,CHECKED
           MENUITEM "Template 2",1103
           MENUITEM "Template 3",1104
         ENDMenu
         MENUITEM "SEPARATOR"
         MENUITEM "Empty &window",1105
       ENDMenu
       MENUITEM "&Open..." tab "Ctrl+O",1110
       MENUITEM "&Save" tab "Ctrl+S",1111
       MENUITEM "Save &as..." tab "F12",1112
       MENUITEM "SEPARATOR"
       MENUITEM "E&xit" tab "Alt+F4",1180
     ENDMenu
     POPUP "&Edit"
     BEGIN
       MENUITEM "U&ndo" tab "Ctrl+Z",1200,GRAYED
       MENUITEM "SEPARATOR"
       MENUITEM "&Cut" tab "Ctrl+X",1201,GRAYED
       MENUITEM "C&opy" tab "Ctrl+C",1202,GRAYED
       MENUITEM "&Paste" tab "Ctrl+V",1203
       MENUITEM "SEPARATOR"
       MENUITEM "Select &all" tab "Ctrl+A",1204
     ENDMenu
     MENUITEM "&Compile!",1301
     MENUITEM "&Run!",1302
     POPUP "&Tools"
     BEGIN
       MENUITEM "&Compile" tab "F5",1301
       MENUITEM "&Run" tab "F6",1302
       MENUITEM "SEPARATOR"
       MENUITEM "&Edit Resources" tab "F7",1311
       MENUITEM "SEPARATOR"
       MENUITEM "Code &formatter...",1321
     ENDMenu
     POPUP "&Options"
        BEGIN
       MENUITEM "&Font settings...",1401
       MENUITEM "&General settings...",1402
       MENUITEM "&Project settings...",1403
       MENUITEM "SEPARATOR"
       MENUITEM "Auto &indent",1411
     ENDMenu
     POPUP "&Help"
     BEGIN
       MENUITEM "Help &keyword..." tab "F1",1900
       MENUITEM "&Basic help" tab "Shift+F1",1901
       MENUITEM "&API help" tab "Alt+F1",1902
       MENUITEM "&Editor help" tab "Ctrl+F1",1903
       MENUITEM "SEPARATOR"
       MENUITEM "Ab&out",1909
     ENDMenu
   ENDMenu

   if SetMenu( hDlg, hMenu ) = 0 then
     mbox "SetMenu hMenu failed!"
   end if


   'Accelerators
   indexbase 0
   
   ACCEL accl[9] = {
   {FVIRTKEY | FCONTROL, asc("O"),      1110 },
   {FVIRTKEY | FCONTROL, asc("S"),      1111 },
   {FVIRTKEY           , VK_F12,        1112 },               
   {FVIRTKEY           , VK_F5,         1301 },               
   {FVIRTKEY           , VK_F6,         1302 },               
   {FVIRTKEY           , VK_F7,         1311 },           
   {FVIRTKEY | FSHIFT  , VK_F1,         1901 },  
   {FVIRTKEY | FALT    , VK_F1,         1902 },    
   {FVIRTKEY           , VK_F1,         1900 },           
   {FVIRTKEY | FCONTROL, VK_F1,         1903 } 
   }

   hAccel = CreateAcceleratorTable( @accl, 10 )

end sub

