{ Example of a program using the  wMenus0.pp  unit.
  This is the second example which uses really the Message file, and
  and a description of its menu in the message file.
  It uses the facilities of the library.
  The menu is generated automatically, because the corresponding
  message file exist (tEx031.msg) and line index 10000 is :
  10000 AutoCreate
  # here the menu description comes, c.f. tEx031.msg

  Also the handling of window messages is done automatically,
  the disposal of the menu object also.

  If you remove all comments, you get a very short programme, having
  a menu, a status line, information displayed in the status line
  when you are in the menu.
  The  WMCommand(...)  is the heart of the program.
  When a menu is selected, it calls the desired action.
  For the moment, does not much.

  In the next example, tEx032.pp, a little text editor will be demonstrated,
  similar to the one of example tEx008.pp
  See how many code lines have been removed, because they are automatically
  treated in the library.
  --------------------------------------------}
program tEx031;

// To tell FreePascal that the application is a Graphical User Interface
// i.e. is running in windows, not in text mode.
{$APPTYPE GUI}

Uses
  Windows
// ,wGlobals2
 ,wApplication0
 ,wWindow0
// ,wStatusLine0 use the status of the library.
// ,wMenus0 use the automatic creation of the library.
 ,wDebug0;

type
  PMyWindow = ^TMyWindow;
  TMyWindow = object(TWindow)
  //"""""""""""""""""""""""""

  constructor Init(strWinTitlePrm:ShortString);
//  destructor Done; virtual; useless, all is done in the parent object

//  procedure WinCreate(strWinClass:ShortString); virtual; useless, all is done in the parent object
  // Set  strWinClass=''  to use the class defined in the application object

  procedure TestMenu1;
  // First test to see the number value a menu type can have.

  function WMCommand(wPar:WPARAM; lPar:LPARAM):LRESULT; virtual;
  // Handles the menu messages

//  function WindowProc(hWindow:HWND; wMsg:UINT; wPar:WPARAM; lPar:LPARAM):LRESULT; virtual;
  // Even the WindowProc is useless.
  end; // TMyWindow = object(TWindow)

// var nNotUsed : integer; // only to avoid an error message while compliling in DevPascal 1.9

constructor TMyWindow.Init(strWinTitlePrm:ShortString);
//=====================================================
begin
inherited Init(strWinTitlePrm);

// This line is all what is needed to have a status line.
new(poStatusLine, Init(@Self));
end;  // TMyWindow.Init
{
destructor TMyWindow.Done;
//========================
// It's useless to define a destructor
begin
// dispose(poStatusLine, Done); useless, it's done in the parent object.

inherited Done;
end;  // TMyWindow.Done
}
{
procedure TMyWindow.WinCreate(strWinClass:ShortString);
//=====================================================
// Create the window, and insert a status line in it.
begin
// here strWinClass=''.
inherited WinCreate(strWinClass);
end;  // TMyWindow.WinCreate
}
procedure TMyWindow.TestMenu1;
//============================
// First test to see the number value a menu type can have.
begin
DBW0(1, 'MF_POPUP        = ' + ITS(MF_POPUP));
DBW0(1, 'MF_BITMAP       = ' + ITS(MF_BITMAP));
DBW0(1, 'MF_CHECKED      = ' + ITS(MF_CHECKED));
DBW0(1, 'MF_STRING       = ' + ITS(MF_STRING));
DBW0(1, 'MF_OWNERDRAW    = ' + ITS(MF_OWNERDRAW));
DBW0(1, 'MF_CHECKED      = ' + ITS(MF_CHECKED));
DBW0(1, 'MF_DISABLED     = ' + ITS(MF_DISABLED));
DBW0(1, 'MF_ENABLED      = ' + ITS(MF_ENABLED));
DBW0(1, 'MF_GRAYED       = ' + ITS(MF_GRAYED));
DBW0(1, 'MF_MENUBARBREAK = ' + ITS(MF_MENUBARBREAK));
DBW0(1, 'MF_MENUBREAK    = ' + ITS(MF_MENUBREAK));
DBW0(1, 'MF_OWNERDRAW    = ' + ITS(MF_OWNERDRAW));
DBW0(1, 'MF_SEPARATOR    = ' + ITS(MF_SEPARATOR));
DBW0(1, 'MF_UNCHECKED    = ' + ITS(MF_UNCHECKED));
{
MF_SEPARATOR    =       2048
MF_POPUP        =         16
MF_STRING       =          0
MF_OWNERDRAW    =        256
MF_MENUBREAK    =         64
MF_MENUBARBREAK =         32
MF_CHECKED      =          8
MF_BITMAP       =          4
MF_DISABLED     =          2
MF_GRAYED       =          1
MF_ENABLED      =          0
MF_UNCHECKED    =          0

This tells us that number above the sum of these numbers are not used
in the Menu Type. Thus it can be used for other information.
It will be used to remember the position of popup menus, since
it's the only way to identify them.
}
end;  // TMyWindow.TestMenu1

function TMyWindow.WMCommand(wPar:WPARAM; lPar:LPARAM):LRESULT;
//=============================================================
// Handles the menu messages
Var wNrMenu     : word;
begin
WMCommand := 0; // Default return value when processing a message

if (lPar <> 0) then begin
   // call the parent WMCommand method.
   WMCommand:=inherited WMCommand(wPar, lPar);
   exit;
   end;

// for the menus,  lPar = 0
//=========================
wNrMenu   := LoWord(wPar);
Case wNrMenu Of
   101 : TestMenu1;
   401 : MessageBox( hWin,'To see the simplicity of the menu creation',
                     'How easy it is to have a menu and status line.',
                     MB_OK Or MB_IconInformation);
   600..610 : // toggle the check mark
      poMenu^.CheckMenuItemID(wNrMenu, 8096);

   701..703 : // disable menus
      poMenu^.EnableMenuItemID(wNrMenu-100, MF_GRAYED);

   711..713 : // enable menus
      poMenu^.EnableMenuItemID(wNrMenu-110, MF_ENABLED);

   805..807 : // disable menus
      poMenu^.EnableMenuItemID(wNrMenu-200, MF_GRAYED);

   815..817 : // enable menus
      poMenu^.EnableMenuItemID(wNrMenu-210, MF_ENABLED);

   901 : begin // disable the complete check marks menu
      poMenu^.EnableMenuItemByMsgNum(10001, MF_GRAYED);
      DrawMenuBar(hWin); // must redraw the menu bar
      end;

   902 : begin // enable the complete check marks menu
      poMenu^.EnableMenuItemByMsgNum(10001, MF_ENABLED);
      DrawMenuBar(hWin); // must redraw the menu bar
      end;



   else WMCommand:=inherited WMCommand(wPar, lPar);
   end;  // Case NrMenu Of
end;  // TMyWindow.WMCommand

var
  oApp        : TApplication;
  poMyMainWin : PMyWindow;

Begin // MAIN ******
// Name under which the main window is registered. Spaces are not allowed
oApp.Init('Example031');

// Creation of the main window
new(poMyMainWin, Init('tEx031. Example were the menu is created automatically'));

// The App.WindowClass can be modified here, if wanted. (Not usual)
oApp.Run;
oApp.Done;  // The main window object is disposed here.
End.

