Metropoli BBS
VIEWER: print.pas MODE: TEXT (CP437)
{█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█}
{█                                                       █}
{█      Virtual Pascal Examples. Version 1.10            █}
{█        PM Print Example                               █}
{█        The Art Of OS/2, Chapter 28, p542-556          █}
{█      ─────────────────────────────────────────────────█}
{█      Copyright (c) 1992-1996 by Larry Salomon         █}
{█      VP/2 Version Copyright (C) 1996 fPrint UK Ltd    █}
{█                                                       █}
{▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀}

Program Print;

{$PMTYPE PM}
{$R *.RES}
{$D Printing example - Copyright (c) 1992 by Larry Salomon}

Uses
  Use32, Dos, VPUtils, Os2Def, Os2Base, Os2PmApi, Strings;

{$IFDEF VPDEMO}
  {&Dynamic VP11Demo.Lib}
{$ENDIF}

Const
  RES_CLIENT      = 256;
  WND_LISTBOX     = 257;
  M_SAMPLE        = 256;
  MI_PRINT        = 257;
  MI_SETUP        = 258;
  MI_REFRESH      = 259;
  M_EXIT          = 260;
  MI_EXIT         = 261;
  MI_RESUME       = 262;
  CLS_CLIENT      = 'SampleClass';
  CPL_ERROR       = 0;
  CPL_NOPRINTERS  = 1;
  CPL_SUCCESS     = 2;

Type
  ptPrnListInfo = ^tPrnListInfo;
  tPrnListInfo = Record
    DosPrinter    : DEVOPENSTRUC;
    achDevice     : Array[0..255] of Char;
  end;

  ptPrnThreadInfo = ^tPrnThreadInfo;
  tPrnThreadInfo = Record
    ulSizeStruct   : ULong;
    hwndOwner      : HWnd;
    dosPrinter     : DEVOPENSTRUC;
  end;

  ptClientInfo = ^tClientInfo;
  tClientInfo  = Record
    hwndListbox    : HWnd;
  end;

procedure extractPrnInfo( ppiQueue    : PPRQINFO3;
                          pDosPrinter : pDEVOPENSTRUC );
{---------------------------------------------------------------}
{ This function extracts the needed information from the        }
{ specified PRQINFO3 structure and places it into the specifies }
{ DEVOPENSTRUC structure.                                       }
{                                                               }
{ Input:  ppiQueue - points to the PRQINFO3 structure           }
{ Output:  pdosPrinter - points to the initialized DEVOPENSTRUC }
{                        structure                              }
{---------------------------------------------------------------}
Var
  pchPos : pChar;

