WITH   Ada.Unchecked_Conversion ;
WITH   Interfaces.C ;
WITH   System ;
WITH   Win32 ;
WITH   Win32.Crt.Strings ;
WITH   Win32.Windef ;
WITH   Win32.Wingdi ;
WITH   Win32.Winuser ;

PACKAGE BODY   CharTb31_Pkg  IS

   FUNCTION   CP   ( I_Str : Win32.CHAR_Array )  RETURN  Win32.LPCSTR  IS
      FUNCTION   UC  IS
         new Ada.Unchecked_Conversion ( System.Address , Win32.LPCSTR );
   BEGIN
      RETURN  UC ( I_Str(I_Str'First)'Address );
   END CP;

   FUNCTION   CPS   ( I_Str : Win32.CHAR_Array )  RETURN  Win32.LPSTR  IS
      FUNCTION   UC  IS
         new Ada.Unchecked_Conversion ( System.Address , Win32.LPSTR );
   BEGIN
      RETURN  UC ( I_Str(I_Str'First)'Address );
   END CPS;

   USE TYPE   Win32.CHAR_Array ;      --- To get "&"

   Nul : Win32.Char RENAMES Win32.Nul ;

   wm_MyAction : CONSTANT := Win32.Winuser.WM_USER + 101 ;

   CRLFz : CONSTANT Win32.CHAR_Array := Win32.Char(Character'Val(13))  &  Win32.Char(Character'Val(10))  &  Nul ;

   L_PaintStruct : ALIASED Win32.Winuser.PAINTSTRUCT ;
   L_Rect        : ALIASED Win32.Windef.RECT := (0,0,0,0);

   L_Buf01z : ALIASED Win32.CHAR_Array(0..1);

   FUNCTION   MainWindow_Proc   ( I_HWnd    : Win32.Windef.HWND
                                ; I_Message : Win32.UINT
                                ; I_WParam  : Win32.WPARAM
                                ; I_LParam  : Win32.LPARAM )  RETURN  Win32.LRESULT  IS
      L_HDC : Win32.Windef.HDC ;
      L_PREV_GdiObj : Win32.Windef.HGDIOBJ ;
      IgnoredH      : Win32.Windef.HGDIOBJ ;

      L_Code : Standard.INTEGER ;
   BEGIN
      CASE I_Message IS
         WHEN wm_MyAction =>
            G_MainMsgBuf(0) := Nul ;

            L_Buf01z(1) := Nul ;

            ----- LOOP 1
            FOR L_i in 0..15 LOOP

               ----- LOOP 2
               FOR L_j in 0..15 LOOP
                  L_Code := L_i*16  +  L_j ;

                  ----- Write char  ( Ignoring problem chars )
                  IF    (L_Code = 0) or (L_Code = 10) or (L_Code = 13)
                     or (L_Code = 38)
                  THEN
                     L_Buf01z(0) := '-' ;
                  ELSE
                     L_Buf01z(0) := Win32.Char(Character'Val(L_Code));
                  END IF;
                  IgnoredP := Win32.Crt.Strings.StrCat ( CPS(G_MainMsgBuf) , CP(L_Buf01z) );
               END LOOP;--j

               IgnoredP := Win32.Crt.Strings.StrCat ( CPS(G_MainMsgBuf) , CP(CRLFz) );
            END LOOP;--i

            ----- Force paint again
            IgnoredB := Win32.Winuser.GetClientRect ( I_HWnd , L_Rect'Access );
            IgnoredB := Win32.Winuser.InvalidateRect ( I_HWnd , L_Rect'Access , Win32.FALSE );

         WHEN Win32.Winuser.WM_PAINT =>
            L_HDC := Win32.Winuser.BeginPaint ( I_HWnd , L_PaintStruct'Access );
            IgnoredB := Win32.Winuser.GetClientRect ( I_HWnd , L_Rect'Access );

            L_PREV_GdiObj := Win32.Wingdi.SelectObject ( L_HDC
                                                       , Win32.Wingdi.GetStockObject(Win32.Wingdi.SYSTEM_FIXED_FONT) );

            IgnoredI := Win32.Winuser.DrawText ( L_HDC
                                               , CP(G_MainMsgBuf)
                                               , Interfaces.C.Int( Win32.Crt.Strings.StrLen(CP(G_MainMsgBuf)) )
                                               , L_Rect'Access
                                               , Win32.Winuser.DT_WORDBREAK );

            IgnoredH := Win32.Wingdi.SelectObject ( L_HDC , L_PREV_GdiObj );
            IgnoredB := Win32.Winuser.EndPaint ( L_HDC , L_PaintStruct'Access );

            ----- Only once...
            IF not G_MainPaintedOnceQ THEN
               G_MainPaintedOnceQ := Standard.TRUE ;
               IgnoredB := Win32.Winuser.PostMessage ( I_HWnd , wm_MyAction , 0 , 0 );      --- "Indirect" call...
            END IF;

         WHEN Win32.Winuser.WM_SIZE =>      --- When window is resized,...
            ----- Force paint again
            IgnoredB := Win32.Winuser.GetClientRect ( I_HWnd , L_Rect'Access );
            IgnoredB := Win32.Winuser.InvalidateRect ( I_HWnd , L_Rect'Access , Win32.FALSE );

         WHEN Win32.Winuser.WM_DESTROY =>
            Win32.Winuser.PostQuitMessage(0);

         WHEN OTHERS =>
            RETURN  Win32.Winuser.DefWIndowProc ( I_HWnd , I_Message , I_WParam , I_LParam );
      END CASE;

      ----- Default result : Msg processed!!!
      RETURN  0 ;
   END MainWindow_Proc;
END CharTb31_Pkg;