begin
  pdosPrinter^.pszLogAddress := ppiQueue^.pszName;

  pdosPrinter^.pszDriverName := ppiQueue^.pszDriverName;
  pchPos := strPos( pdosPrinter^.pszDriverName, '.');
  if pchPos <> nil then
    pchPos^ := #0;

  {------------------------------------------------------------}
  { The following if statement helps fix a bug from the 1st    }
  { edition.  The sample originally copied the pointer into    }
  { the DEVOPENSTRUC structure, but the memory into which      }
  { the memory was pointing was freed by createPrnList().      }
  {                                                            }
  { The fix, obviously, is to allocate our own area of memory  }
  { and to copy the printer data to the new buffer.  Note that }
  { destroyPrnList() must free the memory.  destroyPrnList()   }
  { doesn't get called until the application exits.            }
  {------------------------------------------------------------}
  if ppiQueue^.pDriverData <> nil then
    begin
      GetMem( pdosPrinter^.pdriv, ppiQueue^.pDriverData^.cb );
      if pdosPrinter^.pdriv = nil then
        Exit;

      Move( ppiQueue^.pDriverData^,
            pdosPrinter^.pdriv^,
            ppiQueue^.pDriverData^.cb );
    end
  else
     pdosPrinter^.pdriv := nil;

  pdosPrinter^.pszDataType := 'PM_Q_STD';
  pdosPrinter^.pszComment := ppiQueue^.pszComment;

  if strlen(ppiQueue^.pszPrProc) > 0 then
    pdosPrinter^.pszQueueProcName := ppiQueue^.pszPrProc
  else
    pdosPrinter^.pszQueueProcName := nil;

  if strlen(ppiQueue^.pszParms) > 0 then
    pdosPrinter^.pszQueueProcParams := ppiQueue^.pszParms
  else
    pdosPrinter^.pszQueueProcParams := nil;

  pdosPrinter^.pszSpoolerParams := nil;
  pdosPrinter^.pszNetworkParams := nil;
end; { ExtractPrnInfo }

procedure destroyPrnList( hwndListbox: HWnd );
{---------------------------------------------------------------}
{ This function destroys the printer list and returns the memory}
{ to the system.                                                }
{                                                               }
{ Input:  hwndListbox - handle of the listbox containing the    }
{                       printer list                            }
{---------------------------------------------------------------}
Var
  usNumItems   : UShort;
  usIndex      : UShort;
  ppliInfo     : ptPrnListInfo;

begin
  usNumItems := WinQueryLboxCount(hwndListbox);

  for usIndex := 0 to usNumItems-1 do
    begin
      ppliInfo :=
        ptPrnListInfo(
          pVoidFromMR( WinSendMsg( hwndListbox,
                                   LM_QUERYITEMHANDLE,
                                   MPFROMSHORT(usIndex),
                                   0) ) );
     if ppliInfo <> nil then
       begin
         {------------------------------------------------------}
         { The following 3 lines help fix a bug from the 1st    }
         { edition                                              }
         {------------------------------------------------------}
         if ppliInfo^.dosPrinter.pdriv <> nil then
           FreeMem(ppliInfo^.dosPrinter.pdriv,ppliInfo^.dosPrinter.pdriv^.cb);
         Dispose(ppliInfo);
       end;
    end;

  WinSendMsg( hwndListbox,
              LM_DELETEALL,
              0,
              0 );
end; { DestroyPrnList }

Function createPrnList( hwndListbox : HWnd ) : UShort;
{---------------------------------------------------------------}
{ This function enumerates the printers available and inserts   }
{ them into the specified listbox.                              }
{                                                               }
{ Input:  hwndListbox - handle to the listbox to contain the    }
{                       list                                    }
{ Returns:  an CPL_* constant                                   }
{---------------------------------------------------------------}
Var
  seError        : SPLERR;
  ulSzBuf        : ULONG;
  ulNumQueues    : ULONG;
  ulNumReturned  : ULONG;
  ulSzNeeded     : ULONG;
  ulIndex        : ULONG;
  ppiQueue       : PPRQINFO3;
  pp             : pPrqInfo3;
  pchPos         : PCHAR;
  ppliInfo       : ptPrnListInfo;
  sInsert        : SmallInt;

begin
  {------------------------------------------------------------}
  { Get the size of the buffer needed                          }
  {------------------------------------------------------------}

  seError := SplEnumQueue( nil,
                           3,
                           nil,
                           0,
                           ulNumReturned,
                           ulNumQueues,
                           ulSzNeeded,
                           nil );
  if seError <> ERROR_MORE_DATA then
    begin
      createPrnList := CPL_ERROR;
      Exit;
    end
  else
    if ulNumQueues = 0 then
      begin
        createPrnList := CPL_NOPRINTERS;
        Exit;
      end;

  GetMem( ppiQueue, ulszNeeded );
  if ppiQueue = nil then
    begin
      createPrnList := CPL_ERROR;
      Exit;
    end;

  ulSzBuf := ulSzNeeded;
  {------------------------------------------------------------}
  { Get the information                                        }
  {------------------------------------------------------------}

  SplEnumQueue(nil,
               3,
               ppiQueue,
               ulSzBuf,
               ulNumReturned,
               ulNumQueues,
               ulSzNeeded,
               nil);
  {------------------------------------------------------------}
  { ulNumReturned has the count of the number of PRQINFO3      }
  { structures.                                                }
  {------------------------------------------------------------}

  pp := ppiQueue;
  for ulIndex := 0 to ulNumReturned-1 do
    begin
      {---------------------------------------------------------}
      { Since the 'comment' can have newlines in it, replace    }
      { them with spaces                                        }
      {---------------------------------------------------------}
      pchPos := strpos(pp^.pszComment,#10);
      while pchPos <> nil do
        begin
          pchPos^ := ' ';
          pchPos := strpos(pp^.pszComment,#10);
        end;

      New( ppliInfo );
      if ppliInfo = nil then
        continue;

      {---------------------------------------------------------}
      { Extract the device name before initializing the         }
      { DEVOPENSTRUC structure                                  }
      {---------------------------------------------------------}
      pchPos := strpos(pp^.pszDriverName, '.');
      if pchPos <> nil then
        begin
          pchPos^ := #0;
          strcopy(ppliInfo^.achDevice, pchPos+1);
        end;

      extractPrnInfo( pp, @ppliInfo^.dosPrinter);

      sInsert := WinInsertLboxItem( hwndListbox,
                                    0,
                                    pp^.pszComment);

      WinSendMsg( hwndListbox,
                  LM_SETITEMHANDLE,
                  MPFROMSHORT(sInsert),
                  MPFROMP(ppliInfo) );

      if pp^.fsType AND PRQ3_TYPE_APPDEFAULT <> 0 then
        WinSendMsg( hwndListbox,
                    LM_SELECTITEM,
                    MPFROMSHORT(sInsert),
                    ord(TRUE) );
      Inc( pp );
    end; { For }

  FreeMem( ppiQueue, ulSzNeeded );
  createPrnList := CPL_SUCCESS;
end;

Function drawPage( hpsDraw : Hps; usPage: UShort ) : Bool;
{---------------------------------------------------------------}
{ This function draws a box for page 1.  Any other page number  }
{ returns an error.                                             }
{                                                               }
{ Input:  usPage - specifies the page number to draw.           }
{ Returns:  TRUE if successful, FALSE otherwise                 }
{---------------------------------------------------------------}
Var
  ptlMove : PointL;
  s       : String;

begin
  DrawPage := True;
  Case usPage of
    1 :
      begin
        ptlMove.x := 10;
        ptlMove.y := 10;

        GpiMove( hpsDraw, ptlMove );

        ptlMove.x := 100;
        ptlMove.y := 100;

        { Additional drawings added in Virtual Pascal version }
        GpiBox( hpsDraw,
                DRO_OUTLINE,
                ptlMove,
                0,
                0 );

        GpiMove( hpsDraw, ptlMove );
        ptlMove.x := 300;
        ptlMove.y := 300;

        GpiBox( hpsDraw,
                DRO_FILL,
                ptlMove,
                0,
                0 );

        ptlMove.x := 10;
        GpiMove( hpsDraw, ptlMove );
        s := 'Presentation Manager Print Sample'#0;
        GpiCharString( hpsDraw, Length(s)-1, @s[1] );

        { End of block added in Virtual Pascal version }
      end;
    else
      DrawPage := False;
  end; { Case usPage }
end;

function printThread( pArg : Pointer ) : Longint;
{---------------------------------------------------------------}
{ This function is the secondary thread which prints the output.}
{                                                               }
{ Input:  pptiInfo - points to the ptRNTHREADINFO structure     }
{                    containing needed information              }
{---------------------------------------------------------------}
Var
  habAnchor   : Hab;
  hmqQueue    : HMq;
  hdcPrinter  : HDC;
  szlHps      : SizeL;
  hpsPrinter  : Hps;
  OutCount    : Long;
  pptiInfo    : ptPrnThreadInfo absolute pArg;

begin
  habAnchor := WinInitialize(0);
  hmqQueue := WinCreateMsgQueue(habAnchor,
                               0);
  WinCancelShutdown(hmqQueue,
                    TRUE);
  {------------------------------------------------------------}
  { Open a device context (HDC)                                }
  {------------------------------------------------------------}

  hdcPrinter := DevOpenDC( habAnchor,
                           OD_QUEUED,
                           '*',
                           9,
                           @pptiInfo^.dosPrinter,
                           NULLHANDLE);

  if hdcPrinter = NULLHANDLE then
    begin
      {---------------------------------------------------------}
      { An error occurred                                       }
      {---------------------------------------------------------}
      WinAlarm( HWND_DESKTOP,
                WA_ERROR);
      WinMessageBox( HWND_DESKTOP,
                     pptiInfo^.hwndOwner,
                     'Error creating the device context.',
                     'Error',
                     0,
                     MB_INFORMATION OR MB_OK );

      WinDestroyMsgQueue(hmqQueue);
      WinTerminate(habAnchor);
      Dispose(pptiInfo);
      Endthread(0);
  end;

  {------------------------------------------------------------}
  { Query the width and height of the printer page             }
  {------------------------------------------------------------}
  DevQueryCaps( hdcPrinter,
                CAPS_WIDTH,
                1,
                szlHps.cx );
  DevQueryCaps( hdcPrinter,
                CAPS_HEIGHT,
                1,
                szlHps.cy );
  {------------------------------------------------------------}
  { Create a presentation space (HPS) associated with the      }
  { printer HDC                                                }
  {------------------------------------------------------------}

  hpsPrinter := GpiCreatePS( habAnchor,
                             hdcPrinter,
                             szlHps,
                             PU_LOENGLISH OR GPIT_MICRO OR GPIA_ASSOC );
  if hpsPrinter = NULLHANDLE then
    begin
      {---------------------------------------------------------}
      { An error occurred                                       }
      {---------------------------------------------------------}
      DevCloseDC(hdcPrinter);

      WinAlarm( HWND_DESKTOP,
                WA_ERROR );
      WinMessageBox( HWND_DESKTOP,
                     pptiInfo^.hwndOwner,
                     'Error creating the presentation space.',
                     'Error',
                     0,
                     MB_INFORMATION OR MB_OK );

      WinDestroyMsgQueue(hmqQueue);
      WinTerminate(habAnchor);
      Dispose( pptiInfo );
      Endthread(0);
    end;

  {------------------------------------------------------------}
  { Tell the printer that we are starting a print job          }
  {------------------------------------------------------------}
  if (DevEscape(hdcPrinter,
                DEVESC_STARTDOC,
                strlen(pptiInfo^.dosPrinter.pszComment),
                pptiInfo^.dosPrinter.pszComment,
                OutCount,
                nil) <> DEV_OK) then
    begin
      {---------------------------------------------------------}
      { An error occurred                                       }
      {---------------------------------------------------------}
      GpiDestroyPS(hpsPrinter);
      DevCloseDC(hdcPrinter);

      WinAlarm( HWND_DESKTOP,
                WA_ERROR );
      WinMessageBox(HWND_DESKTOP,
                    pptiInfo^.hwndOwner,
                    'Error starting the print job.',
                    'Error',
                    0,
                    MB_INFORMATION OR MB_OK);

      WinDestroyMsgQueue(hmqQueue);
      WinTerminate(habAnchor);
      Dispose( pptiInfo );
      endthread(0);
    end;

  {------------------------------------------------------------}
  { Draw sample output                                         }
  {------------------------------------------------------------}
  if not drawPage( hpsPrinter, 1) then
    begin
      {---------------------------------------------------------}
      { An error occurred so abort the print job                }
      {---------------------------------------------------------}
      DevEscape( hdcPrinter,
                 DEVESC_ABORTDOC,
                 0,
                 nil,
                 OutCount,
                 nil);
      GpiDestroyPS(hpsPrinter);
      DevCloseDC(hdcPrinter);

      WinAlarm( HWND_DESKTOP,
                WA_ERROR );
      WinMessageBox(HWND_DESKTOP,
                    pptiInfo^.hwndOwner,
                    'Error drawing the printer page.',
                    'Error',
                    0,
                    MB_INFORMATION OR MB_OK);

      WinDestroyMsgQueue(hmqQueue);
      WinTerminate(habAnchor);
      Dispose( pptiInfo );
      EndThread(0);
    end;

  {------------------------------------------------------------}
  { Tell the printer that we are finished with the print job   }
  {------------------------------------------------------------}
  if (DevEscape( hdcPrinter,
                 DEVESC_ENDDOC,
                 0,
                 nil,
                 OutCount,
                 nil) <> DEV_OK) then
    begin
      {---------------------------------------------------------}
      { An error occurred so abort the print job                }
      {---------------------------------------------------------}
      DevEscape( hdcPrinter,
                 DEVESC_ABORTDOC,
                 0,
                 nil,
                 OutCount,
                 nil );
      GpiDestroyPS(hpsPrinter);
      DevCloseDC(hdcPrinter);

      WinAlarm( HWND_DESKTOP,
                WA_ERROR);
      WinMessageBox(HWND_DESKTOP,
                    pptiInfo^.hwndOwner,
                    'Error ending the print job.',
                    'Error',
                    0,
                    MB_INFORMATION OR MB_OK);

      WinDestroyMsgQueue(hmqQueue);
      WinTerminate(habAnchor);
      Dispose(pptiInfo);
      EndThread(0);
    end;

  {------------------------------------------------------------}
  { Destroy the HPS and close the printer HDC                  }
  {------------------------------------------------------------}
  GpiDestroyPS(hpsPrinter);
  DevCloseDC(hdcPrinter);
  WinAlarm(HWND_DESKTOP,
           WA_NOTE);
  WinDestroyMsgQueue(hmqQueue);
  WinTerminate(habAnchor);
  Dispose( pptiInfo );
  EndThread(0);
end; { PrintThread }

Function ClientWndProc ( hwndClient : HWND ;
                         ulMsg      : ULONG;
                         mpParm1    : MPARAM;
                         mpParm2    : MPARAM ) : mResult; cdecl;

Var
  pciInfo  : ptClientInfo;
  sSelect  : Integer;
  ppliInfo : ptPrnListInfo;
  sIndex   : Integer;
  pptiInfo : ptPrnThreadInfo;
  usSelect : Integer;
  usResult : SmallInt;
  hpsPaint : Hps;
  rclPaint : RectL;

begin
  pciInfo := WinQueryWindowPtr( hwndClient, 0 );
  ClientWndProc := ord( False );

  Case ulMsg of
    WM_CREATE :
      begin
        {------------------------------------------------------}
        { Allocate and initialize the CLIENTINFO structure     }
        {------------------------------------------------------}

        New( pciInfo );
        if pciInfo = nil then
          begin
            WinMessageBox(HWND_DESKTOP,
                          HWND_DESKTOP,
                          'An error occurred in initialization.',
                          'Error',
                          0,
                          MB_OK OR MB_INFORMATION);
            ClientWndProc := ord( True );
          end;

        WinSetWindowPtr( hwndClient,
                         0,
                         pciInfo );

        pciInfo^.hwndListbox := WinCreateWindow(hwndClient,
                                               WC_LISTBOX,
                                               '',
                                               LS_HORZSCROLL OR
                                                LS_NOADJUSTPOS,
                                               0,
                                               0,
                                               0,
                                               0,
                                               hwndClient,
                                               HWND_TOP,
                                               WND_LISTBOX,
                                               nil,
                                               nil);
        if pciInfo^.hwndListbox = NULLHANDLE then
          begin
            WinMessageBox(HWND_DESKTOP,
                          HWND_DESKTOP,
                          'An error occurred in initialization.',
                          'Error',
                          0,
                          MB_OK OR MB_INFORMATION);
            Dispose( pciInfo );
            ClientWndProc := ord( True );
          end;

        WinSendMsg( hwndClient,
                    WM_COMMAND,
                    MPFROMSHORT(MI_REFRESH),
                    0 );
      end; { WM_CREATE }

    WM_DESTROY :
      begin
        {---------------------------------------------------------}
        { Return the resources to the system                      }
        {---------------------------------------------------------}
        destroyPrnList(pciInfo^.hwndListbox);
        WinDestroyWindow(pciInfo^.hwndListbox);
      end; { WM_DESTROY }

    WM_SIZE :
      WinSetWindowPos( pciInfo^.hwndListbox,
                       NULLHANDLE,
                       0,
                       0,
                       SHORT1FROMMP(mpParm2),
                       SHORT2FROMMP(mpParm2),
                       SWP_MOVE OR SWP_SIZE OR SWP_SHOW );

    WM_INITMENU :
      Case Short1FromMP(mpParm1) of
        M_SAMPLE :
          begin
            sSelect := WinQueryLboxSelectedItem(pciInfo^.hwndListbox);

            ppliInfo :=
              ptPrnListInfo(
                pVoidFromMR(WinSendMsg(pciInfo^.hwndListbox,
                                       LM_QUERYITEMHANDLE,
                                       MPFROMSHORT(sSelect),
                                       0)) );

            {---------------------------------------------------}
            { If no printer is selected, disable the print      }
            { menuitem                                          }
            {---------------------------------------------------}

            if sSelect <> LIT_NONE then
              WinEnableMenuItem( HWNDFROMMP(mpParm2),
                                 MI_PRINT,
                                 TRUE )
            else
              WinEnableMenuItem( HWNDFROMMP(mpParm2),
                                 MI_PRINT,
                                 FALSE );

            {---------------------------------------------------}
            { If no printer is selected or there is no driver   }
            { data, disable the setup menuitem                  }
            {---------------------------------------------------}
            if ((sSelect <> LIT_NONE) AND (ppliInfo <> nil) AND
               (ppliInfo^.dosPrinter.pdriv <> nil)) then
              WinEnableMenuItem( HWNDFROMMP(mpParm2),
                                 MI_SETUP,
                                 TRUE)
            else
              WinEnableMenuItem( HWNDFROMMP(mpParm2),
                                 MI_SETUP,
                                 FALSE );
          end; { M_SAMPLE }
        else
          ClientWndProc := WinDefWindowProc( hwndClient,
                                             ulMsg,
                                             mpParm1,
                                             mpParm2);
      end; { WM_INITMENU }

    WM_COMMAND :
      Case Short1FromMP(mpParm1) of
        MI_PRINT :
          begin
            {---------------------------------------------------}
            { Query the selected printer                        }
            {---------------------------------------------------}

            sIndex := WinQueryLboxSelectedItem(pciInfo^.hwndListbox);

            ppliInfo :=
              ptPrnListInfo(
                pVoidFromMR(WinSendMsg(pciInfo^.hwndListbox,
                                       LM_QUERYITEMHANDLE,
                                       MPFROMSHORT(sIndex),
                                       0)) );

            {---------------------------------------------------}
            { Allocate and initialize the PRNTHREADINFO         }
            { structure to pass to the thread                   }
            {---------------------------------------------------}

            New( pptiInfo );
            if pptiInfo = nil then
              begin
                WinMessageBox( HWND_DESKTOP,
                               HWND_DESKTOP,
                               'An error occurred while trying to print',
                               'Error',
                               0,
                               MB_OK OR MB_INFORMATION );
                ClientWndProc := ord( True );
                Exit;
              end;

            pptiInfo^.ulSizeStruct := sizeof(tPrnThreadInfo);
            pptiInfo^.hwndOwner := hwndClient;
            pptiInfo^.dosPrinter := ppliInfo^.dosPrinter;
            {---------------------------------------------------}
            { Create the thread to do the printing              }
            {---------------------------------------------------}

            if VPBeginThread( PrintThread,
                              $8000,
                              pptiInfo) = -1 then
              WinMessageBox( HWND_DESKTOP,
                             HWND_DESKTOP,
                             'An error occurred while trying to print',
                             'Error',
                             0,
                             MB_OK OR MB_INFORMATION );
          end; { MI_PRINT }

        MI_SETUP :
          begin
            {---------------------------------------------------}
            { Query the selected printer                        }
            {---------------------------------------------------}

            usSelect := WinQueryLboxSelectedItem(pciInfo^.hwndListbox);

            ppliInfo :=
              ptPrnListInfo(
                pVoidFromMR(WinSendMsg(pciInfo^.hwndListbox,
                                       LM_QUERYITEMHANDLE,
                                       MPFROMSHORT(usSelect),
                                       0)) );

            DevPostDeviceModes( WinQueryAnchorBlock(hwndClient),
                                ppliInfo^.dosPrinter.pdriv,
                                ppliInfo^.dosPrinter.pszDriverName,
                                ppliInfo^.achDevice,
                                nil,
                                DPDM_POSTJOBPROP );
          end; { MI_SETUP }

        MI_REFRESH :
          begin
            destroyPrnList(pciInfo^.hwndListbox);

            usResult := createPrnList(pciInfo^.hwndListbox);

            case usResult of
              CPL_ERROR :
                WinMessageBox( HWND_DESKTOP,
                               HWND_DESKTOP,
                               'An error occurred while refreshing the list',
                               'Error',
                               0,
                               MB_OK OR MB_INFORMATION);

              CPL_NOPRINTERS :
                WinMessageBox( HWND_DESKTOP,
                               HWND_DESKTOP,
                               'There are no printers defined.',
                               'Warning',
                               0,
                               MB_OK OR MB_INFORMATION);
              else
                WinSendMsg( WinWindowFromID(hwndClient,WND_LISTBOX),
                            LM_SELECTITEM,
                            MPFROMSHORT(0),
                            ord(TRUE));

            end; { Case usResult }
          end; { MI_REFRESH }

        MI_EXIT :
          WinPostMsg( hwndClient,
                      WM_CLOSE,
                      0,
                      0 );
        else
          ClientWndProc := WinDefWindowProc( hwndClient,
                                             ulMsg,
                                             mpParm1,
                                             mpParm2);
      end; { WM_COMMAND }

    WM_PAINT :
      begin
        hpsPaint := WinBeginPaint( hwndClient,
                                   NULLHANDLE,
                                   @rclPaint );
        WinFillRect( hpsPaint,
                     rclPaint,
                     SYSCLR_WINDOW );
        WinEndPaint(hpsPaint);
      end; { WM_PAINT }

    else
      ClientWndProc := WinDefWindowProc( hwndClient,
                                         ulMsg,
                                         mpParm1,
                                         mpParm2);
  end; { Case ulMsg }
end;

Var
  habAnchor   : HAB;
  hmqQueue    : HMQ;
  ulFlags     : ULONG;
  hwndFrame   : HWND;
  bLoop       : BOOL;
  qmMsg       : QMSG;

begin
   habAnchor := WinInitialize(0);
   hmqQueue := WinCreateMsgQueue(habAnchor,
                                0);

   WinRegisterClass( habAnchor,
                     CLS_CLIENT,
                     clientWndProc,
                     0,
                     sizeof(Pointer) );

   ulFlags := FCF_SIZEBORDER OR FCF_TITLEBAR OR FCF_TASKLIST OR
      FCF_SHELLPOSITION OR FCF_SYSMENU OR FCF_MENU OR FCF_ACCELTABLE;

   hwndFrame := WinCreateStdWindow(HWND_DESKTOP,
                                   WS_VISIBLE,
                                   ulFlags,
                                   CLS_CLIENT,
                                   'Printing Sample Application',
                                   0,
                                   NULLHANDLE,
                                   RES_CLIENT,
                                   nil);

   if hwndFrame <> NULLHANDLE then
    begin
      bLoop := WinGetMsg(habAnchor,
                         qmMsg,
                         NULLHANDLE,
                         0,
                         0);
      while bLoop do
        begin
          WinDispatchMsg( habAnchor,
                          qmMsg);
          bLoop := WinGetMsg( habAnchor,
                              qmMsg,
                              NULLHANDLE,
                              0,
                              0);
        end;
      WinDestroyWindow(hwndFrame);
    end;
   WinDestroyMsgQueue(hmqQueue);
   WinTerminate(habAnchor);
end.


[ RETURN TO DIRECTORY ]