Пример #1
0
MRESULT _System DrvMountDrivesDlg( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 
{
    if (msg == WM_TIMER && mp1 == (MP)CAM_LVMTMR) {
        HEV  hev = WinQueryWindowULong( hwnd, QWL_USER);

        if (!WinWaitEventSem( hev, 0))
            WinSendMsg( hwnd, WM_COMMAND, (MP)CAM_LVMTMR, 0);
        return (0);
    }

    if (msg == WM_COMMAND || msg == WM_SYSCOMMAND) {
        ULONG   ulChk;

        if (!WinStopTimer( 0, hwnd, CAM_LVMTMR))
            printf( "DrvMountDrivesDlg - WinStopTimer\n");

        ulChk = (ULONG)WinSendDlgItemMsg( hwnd, IDC_AUTOMOUNT,
                                          BM_QUERYCHECK, 0, 0);
        DrvSetUseLvm( WinQueryWindow( hwnd, QW_OWNER), ulChk);

        WindowClosed( WinQueryWindowUShort( hwnd, QWS_ID));
        WinDismissDlg( hwnd, (mp1 == (MP)CAM_LVMTMR));
        return (0);
    }

    if (msg == WM_INITDLG) {
        HEV  hev = (HEV)mp2;

        WinSetWindowULong( hwnd, QWL_USER, hev);
        LoadDlgStrings( hwnd, nlsMountDlg);
        WinSendDlgItemMsg( hwnd, IDC_AUTOMOUNT, BM_SETCHECK,
                           (MP)(CAMDRV_IS_NOLVM ? 0 : 1), 0);
        ShowDialog( hwnd, 0);

        if (!WinWaitEventSem( hev, 0)) {
            WindowClosed( WinQueryWindowUShort( hwnd, QWS_ID));
            WinDismissDlg( hwnd, TRUE);
        }
        else
            if (!WinStartTimer( 0, hwnd, CAM_LVMTMR, 250))
                printf( "DrvMountDrivesDlg - WinStartTimer\n");
        return (0);
    }

    if (msg == WM_FOCUSCHANGE) {
        if (SHORT1FROMMP(mp2) && !WinIsWindowEnabled( hwnd)) {
            WinPostMsg( WinQueryWindow( hwnd, QW_OWNER),
                        CAMMSG_FOCUSCHANGE, 0, 0);
            return (0);
        }
    }

    return (WinDefDlgProc( hwnd, msg, mp1, mp2));
}
Пример #2
0
MRESULT _System DrvEjectAllDlg( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 
{
    switch (msg) {

        case WM_INITDLG:
            DrvInitEjectAllDlg( hwnd, mp2);
            return (0);

        case WM_SAVEAPPLICATION:
            WinStoreWindowPos( CAMINI_APP, CAMINI_EJECTPOS, hwnd);
            return (0);

        case WM_SYSCOMMAND:
            if (SHORT1FROMMP( mp1) == SC_CLOSE)
                return (WinSendMsg( hwnd, WM_COMMAND, (MP)IDC_NO, 0));
            break;

        case WM_COMMAND:
            if (mp1 == (MP)IDC_YES) {
                WinEnableWindow( WinWindowFromID( hwnd, IDC_YES), FALSE);
                WinEnableWindow( WinWindowFromID( hwnd, IDC_NO), FALSE);
                LoadDlgItemString( hwnd, IDC_TEXT1, MSG_Ejecting);
                LoadDlgItemString( hwnd, IDC_TEXT4, MSG_ThisMayTake);
                DrvEjectAllDrives( hwnd);
            }
            WindowClosed( WinQueryWindowUShort( hwnd, QWS_ID));
            WinDestroyWindow( hwnd);
            return (0);

        case WM_FOCUSCHANGE:
            if (SHORT1FROMMP(mp2) && !WinIsWindowEnabled( hwnd)) {
                WinPostMsg( WinQueryWindow( hwnd, QW_OWNER),
                            CAMMSG_FOCUSCHANGE, 0, 0);
                return (0);
            }
            break;

        case WM_DESTROY:
            WinPostMsg( WinQueryWindow( hwnd, QW_OWNER), CAMMSG_EXIT,
                        (MP)TRUE, 0);
            break;

    }

    return (WinDefDlgProc( hwnd, msg, mp1, mp2));
}
// ScrollBar - окно полоски просмотра, ее состояние надо вернуть в SB_State.
// Эта структура должна располагаться в разделяемой памяти, иначе возникнет ошибка.
VOID Scroller_QueryScrollBarState( HWND ScrollBar, PSBCDATA SB_State )
{
 // Полоска просмотра может быть отключена.
 SB_State->sHilite = WinIsWindowEnabled( ScrollBar );

 // Узнаем число делений. Значения posLast >= posFirst >= 0.
 MRESULT Bounds = WinSendMsg( ScrollBar, SBM_QUERYRANGE, 0, 0 );
 SB_State->posFirst = SHORT1FROMMP( Bounds );
 SB_State->posLast  = SHORT2FROMMP( Bounds );

 // Узнаем положение движка в полоске.
 MRESULT Slider = WinSendMsg( ScrollBar, SBM_QUERYPOS, 0, 0 );
 SB_State->posThumb = SHORT1FROMMP( Slider );

 // Возврат.
 return;
}
/*************************************************************************
 *
 * Name       : WinProc(hwnd, msg, mp1, mp2)
 *
 * Description: Processes the messages sent to the main client
 *              window.  This routine processes the basic
 *              messages all client windows should process.
 *
 * Concepts   : This procedure provides service routines for the general
 *              PM events (messages) that PM sends to the window, as well
 *              as the user initiated events (messages) that are generated
 *              when the user selects the action bar and pulldown menu
 *              controls or the corresponding keyboard accelerators.
 *
 *              The switch statement shown below distributes the window
 *              messages to the respective message service routines, which
 *              are set apart by the case statements.  The window
 *              procedures must provide an appropriate service routine for
 *              its end user initiated messages, as well as the general PM
 *              messages (like the WM_CLOSE message). If a message is sent
 *              to this procedure for which there is no programmed case
 *              clause (i.e., no service routine), the message is defaulted
 *              function WinDefWindowProc, where it is disposed of by PM.
 *
 *              Time-consuming tasks are posted to the object window where
 *              they can be performed without the 1/10 second turnaround
 *              time imposed on the client window. When the object window
 *              is busy, the client window is usually disabled. The object
 *              window then posts an acknowledgement
 *              back to the client when the lengthy task is completed.
 *
 *              Cases under the big switch appear in alphabetical order.
 *
 *  API's     :   WinLoadString
 *                WinMessageBox
 *                WinQueryWindowULong
 *                WinSendMsg
 *                WinPostMsg
 *                WinIsWindowEnabled
 *                WinSetPointer
 *                WinQuerySysPointer
 *                WinBeginPaint
 *                WinQueryWindowRect
 *                WinFillRect
 *                WinEndPaint
 *                WinInvalidateRect
 *                WinSetWindowText
 *                GpiDrawChain
 *                GpiConvert
 *                GpiSetDefaultViewMatrix
 *                GpiAssociate
 *                GpiDestroyPS
 *                GpiDeleteBitmap
 *                GpiDeleteMetafile
 *
 * Parameters : HWND         window handle
 *              ULONG        message
 *              MPARAM       message parameter 1
 *              MPARAM       message parameter 2
 *
 * Result     : MRESULT      message result
 *
 *************************************************************************/
MRESULT EXPENTRY WinProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
   BOOL                bOK;
   PMAIN_PARM       pmp;
   HPS                 hps;
   RECTL              rectl;
   PSZ                 psz;
   CHAR               szWork[ LEN_WORKSTRING ];
   SHORT              sStep;
   ULONG              ulWork;
   SHORT              sNewPos;
   ULONG              rc;

   switch(msg)
   {
   case WM_CLOSE:
      /* obtain the main parameter pointer from window words */
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );
#ifdef OSA_AWARE
      /* Do OSA termination */
      TerminateOSA(hwnd);
#endif
      if( pmp->fBusy )
      {
         /* OK to close when object window is busy?  */
         WinLoadString( pmp->hab, (HMODULE)NULLHANDLE,
                   ERRMSG_CLOSE_QUESTION, LEN_WORKSTRING, szWork );
         ulWork = WinMessageBox( HWND_DESKTOP,
                                 pmp->hwndFrame,
                                 szWork,
                                 pmp->pszTitle,
                                 (USHORT)0,
                                 MB_YESNOCANCEL | MB_MOVEABLE |
                                 MB_CUANOTIFICATION | MB_APPLMODAL);

         if( ulWork == MBID_YES )
         {
            /* close down the application in spite of being busy */
            pmp->fCancel = TRUE;
            /* disable client during exit */
            WinSendMsg( hwnd, WM_USER_DISABLE_CLIENT, (MPARAM)0 , (MPARAM)0  );
            /* start a watchdog timer to ensure a timely death */
            WinStartTimer( pmp->hab, hwnd, ID_DEATH_TIMER, LEN_DEATH_TIMER );
            /* Tell object window to close, quit, and post me a WM_QUIT */
            WinPostMsg( pmp->hwndObject, WM_USER_CLOSE, (MPARAM)hwnd, (MPARAM)0 );
         }
      }
      else
      {
         /* not busy, so initiate closure by telling object window to close */
         WinPostMsg( pmp->hwndObject, WM_USER_CLOSE, (MPARAM)hwnd, (MPARAM)0 );
      }
      return (MRESULT)NULL;


   case WM_COMMAND:
      /* do menu activities; see menu.c */
      return Menu( hwnd, msg, mp1, mp2 );


   case WM_CREATE:

      /*
       * Do one-time, startup processing in PRTCREAT.C.
       * This function allocates the pmp, a pointer to the program's
       * main parameters. See the declaration of this block of
       * parameters in PRTSAMP.H, the MAIN_PARM structure.
       *
       * The Create() function allocates this structure and
       * begins to initialize it. Throughout all the code, the pmp->
       * pointer is usually obtainable with a call to WinQueryWindowULong.
       * Window word space for this pointer was reserved on the call
       * to WinRegisterClass.
       *
       * Create() allocates, initializes, and stores the pmp pointer
       * in the client window words. It then starts thread 2 of the
       * application on which the object window operates. The pmp
       * pointer is passed to thread 2 with _beginthread in PRTCREAT.C.
       * The pmp is passed to the object window on the call to
       * WinCreateWindow in PRTOBJ.C. Finally, the object window stores
       * the pmp in its window words under the WM_CREATE case of the
       * ObjectWinProc in PRTOBJ.C.
       *
       */

      Create( hwnd );
#ifdef OSA_AWARE
      /* Do OSA Initialization */
      InitOSA(hwnd);
#endif

#ifdef OSA_AWARE
        /* Generate a Apple Event - Open Application to myself  (Workaround) */
        rc =  GenerateOSAEvent(hwnd, msg, MPFROMSHORT(IDM_AEOPENAPP), mp2);
#endif
      return (MRESULT)NULL;


   case WM_HSCROLL:
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );

      /* Compute some fraction of scroll bar range for a unit of scrolling. */
      sStep  = pmp->sHScrollRange / 50;

      switch( SHORT2FROMMP( mp2 ))
      {
      case SB_LINELEFT:
         pmp->sHScrollPos -= sStep;
         break;
      case SB_PAGELEFT:
         pmp->sHScrollPos -= pmp->sizelClient.cx;
         break;
      case SB_LINERIGHT:
         pmp->sHScrollPos += sStep;
         break;
      case SB_PAGERIGHT:
         pmp->sHScrollPos += pmp->sizelClient.cx;
         break;
      case SB_SLIDERPOSITION:
      case SB_SLIDERTRACK:
         pmp->sHScrollPos = SHORT1FROMMP( mp2 );
         break;
      }

      /* Don't allow step assignments to exceed limits of zero to range. */
      pmp->sHScrollPos = max( (SHORT)0,
                              min( pmp->sHScrollPos, pmp->sHScrollRange ));

      if( pmp->sHScrollPos != SHORT1FROMMR(WinSendMsg( pmp->hwndHScroll,
          SBM_QUERYPOS, (MPARAM)0, (MPARAM)0 )))
      {
         /*
          * New scroll bar thumbbutton position is different than current.
          * Set a new X translation value to effect the scroll.
          * Current scale setting affects the X element of the matrix.
          */
         pmp->matlfDefView.lM31 = OFFSET_XY_TWIPS - (LONG)(pmp->floatScale *
                                                 (float)( pmp->sHScrollPos));
         bOK = GpiSetDefaultViewMatrix( pmp->hpsClient,
                                        9,
                                        &pmp->matlfDefView,
                                        TRANSFORM_REPLACE );
         pmassert( pmp->hab, bOK );
         CalibrateHorizontalScrollBar( pmp );
         WinInvalidateRect( hwnd, NULL, FALSE );
      }
      return (MRESULT) 0;


   case WM_MOUSEMOVE:
      /* display which pointer? -- could query pmp->fBusy or... */
      if( WinIsWindowEnabled( hwnd ))
      {
         /* not disabled; display regular pointer */
         WinSetPointer( HWND_DESKTOP,
                        WinQuerySysPointer( HWND_DESKTOP, SPTR_ARROW, FALSE ));
      }
      else
      {
         /* disabled; display hourglass because I'm busy */
         WinSetPointer( HWND_DESKTOP,
                        WinQuerySysPointer( HWND_DESKTOP, SPTR_WAIT, FALSE ));
      }
     return (MRESULT) 1;



   case WM_NACK_BITMAP_NOT_SUPPORTED:
      /*
       * Object window does not support this format of bitmap -
       * show a message box.
       */
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );
      WinSendMsg( hwnd, WM_USER_ENABLE_CLIENT, (MPARAM)0, (MPARAM)0 );
      bOK = WinLoadString( pmp->hab, (HMODULE)0,
                   ERRMSG_BITMAP_NOT_SUPPORTED, LEN_WORKSTRING, szWork );
      pmassert( pmp->hab, bOK );
      WinMessageBox( HWND_DESKTOP,
                     pmp->hwndFrame,
                     szWork,
                     pmp->pszTitle,
                     (USHORT)0,
                     MB_OK | MB_MOVEABLE | MB_CUACRITICAL | MB_APPLMODAL);

      pmp->ulNextMode        = MODE_UNKNOWN;
      pmp->szNextFilename[0] = 0;
      WinPostMsg( hwnd, WM_USER_NEW_MODE, (MPARAM)0, (MPARAM)0 );
      return (MRESULT) 0;


   case WM_NACK_BITMAP_ERROR:
      /*
       * Object window had error loading the bitmap file -
       * show a message box
       */
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );
      WinSendMsg( hwnd, WM_USER_ENABLE_CLIENT, (MPARAM)0, (MPARAM)0 );
      bOK = WinLoadString( pmp->hab,
                           (HMODULE)NULLHANDLE,
                           ERRMSG_BAD_BITMAP,
                           LEN_WORKSTRING,
                           szWork );
      pmassert( pmp->hab, bOK );
      WinMessageBox( HWND_DESKTOP,
                     pmp->hwndFrame,
                     szWork,
                     pmp->pszTitle,
                     (USHORT)0,
                     MB_OK | MB_MOVEABLE | MB_CUAWARNING | MB_APPLMODAL);

      pmp->ulNextMode        = MODE_UNKNOWN;
      pmp->szNextFilename[0] = 0;
      WinPostMsg( hwnd, WM_USER_NEW_MODE, (MPARAM)0, (MPARAM)0 );
      return (MRESULT) 0;


   case WM_NACK_FILE_READING_ERROR:
      /*
       * Object window had a problem with reading the disk -
       * show a message box.
       */
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );
      WinSendMsg( hwnd, WM_USER_ENABLE_CLIENT, (MPARAM)0, (MPARAM)0 );
      bOK = WinLoadString( pmp->hab, (HMODULE)NULLHANDLE,
                           ERRMSG_READ_ERROR, LEN_WORKSTRING, szWork );
      pmassert( pmp->hab, bOK );
      WinMessageBox( HWND_DESKTOP,
                     pmp->hwndFrame,
                     szWork,
                     pmp->pszTitle,
                     (USHORT)0,
                     MB_OK | MB_MOVEABLE | MB_CUACRITICAL | MB_APPLMODAL);
      pmp->ulNextMode        = MODE_UNKNOWN;
      pmp->szNextFilename[0] = 0;
      WinPostMsg( hwnd, WM_USER_NEW_MODE, (MPARAM)0, (MPARAM)0 );
      return (MRESULT) 0;


   case WM_PAINT:
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );

      /* do not rely on client window rectangle being correct */
      WinQueryUpdateRect( hwnd, &rectl );
      WinQueryWindowRect( hwnd, &rectl );

      /* current mode of the program affects window painting */
      switch( pmp->ulMode )
      {
      case MODE_UNKNOWN:
         WinSendMsg( hwnd, WM_USER_DISABLE_CLIENT, (MPARAM)0, (MPARAM)0 );
         WinPostMsg( pmp->hwndObject, WM_USER_PAINT_DEFAULT_SCREEN,
                        (MPARAM)hwnd, (MPARAM)0 );
         /* must call default window proc for window validation */
         break;

      case MODE_TEXT:
         if( pmp->fBusy )
         {
            /*
             * Object window is busy with the client PS drawing into
             * retained segments. Use a cached micro PS to merely
             * fill the client window with a background wash.
             *
             * Proper painting of the text will occur in due time
             * because the WM_USER_ACK case below will
             * invalidate the client window and force a paint.
             * The object window won't be busy then.
             */
            hps = WinBeginPaint( hwnd, (HPS) 0, &rectl );
            pmassert( pmp->hab, hps );
            bOK = WinFillRect( hps, &rectl, SYSCLR_WINDOW );
            pmassert( pmp->hab, bOK );
            WinEndPaint( hps );
         }
         else
         {
            /* PS not busy. Use GpiDrawChain to repaint the text */
            hps = WinBeginPaint( hwnd, (HPS)pmp->hpsClient, &rectl );
            pmassert( pmp->hab, hps );
            bOK = WinFillRect( pmp->hpsClient, &rectl, SYSCLR_WINDOW );
            pmassert( pmp->hab, bOK );
            /*
             * GpiDrawChain re-plays the GpiCharString orders that were
             * retain in the WM_USER_PAGINATE case in prtobj.c
             */
            bOK = GpiDrawChain( pmp->hpsClient );
            pmassert( pmp->hab, bOK );
            bOK = WinEndPaint( pmp->hpsClient );
            pmassert( pmp->hab, bOK );
         }
         return (MRESULT) 0;

      case MODE_BITMAP:
         if( pmp->hbm )
         {
            WinSendMsg( hwnd, WM_USER_DISABLE_CLIENT, (MPARAM)0, (MPARAM)0 );
            WinPostMsg( pmp->hwndObject, WM_USER_PAINT_BITMAP,
                        (MPARAM)hwnd, (MPARAM)0 );
         }
         /* must call default window proc for window validation */
         break;

      case MODE_METAFILE:
         hps = WinBeginPaint( hwnd, (HPS) 0, &rectl );
         pmassert( pmp->hab, hps );
         WinFillRect( hps, &rectl, SYSCLR_WINDOW );
         if( pmp->hmf )
         {
            WinSendMsg( hwnd, WM_USER_DISABLE_CLIENT, (MPARAM)0, (MPARAM)0 );
            WinPostMsg( pmp->hwndObject, WM_USER_PAINT_METAFILE,
                        (MPARAM)hwnd, (MPARAM)0 );
         }
         WinEndPaint( hps );
         return (MRESULT) 0;

      default:
         pmassert( pmp->hab, NULL == "bad case in WM_PAINT" );
      }
      break;


#ifdef OSA_AWARE
   case WM_SEMANTICEVENT:
      /* Handle Apple Event Manager Semantic Event */
      WinMessageBox( HWND_DESKTOP,
                     HWND_DESKTOP,
                     "WM_SEMANTIC_EVENT was received",
                     "WinProc",
                     (USHORT)0,
                     MB_OK | MB_NOICON);
      /* Call ProcessSemanticEvent to process the Apple Event */
      ProcessSemanticEvent( hwnd, msg, mp1, mp2 );
      return (MRESULT) 0;
#endif


   case WM_SIZE:
      /* Do size process if frame is not minimized  */
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );

      /*
       * If the object window is busy drawing, the GPI calls here can fail
       * because the PS is busy. Check for this situation and delay
       * the sizing operation by a few milliseconds.
       */
      if( pmp->fBusy )
      {
          WinStartTimer( pmp->hab, hwnd, ID_SIZE_TIMER, LEN_SIZE_TIMER );
          return (MRESULT) 0;
      }

      ulWork = WinQueryWindowULong( pmp->hwndFrame, QWL_STYLE );

      if( !( ulWork & WS_MINIMIZED ))
      {
         /* Frame is not minimized. Get window size in pels. */
         WinQueryWindowRect( hwnd, &rectl );

         /* how many twips will fit into the client window now? */
         bOK = GpiConvert( pmp->hpsClient, CVTC_DEVICE,
                           CVTC_WORLD, 2L, (PPOINTL)&rectl );
         pmassert( pmp->hab, bOK );

         /* compute client size in twips, store in pmp */
         pmp->sizelClient.cx = rectl.xRight - rectl.xLeft;
         pmp->sizelClient.cy = rectl.yTop   - rectl.yBottom;

         /* Try to keep the current position still in view by calculating */
         /* the difference between size required and client window. */
         /* The scroll position is then either 0 or the minimum of the */
         /* difference and the old scroll position */
         sNewPos = (LONG)FixedInchesToTwips(pmp->form.fxxWidth) +
                    (((float)(2 * OFFSET_XY_TWIPS)) / pmp->floatScale) -
                   pmp->sizelClient.cx;
         pmp->sHScrollPos = min( max( 0, sNewPos), pmp->sHScrollPos);
         sNewPos = (LONG)FixedInchesToTwips(pmp->form.fxyHeight) +
                    (((float)(2 * OFFSET_XY_TWIPS)) / pmp->floatScale) -
                   pmp->sizelClient.cy;
         pmp->sVScrollPos = min( max( 0, sNewPos), pmp->sVScrollPos);

         /* recalibrate the scroll bars */
         CalibrateHorizontalScrollBar( pmp );
         CalibrateVerticalScrollBar( pmp );

         /*
          * Modify def-view matrix translation to home the displayed page.
          * This depends on the current scaling value.
          */
         pmp->matlfDefView.lM31 = OFFSET_XY_TWIPS - (LONG)(pmp->floatScale *
                                                 (float)( pmp->sHScrollPos));
         pmp->matlfDefView.lM32 = OFFSET_XY_TWIPS + (LONG)(pmp->floatScale *
                          (float)( pmp->sVScrollPos - pmp->sVScrollRange ));
         bOK = GpiSetDefaultViewMatrix( pmp->hpsClient, 9,
                          &pmp->matlfDefView, TRANSFORM_REPLACE );
         pmassert( pmp->hab, bOK );

         /* force a paint */
         WinInvalidateRect( hwnd, NULL, FALSE );
      }
      return (MRESULT) 0;




   case WM_TIMER:
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );
      switch( (ULONG) mp1 )
      {
      case ID_DEATH_TIMER:
         /* object window never posted a quit in allotted time.
         WinPostMsg( hwnd, WM_QUIT, 0, 0 );
         break;
      case ID_SIZE_TIMER:
         /* object window was busy with the PS before; try sizing now */
         bOK = WinStopTimer( pmp->hab, hwnd, ID_SIZE_TIMER );
         pmassert( pmp->hab, bOK );
         WinSendMsg( hwnd, WM_SIZE, 0, 0 );
         break;
      }
      return (MRESULT) 0;





   case WM_USER_ACK:
      /*
       * Object window is done processing lengthy task.
       * mp1 contains the WM_USER msg originally posted to the object window
       * mp2 may contain a result code, depending on mp1
       */
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );

      /* reenable the client window */
      WinSendMsg( hwnd, WM_USER_ENABLE_CLIENT, (MPARAM)0, (MPARAM)0 );

      switch( (ULONG)mp1 )
      {
      case WM_USER_LOAD_BITMAP:
      case WM_USER_LOAD_METAFILE:
      case WM_USER_LOAD_TEXT:
         /*
          * Do size processing so that document will
          * "home" in the client window.
          */
         WinSendMsg( hwnd, WM_SIZE, (MPARAM)0, (MPARAM)0 );
         break;
      case WM_USER_PAGINATE:
         switch( (ULONG)mp2  )
         {
         case PAGINATE_EOF:
         case PAGINATE_EOF_PART_PAGE:
            /* seek top of file */
            fseek( pmp->f, 0, SEEK_SET );
         }
         WinInvalidateRect( hwnd, NULL, FALSE );
         break;
      }

      return (MRESULT) 0;


   case WM_USER_DISABLE_CLIENT:
      /*
       * usually disable before posting a task to the object window
       * this message may be sent; disable menu action bar as well
       */
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );
      pmp->fBusy = TRUE;
      WinEnableWindow( pmp->hwndClient,  FALSE );
      WinEnableWindow( pmp->hwndMenubar, FALSE );
      WinEnableControl( pmp->hwndFrame, FID_HORZSCROLL,  FALSE );
      WinEnableControl( pmp->hwndFrame, FID_VERTSCROLL,  FALSE );
      WinEnableMenuItem( pmp->hwndMenubar, IDM_PAGEDOWN, FALSE );
      WinEnableMenuItem( pmp->hwndMenubar, IDM_VIEWFULL, FALSE );
      WinEnableMenuItem( pmp->hwndMenubar, IDM_VIEWHALF, FALSE );
      return (MRESULT)0;


   case WM_USER_ENABLE_CLIENT:
      /*
       * usually enable upon receipt of object window ack/nack
       * this message may be sent; enable menu actions if text mode
       */
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );
      pmp->fBusy = FALSE;
      WinEnableWindow( pmp->hwndClient,  TRUE );
      WinEnableWindow( pmp->hwndMenubar, TRUE );
      WinEnableControl( pmp->hwndFrame, FID_HORZSCROLL,  TRUE );
      WinEnableControl( pmp->hwndFrame, FID_VERTSCROLL,  TRUE );
      WinEnableMenuItem( pmp->hwndMenubar, IDM_VIEWFULL, TRUE );
      WinEnableMenuItem( pmp->hwndMenubar, IDM_VIEWHALF, TRUE );
      if( pmp->ulMode == MODE_TEXT )
      {
         WinEnableMenuItem( pmp->hwndMenubar, IDM_PAGEDOWN, TRUE );
      }
      return (MRESULT) 0;



   case WM_USER_NEW_MODE:
      /*
       * The program now has a new file, file type, or printer, or
       * printer form, orientation, resolution, etc. The receipt
       * and processing of this message works to reset the program:
       * Old file, bitmap, or metafile handles are closed, and
       * new ones get opened. The titlebar shows the new filename.
       * This case works very much like a program reset.
       */
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );

      /* close processing on current file */

      switch( pmp->ulMode )
      {
      case MODE_BITMAP:
        /* destroy previous memory dc, ps, and hbm */
        if( pmp->hpsMemory )
        {
          GpiAssociate( pmp->hpsMemory, (HDC)0 );
          GpiDestroyPS( pmp->hpsMemory );
          pmp->hpsMemory = (HPS) 0;
        }
        if( pmp->hdcMemory )
        {
          DevCloseDC( pmp->hdcMemory );
          pmp->hdcMemory = (HDC) 0;
        }
        if( pmp->hbm )
        {
          GpiDeleteBitmap( pmp->hbm );
          pmp->hbm = (HBITMAP) 0;
        }
        break;

      case MODE_METAFILE:
        /* destroy old metafile handle */
        if( pmp->hmf )
        {
          GpiDeleteMetaFile( pmp->hmf );
          pmp->hmf = (HMF) 0;
        }
        break;

      case MODE_TEXT:
        fclose( pmp->f );
        pmp->f = (FILE *) 0;
        /* turn off options for text mode */
        WinEnableMenuItem( pmp->hwndMenubar, IDM_PAGEDOWN, FALSE );
        WinEnableMenuItem( pmp->hwndMenubar, IDM_SETFONT,  FALSE );
        break;
      }

      /* turn off options for all modes */
      WinEnableMenuItem( pmp->hwndMenubar, IDM_VIEWHALF, FALSE );
      WinEnableMenuItem( pmp->hwndMenubar, IDM_VIEWFULL, FALSE );
      WinEnableControl( pmp->hwndFrame, FID_HORZSCROLL,  FALSE );
      WinEnableControl( pmp->hwndFrame, FID_VERTSCROLL,  FALSE );

      /* copy over current values with the next values */
      pmp->ulMode = pmp->ulNextMode;
      strcpy( pmp->szFilename, pmp->szNextFilename );

      /* enable the print menu option if mode is known and there
         is a printer set up. */
      WinEnableMenuItem( pmp->hwndMenubar, IDM_PRINT,
       (pmp->ulMode != MODE_UNKNOWN && pmp->hpsPrinterInfo ) );


      /* update title bar text and show filename in use */
      if( *pmp->szFilename )
      {
         /* parse full-qualified filename to just get filename and extension */
         psz = strrchr( pmp->szFilename, '\\' );
         if (psz && *psz)
         {
             ++psz;
         }
         else
         {
             psz = pmp->szFilename;
         }
         sprintf( szWork, "%s - %s", pmp->pszTitle, psz );
      }
      else
      {
         strcpy( szWork, pmp->pszTitle );
      }
      WinSetWindowText( pmp->hwndTitlebar, szWork );

      /* enable options for all modes */
      WinEnableMenuItem( pmp->hwndMenubar, IDM_VIEWHALF, TRUE  );
      WinEnableMenuItem( pmp->hwndMenubar, IDM_VIEWFULL, TRUE  );
      WinEnableControl( pmp->hwndFrame, FID_HORZSCROLL,  TRUE  );
      WinEnableControl( pmp->hwndFrame, FID_VERTSCROLL,  TRUE  );

      /* process this new mode */
      switch( pmp->ulMode )
      {
      case MODE_BITMAP:
        /* load the bitmap into memory so it is compatible with the screen */
        WinSendMsg( hwnd, WM_USER_DISABLE_CLIENT, 0, 0 );
        WinPostMsg( pmp->hwndObject, WM_USER_LOAD_BITMAP,
                    (MPARAM)hwnd, (MPARAM)FLAGS_SCREEN );
        break;

      case MODE_METAFILE:
        /* make object window read metafile */
        WinSendMsg( hwnd, WM_USER_DISABLE_CLIENT, 0, 0 );
        WinPostMsg( pmp->hwndObject, WM_USER_LOAD_METAFILE, (MPARAM)hwnd, 0 );
        break;

      case MODE_TEXT:
        /* turn on options for text mode */
        WinEnableMenuItem( pmp->hwndMenubar, IDM_PAGEDOWN, TRUE  );
        WinEnableMenuItem( pmp->hwndMenubar, IDM_SETFONT,  TRUE  );
        /* reset view matrix that was last in effect for viewing text pages; */
        /* this gets lost after viewing a metafile */
        bOK = GpiSetDefaultViewMatrix( pmp->hpsClient, 9,
                                       &pmp->matlfDefView, TRANSFORM_REPLACE );
        pmassert( pmp->hab, bOK );
        /* disable until text loaded */
        WinSendMsg( hwnd, WM_USER_DISABLE_CLIENT, 0, 0 );
        /* tell object window to load the text file */
        bOK = WinPostMsg( pmp->hwndObject, WM_USER_LOAD_TEXT, (MPARAM)hwnd, 0 );
        pmassert( pmp->hab, bOK );
        break;


      case MODE_UNKNOWN:
        /* size screen to get correct scrollbars */
        WinPostMsg( pmp->hwndClient, WM_SIZE, 0, 0 );
        break;

      }
      return (MRESULT) 0;

   case WM_VSCROLL:
      pmp = (PMAIN_PARM) WinQueryWindowULong( hwnd, QWL_USER );

      /* Compute some fraction of scroll bar range for a unit of scrolling. */
      sStep  = pmp->sVScrollRange / 50;

      switch( SHORT2FROMMP( mp2 ))
      {
      case SB_LINEUP:
         pmp->sVScrollPos -= sStep;
         break;
      case SB_PAGEUP:
         pmp->sVScrollPos -= pmp->sizelClient.cy;
         break;
      case SB_LINEDOWN:
         pmp->sVScrollPos += sStep;
         break;
      case SB_PAGEDOWN:
         pmp->sVScrollPos += pmp->sizelClient.cy;
         break;
      case SB_SLIDERPOSITION:
      case SB_SLIDERTRACK:
         sNewPos          = SHORT1FROMMP( mp2 );
         pmp->sVScrollPos = sNewPos;
         break;
      }

      /* Don't allow step assignments to exceed limits of zero to range. */
      pmp->sVScrollPos = max( (SHORT)0,
                              min( pmp->sVScrollPos, pmp->sVScrollRange ));

      if( pmp->sVScrollPos != SHORT1FROMMR(WinSendMsg( pmp->hwndVScroll,
          SBM_QUERYPOS, (MPARAM)0, (MPARAM)0 )))
      {
         /*
          * New scroll bar thumbbutton position is different than current.
          * Set a new Y translation value to effect the scroll.
          * Current scale setting affects the Y element of the matrix.
          */
         pmp->matlfDefView.lM32 = OFFSET_XY_TWIPS + (LONG)(pmp->floatScale *
                          (float)( pmp->sVScrollPos - pmp->sVScrollRange ));

         pmp->matlfDefView.lM32 =  (LONG)(pmp->floatScale *
             (float)( OFFSET_XY_TWIPS +
                      pmp->sVScrollPos -
                      pmp->sVScrollRange ));

         bOK = GpiSetDefaultViewMatrix( pmp->hpsClient,
                                        9,
                                        &pmp->matlfDefView,
                                        TRANSFORM_REPLACE );
         pmassert( pmp->hab, bOK );
         CalibrateVerticalScrollBar( pmp );
         WinInvalidateRect( hwnd, NULL, FALSE );
      }
      return (MRESULT) 0;
   }
   return WinDefWindowProc( hwnd, msg, mp1, mp2 );
}  /* End of WinProc */
Пример #5
0
MRESULT EXPENTRY ClientWinProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
{
    PGLOBALS            pg;
    RECTL               rectl;
    ULONG               rc;
    LONG                lrc;
    char                szWork[ LEN_WORKSTRING ];
    FILE                *f;
    SWP                 swp;

    switch( msg ) {

    case WM_CLOSE:
        // mshell does not close, but at least it can minimize and get out of the way
        pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );
        WinSetWindowPos( pg->hwndFrame, HWND_BOTTOM, 0, 0, 0, 0, SWP_MINIMIZE );
        return (MRESULT) 0;

    case WM_CREATE:
        // see create.c
        pg = Create( hwnd );
        break;

    case WM_COMMAND:
        // see menu.c
        return Command( hwnd, msg, mp1, mp2 );

    case WM_CONTROL:
        pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );

        switch( SHORT1FROMMP( mp1 )) {

            case ID_LISTBOX:

                switch( SHORT2FROMMP( mp1 )) {

                case LN_ENTER:
                    // user wants to start a program
                    WinSendMsg( hwnd, WM_USER_DISABLE_CLIENT, 0, 0 );

                    // see object.c
                    // get index from listbox; works as index to aStartem array
                    lrc = (LONG) WinSendMsg( pg->hwndListbox,
                                             LM_QUERYSELECTION,
                                             (MPARAM)LIT_FIRST, 0 );
#ifdef DEBUG
                    pmassert( pg->hab, LIT_NONE != lrc );
#endif

                    // pass index of program to start in mp2
                    WinPostMsg( pg->hwndObject,
                                WM_USER_START,
                                (MPARAM) hwnd,
                                (MPARAM) lrc );
                    break;
                }
                break;
        }
        return (MRESULT) 0;

    case WM_ERASEBACKGROUND:
        // see Petzold, WM_PAINT below
        return (MRESULT) 1;

    case WM_MOUSEMOVE:
        // display which pointer?
        if( WinIsWindowEnabled( hwnd )) {
            // not disabled; display regular pointer
            WinSetPointer( HWND_DESKTOP,
                           WinQuerySysPointer( HWND_DESKTOP, SPTR_ARROW, FALSE ));
        } else {
            // disabled; display hourglass
            WinSetPointer( HWND_DESKTOP,
                           WinQuerySysPointer( HWND_DESKTOP, SPTR_WAIT, FALSE ));
        }
        return (MRESULT) 0;

    case WM_NACK_NO_INI:
        pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );
        WinSendMsg( hwnd, WM_USER_ENABLE_CLIENT, 0, 0 );

#define PSZNOINIPROMPT "\
Can't find \\MSHELL.INI, a plain text file used to configure MShell.\n\
\n\
Create a default one?"

        rc = (ULONG)WinMessageBox( HWND_DESKTOP,
                                   pg->hwndFrame,
                                   PSZNOINIPROMPT,
                                   CAPTION,
                                   0,
                                   MB_ICONEXCLAMATION | MB_YESNOCANCEL );
        if( MBID_YES == rc ) {

#define PSZDEFINI "\
* MSHELL.INI defines programs that MShell can start\n\
* Configure MSHELL.EXE using the RUNWORKPLACE setting in CONFIG.SYS\n\
* MSHELL.EXE finds its INI in the root of the boot drive\n\
* Each line in the INI file has two parts:\n\
*  1: program title text to appear in MShell window\n\
*  2: the CMD.EXE start command to start the program\n\
* Separate the parts with a semicolon\n\
* Lines starting with ! start automatically at bootup\n\
* Comment lines begin with  *\n\
\n\
* command processors\n\
OS/2 Command Prompt; start /f\n\
DOS Command Prompt; start /f /fs /dos\n\
Win-OS/2; start /fs /dos /c winos2\n\
\n\
* other stuff\n\
Help for Start; start help start\n\
Solitaire; start /f klondike\n\
\n\
* example to start from other than C:\\\n\
* PM Program; d: & cd \\pmpgm & start pmpgm\n"

            if( f = fopen( "\\MSHELL.INI", "w" )) {
                fprintf( f, PSZDEFINI );
                fclose( f );
            }

            // make like user pressed refresh
            WinPostMsg( hwnd, WM_COMMAND, (MPARAM)IDM_REFRESH, 0 );
        }
        return (MRESULT) 0;

    case WM_NACK_NO_SPOOLER:
        pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );
        WinMessageBox( HWND_DESKTOP,
                       pg->hwndFrame,
                       "Sorry, could not start the spooler.",
                       CAPTION,
                       0,
                       MB_CANCEL );
        return (MRESULT) 0;

    case WM_NACK_SYNTAX_ERROR:
        pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );
        // line number of INI file in mp2
        sprintf( szWork, "Line %d of \\mshell.ini is unrecognized.", (SHORT) mp2 );
        WinMessageBox( HWND_DESKTOP, pg->hwndFrame, szWork, CAPTION, 0, MB_CANCEL );
        return (MRESULT) 0;

    case WM_PAINT:
        // see WM_ERASEBACKGROUND above;
        // see Petzold sections on control windows which are children of the client window
        break;

    case WM_SAVEAPPLICATION:
        // save restored position
        pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );
        WinQueryWindowPos( pg->hwndFrame, &swp );

        if( swp.fl &  SWP_MINIMIZE ) {
            // mshell is currently minimized
            pg->profile.swpMinimized.x  = swp.x;
            pg->profile.swpMinimized.y  = swp.y;
            // get restored size from window words
            pg->profile.swp.x  = WinQueryWindowUShort( pg->hwndFrame, QWS_XRESTORE  );
            pg->profile.swp.y  = WinQueryWindowUShort( pg->hwndFrame, QWS_YRESTORE  );
            pg->profile.swp.cx = WinQueryWindowUShort( pg->hwndFrame, QWS_CXRESTORE );
            pg->profile.swp.cy = WinQueryWindowUShort( pg->hwndFrame, QWS_CYRESTORE );
        } else if( swp.fl &  SWP_MAXIMIZE ) {
            // mshell is currently maximized
            // get restored size from window words
            pg->profile.swp.x  = WinQueryWindowUShort( pg->hwndFrame, QWS_XRESTORE  );
            pg->profile.swp.y  = WinQueryWindowUShort( pg->hwndFrame, QWS_YRESTORE  );
            pg->profile.swp.cx = WinQueryWindowUShort( pg->hwndFrame, QWS_CXRESTORE );
            pg->profile.swp.cy = WinQueryWindowUShort( pg->hwndFrame, QWS_CYRESTORE );
            // get minimized icon position from window words
            pg->profile.swpMinimized.x  = WinQueryWindowUShort( pg->hwndFrame, QWS_XMINIMIZE );
            pg->profile.swpMinimized.y  = WinQueryWindowUShort( pg->hwndFrame, QWS_YMINIMIZE );
        } else {
            // mshell is in the restored state
            pg->profile.swp = swp;
            // get minimized icon position from window words
            pg->profile.swpMinimized.x  = WinQueryWindowUShort( pg->hwndFrame, QWS_XMINIMIZE );
            pg->profile.swpMinimized.y  = WinQueryWindowUShort( pg->hwndFrame, QWS_YMINIMIZE );
        }

        // write to ini
        PrfWriteProfileData( HINI_PROFILE,
                             INI_APP,
                             INIKEY_PROFILE,
                             (PVOID)&pg->profile,
                             sizeof( PROFILE ));

#if 0
        // save restored position
        // TO DO: save icon position
        pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );
        WinQueryWindowPos( pg->hwndFrame, &(pg->profile.swp) );
        if( 0 == ( pg->profile.swp.fl & ( SWP_MINIMIZE | SWP_MAXIMIZE ))) {
            // app in restored state, swp struct fine the way it is.
        }else{
            // app currently min'd or max'd. pull restore info from win words
            pg->profile.swp.x  = WinQueryWindowUShort( pg->hwndFrame, QWS_XRESTORE);
            pg->profile.swp.y  = WinQueryWindowUShort( pg->hwndFrame, QWS_YRESTORE);
            pg->profile.swp.cx = WinQueryWindowUShort( pg->hwndFrame, QWS_CXRESTORE);
            pg->profile.swp.cy = WinQueryWindowUShort( pg->hwndFrame, QWS_CYRESTORE);
        }
        // write to ini
        PrfWriteProfileData( HINI_PROFILE,
                             INI_APP,
                             INIKEY_PROFILE,
                             (PVOID)&(pg->profile),
                             sizeof( PROFILE ));
#endif

        break;

    case WM_SIZE:
        pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );
        WinQueryWindowRect( hwnd, &rectl );
        WinSetWindowPos( pg->hwndListbox,
                         HWND_TOP,
                         0, 0,
                         rectl.xRight,
                         rectl.yTop,
                         SWP_SIZE | SWP_MOVE | SWP_SHOW );
        return (MRESULT) 0;

    case WM_USER_ACK:
        // re-enable the window
        pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );

        switch( (ULONG)mp1 ) {

            case WM_CREATE:
                WinSetFocus( HWND_DESKTOP, pg->hwndListbox );
                break;
        }
        WinSendMsg( hwnd, WM_USER_ENABLE_CLIENT, 0, 0 );
        return (MRESULT) 0;

    case WM_USER_DISABLE_CLIENT:
        // this message sent; disable menu action bar as well
        pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );
        WinEnableWindow( pg->hwndClient,  FALSE );
        WinEnableWindow( pg->hwndMenubar, FALSE );
        WinEnableWindow( pg->hwndListbox, FALSE );
        return (MRESULT) 0;

    case WM_USER_ENABLE_CLIENT:
        // this message sent; enable client and action bar
        pg = (PGLOBALS) WinQueryWindowULong( hwnd, QWL_USER );
        WinEnableWindow( pg->hwndClient,  TRUE );
        WinEnableWindow( pg->hwndMenubar, TRUE );
        WinEnableWindow( pg->hwndListbox, TRUE );
        return (MRESULT) 0;
    }

    return( WinDefWindowProc( hwnd, msg, mp1, mp2 ));
}
Пример #6
0
static void onCommand(HWND hWnd, int id, HWND hWndCtl, USHORT codeNotify)
{
  CPlugin * pPlugin = (CPlugin *)WinQueryWindowULong(hWnd, QWL_USER);
  if(!pPlugin)
    return;

  switch (id)
  {
    case IDC_EDIT_SCRIPT_FILE_NAME:
    {
      if(codeNotify != EN_CHANGE)
        break;
      char szString[256];
      WinQueryWindowText(WinWindowFromID(hWnd, IDC_EDIT_SCRIPT_FILE_NAME), sizeof(szString), szString);
      int iLen = strlen(szString);
      WinEnableWindow(WinWindowFromID(hWnd, IDC_BUTTON_GO), (iLen > 0));
      if(iLen <= 0)
        break;

      // synchronize log filename with current script filename
      char szLogFileName[256];
      char * p = strchr(szString, '.');

      if(p != NULL)
        *p = '\0';

      strcpy(szLogFileName, szString);
      strcat(szLogFileName, ".log");
      WinSetWindowText(WinWindowFromID(WinQueryWindow(hWnd, QW_PARENT), IDC_EDIT_LOG_FILE_NAME), szLogFileName);

      // restore
      if(p)
        *p = '.';

      pPlugin->updatePrefs(gp_scriptfile, FALSE, szString);

      break;
    }
    /*
    case IDC_BUTTON_STOP:
      assert(pScripter != NULL);
      pScripter->setStopAutoExecFlag(TRUE);
      WinShowWindow(WinWindowFromID(hWnd, IDC_BUTTON_GO), TRUE);
      WinShowWindow(WinWindowFromID(hWnd, IDC_BUTTON_STOP), FALSE);
      break;
    */
    case IDC_BUTTON_GO:
    {
      pLogger->blockDumpToFile(FALSE);

      //WinShowWindow(WinWindowFromID(hWnd, IDC_BUTTON_GO), FALSE);
      //WinShowWindow(WinWindowFromID(hWnd, IDC_BUTTON_STOP), TRUE);
      //UpdateWindow(WinWindowFromID(hWnd, IDC_BUTTON_STOP));
      EnableWindowNow(WinWindowFromID(hWnd, IDC_BUTTON_GO), FALSE);

      EnableWindowNow(WinWindowFromID(hWnd, IDC_EDIT_SCRIPT_FILE_NAME), FALSE);
      EnableWindowNow(WinWindowFromID(WinQueryWindow(hWnd, QW_PARENT), IDC_EDIT_LOG_FILE_NAME), FALSE);
      EnableWindowNow(WinWindowFromID(WinQueryWindow(hWnd, QW_PARENT), IDC_CHECK_SHOW_LOG), FALSE);
      EnableWindowNow(WinWindowFromID(WinQueryWindow(hWnd, QW_PARENT), IDC_CHECK_LOG_TO_FRAME), FALSE);
      EnableWindowNow(WinWindowFromID(WinQueryWindow(hWnd, QW_PARENT), IDC_CHECK_LOG_TO_FILE), FALSE);
      BOOL bFlashWasEnabled = FALSE;
      if(WinIsWindowEnabled(WinWindowFromID(WinQueryWindow(hWnd, QW_PARENT), IDC_BUTTON_FLUSH)))
      {
        bFlashWasEnabled = TRUE;
        EnableWindowNow(WinWindowFromID(WinQueryWindow(hWnd, QW_PARENT), IDC_BUTTON_FLUSH), FALSE);
      }
      EnableWindowNow(WinWindowFromID(WinQueryWindow(hWnd, QW_PARENT), IDC_BUTTON_CLEAR), FALSE);
      EnableWindowNow(WinWindowFromID(WinQueryWindow(hWnd, QW_PARENT), IDC_RADIO_MODE_MANUAL), FALSE);
      EnableWindowNow(WinWindowFromID(WinQueryWindow(hWnd, QW_PARENT), IDC_RADIO_MODE_AUTO), FALSE);
    
      if(pScripter != NULL)
        delete pScripter;

      pScripter = new CScripter();
      pScripter->associate(pPlugin);

      char szFileName[_MAX_PATH];
      pPlugin ->getModulePath(szFileName, sizeof(szFileName));

      char szFile[_MAX_PATH];
      WinQueryWindowText(WinWindowFromID(hWnd, IDC_EDIT_SCRIPT_FILE_NAME), sizeof(szFile), szFile);
      strcat(szFileName, szFile);

      if(pScripter->createScriptFromFile(szFileName))
      {
        int iRepetitions = pScripter->getCycleRepetitions();
        int iDelay = pScripter->getCycleDelay();
        if(iDelay < 0)
          iDelay = 0;

        assert(pLogger != NULL);
        pLogger->resetStartTime();

        ShowWindowNow(WinWindowFromID(hWnd, IDC_STATIC_REPETITIONS_LABEL), TRUE);
        char szLeft[256];

        for(int i = 0; i < iRepetitions; i++)
        {
          sprintf(szLeft, "%i", iRepetitions - i);
          WinSetWindowText(WinWindowFromID(hWnd, IDC_STATIC_REPETITIONS_LEFT), szLeft);
          pScripter->executeScript();
          /*
          if(pScripter->getStopAutoExecFlag())
          {
            pScripter->setStopAutoExecFlag(FALSE);
            break;
          }
          */
          if(iDelay != 0)
            XP_Sleep(iDelay);
        }
      }
      else
      {
        WinMessageBox(HWND_DESKTOP, hWnd, "Script file not found or invalid", "", 0, MB_OK | MB_ERROR);
      }

      delete pScripter;
      pScripter = NULL;

      WinSetWindowText(WinWindowFromID(hWnd, IDC_STATIC_REPETITIONS_LEFT), "");
      WinShowWindow(WinWindowFromID(hWnd, IDC_STATIC_REPETITIONS_LABEL), FALSE);

      //WinShowWindow(WinWindowFromID(hWnd, IDC_BUTTON_GO), TRUE);
      //WinShowWindow(WinWindowFromID(hWnd, IDC_BUTTON_STOP), FALSE);
      WinEnableWindow(WinWindowFromID(hWnd, IDC_BUTTON_GO), TRUE);

      WinEnableWindow(WinWindowFromID(hWnd, IDC_EDIT_SCRIPT_FILE_NAME), TRUE);
      WinEnableWindow(WinWindowFromID(WinQueryWindow(hWnd, QW_PARENT), IDC_EDIT_LOG_FILE_NAME), TRUE);
      WinEnableWindow(WinWindowFromID(WinQueryWindow(hWnd, QW_PARENT), IDC_CHECK_SHOW_LOG), TRUE);
      WinEnableWindow(WinWindowFromID(WinQueryWindow(hWnd, QW_PARENT), IDC_CHECK_LOG_TO_FRAME), TRUE);
      WinEnableWindow(WinWindowFromID(WinQueryWindow(hWnd, QW_PARENT), IDC_CHECK_LOG_TO_FILE), TRUE);
      if(bFlashWasEnabled)
        WinEnableWindow(WinWindowFromID(WinQueryWindow(hWnd, QW_PARENT), IDC_BUTTON_FLUSH), TRUE);
      WinEnableWindow(WinWindowFromID(WinQueryWindow(hWnd, QW_PARENT), IDC_BUTTON_CLEAR), TRUE);
      WinEnableWindow(WinWindowFromID(WinQueryWindow(hWnd, QW_PARENT), IDC_RADIO_MODE_MANUAL), TRUE);
      WinEnableWindow(WinWindowFromID(WinQueryWindow(hWnd, QW_PARENT), IDC_RADIO_MODE_AUTO), TRUE);
      break;
    }
    default:
      break;
  }
}
MRESULT EXPENTRY ClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) {
	static HWND hwndFrame, hwndButton[10];
	static INT  cxClient, cyClient, cyChar;
	static LONG ButtonWidth, ButtonHeight;
	static CLR  buttonColour;
	CHAR        szBuffer[32];
	FONTMETRICS fm;
	HAB         hab;
	HPS         hps;
	INT         id;
	RECTL       rcl;

	switch(msg) {
		case WM_CREATE:
			hab = WinQueryAnchorBlock(hwnd);
			hwndFrame = WinQueryWindow(hwnd, QW_PARENT);
			hps = WinGetPS(hwnd);
			GpiQueryFontMetrics(hps, sizeof(fm),&fm);
			cyChar = fm.lMaxBaselineExt;
			WinReleasePS(hps);
			buttonColour.Index = 0x00CCCCCC;

// Buttons should be big enough to hold the pointer, with a 4 pixel border
			ButtonWidth = WinQuerySysValue(HWND_DESKTOP, SV_CXPOINTER) + 4;
			ButtonHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYPOINTER) + 4;
			hwndButton[0] = WinCreateWindow(hwnd, SHADEDBTNCLASS, "100", WS_VISIBLE | GBT_NORIGHTLINE | GBT_GRAPHIC, 0, 0, ButtonWidth, ButtonHeight, hwnd, HWND_BOTTOM, 0, NULL, NULL);
			hwndButton[1] = WinCreateWindow(hwnd, SHADEDBTNCLASS, "101", WS_VISIBLE | GBT_NOLEFTLINE | GBT_GRAPHIC, 0, 0, ButtonWidth, ButtonHeight, hwnd, HWND_BOTTOM, 1, NULL, NULL);

// This is the status bar
			hwndButton[2] = WinCreateWindow(hwnd, SHADEDBTNCLASS, "Status Bar", WS_VISIBLE | GBT_NOPUSH, 0, 0, 0, cyChar * 5 / 4, hwnd, HWND_BOTTOM, 2, NULL, NULL);
			sprintf(szBuffer, "Red: %d Green: %d Blue: %d", buttonColour.rgb.red, buttonColour.rgb.green, buttonColour.rgb.blue);
			WinSetWindowText(hwndButton[2], szBuffer);

// Buttons to change the colour of the about button
			hwndButton[3] = WinCreateWindow(hwnd, SHADEDBTNCLASS, "<", WS_VISIBLE | GBT_NORIGHTLINE, 0, 0, ButtonWidth, cyChar * 5 / 4, hwnd, HWND_BOTTOM, 3, NULL, NULL);
			hwndButton[4] = WinCreateWindow(hwnd, SHADEDBTNCLASS, ">", WS_VISIBLE | GBT_NOLEFTLINE, 0, 0, ButtonWidth, cyChar * 5 / 4, hwnd, HWND_BOTTOM, 4, NULL, NULL);
			hwndButton[5] = WinCreateWindow(hwnd, SHADEDBTNCLASS, "<", WS_VISIBLE | GBT_NORIGHTLINE, 0, 0, ButtonWidth, cyChar * 5 / 4, hwnd, HWND_BOTTOM, 5, NULL, NULL);
			hwndButton[6] = WinCreateWindow(hwnd, SHADEDBTNCLASS, ">", WS_VISIBLE | GBT_NOLEFTLINE, 0, 0, ButtonWidth, cyChar * 5 / 4, hwnd, HWND_BOTTOM, 6, NULL, NULL);
			hwndButton[7] = WinCreateWindow(hwnd, SHADEDBTNCLASS, "<", WS_VISIBLE | GBT_NORIGHTLINE, 0, 0, ButtonWidth, cyChar * 5 / 4, hwnd, HWND_BOTTOM, 7, NULL, NULL);
			hwndButton[8] = WinCreateWindow(hwnd, SHADEDBTNCLASS, ">", WS_VISIBLE | GBT_NOLEFTLINE, 0, 0, ButtonWidth, cyChar * 5 / 4, hwnd, HWND_BOTTOM, 8, NULL, NULL);
// info about this program
			hwndButton[9] = WinCreateWindow(hwnd, SHADEDBTNCLASS, "About", WS_VISIBLE | GBT_RIGHTROUND | GBT_LEFTROUND, 0, 0, 2 * ButtonWidth, cyChar * 5 / 4, hwnd, HWND_BOTTOM, 9, NULL, NULL);

// change the colour of the buttons
			WinSendMsg(hwndButton[3], GBM_SETCOLOR, MPFROMLONG(0x00FFCCCC), NULL);
			WinSendMsg(hwndButton[4], GBM_SETCOLOR, MPFROMLONG(0x00FFCCCC), NULL);
			WinSendMsg(hwndButton[5], GBM_SETCOLOR, MPFROMLONG(0x00CCFFCC), NULL);
			WinSendMsg(hwndButton[6], GBM_SETCOLOR, MPFROMLONG(0x00CCFFCC), NULL);
			WinSendMsg(hwndButton[7], GBM_SETCOLOR, MPFROMLONG(0x00CCCCFF), NULL);
			WinSendMsg(hwndButton[8], GBM_SETCOLOR, MPFROMLONG(0x00CCCCFF), NULL);
			WinSendMsg(hwndButton[9], GBM_SETCOLOR, MPFROMLONG(buttonColour.Index), NULL);
			return 0;
		case WM_SIZE:
			hps = WinGetPS(hwnd);
			GpiQueryFontMetrics(hps, sizeof(fm),&fm);
			cyChar = fm.lMaxBaselineExt;
			WinReleasePS(hps);
			cxClient = SHORT1FROMMP(mp2);
			cyClient = SHORT2FROMMP(mp2);
// Center the buttons
			for(id = 0; id < 2; id++)
				WinSetWindowPos(hwndButton[id], NULLHANDLE, (cxClient >> 1) + ButtonWidth * (id - 1), (cyClient - ButtonHeight) >> 1, 0, 0, SWP_MOVE);
			for(id = 3; id < 9; id++)
				WinSetWindowPos(hwndButton[id], NULLHANDLE, (cxClient >> 1) + ButtonWidth * (-(id % 2)), ((cyClient + ButtonHeight) >> 1) + (3 - (id-1) / 2) * cyChar * 5 / 4, 0, 0, SWP_MOVE);
			WinSetWindowPos(hwndButton[9], NULLHANDLE, (cxClient >> 1) - ButtonWidth, ((cyClient - ButtonHeight) >> 1) - cyChar * 15 / 8, 0, 0, SWP_MOVE);
// make the status bar span the width of the window
			WinSetWindowPos(hwndButton[2], NULLHANDLE, 0, 0, cxClient, cyChar * 5 / 4, SWP_SIZE);

// Enable "Smaller" button if window is large enough for the buttons
			if (!WinIsWindowEnabled(hwndButton[0]) && ((9 * cxClient / 10) >= (2 * ButtonWidth)) && ((9  * cyClient / 10) >= (ButtonHeight + cyChar * 15 / 2)))
				WinEnableWindow(hwndButton[0], TRUE);
// Disable "Smaller" button if window is too small for the buttons
			if (WinIsWindowEnabled(hwndButton[0]) && (((9 * cxClient / 10) < (2 * ButtonWidth)) || ((9  * cyClient / 10) < (ButtonHeight + cyChar * 15 / 2))))
				WinEnableWindow(hwndButton[0], FALSE);
			return 0;
		case WM_COMMAND:
			WinQueryWindowRect(hwnd, &rcl);
			WinMapWindowPoints(hwnd, HWND_DESKTOP, (PPOINTL) &rcl, 2);

			switch(COMMANDMSG(&msg)->cmd) {
				case 0: // "Smaller"
					rcl.xLeft   += cxClient / 20;
					rcl.xRight  -= cxClient / 20;
					rcl.yBottom += cyClient / 20;
					rcl.yTop    -= cyClient / 20;
					break;
				case 1: // "Larger"
					rcl.xLeft   -= cxClient / 20;
					rcl.xRight  += cxClient / 20;
					rcl.yBottom -= cyClient / 20;
					rcl.yTop    += cyClient / 20;
					break;
				case 3: // change red
					buttonColour.rgb.red--;
					if (buttonColour.rgb.red == 0)
						WinEnableWindow(hwndButton[3], FALSE);
					if (!WinIsWindowEnabled(hwndButton[4]))
						WinEnableWindow(hwndButton[4], TRUE);
					break;
				case 4:
					buttonColour.rgb.red++;
					if (buttonColour.rgb.red == 255)
						WinEnableWindow(hwndButton[4], FALSE);
					if (!WinIsWindowEnabled(hwndButton[3]))
						WinEnableWindow(hwndButton[3], TRUE);
					break;
				case 5: // change green
					buttonColour.rgb.green--;
					if (buttonColour.rgb.green == 0)
						WinEnableWindow(hwndButton[5], FALSE);
					if (!WinIsWindowEnabled(hwndButton[6]))
						WinEnableWindow(hwndButton[6], TRUE);
					break;
				case 6:
					buttonColour.rgb.green++;
					if (buttonColour.rgb.green == 255)
						WinEnableWindow(hwndButton[6], FALSE);
					if (!WinIsWindowEnabled(hwndButton[5]))
						WinEnableWindow(hwndButton[5], TRUE);
					break;
				case 7:// change blue
					buttonColour.rgb.blue--;
					if (buttonColour.rgb.blue == 0)
						WinEnableWindow(hwndButton[7], FALSE);
					if (!WinIsWindowEnabled(hwndButton[8]))
						WinEnableWindow(hwndButton[8], TRUE);
					break;
				case 8:
					buttonColour.rgb.blue++;
					if (buttonColour.rgb.blue == 255)
						WinEnableWindow(hwndButton[8], FALSE);
					if (!WinIsWindowEnabled(hwndButton[7]))
						WinEnableWindow(hwndButton[7], TRUE);
					break;
				case 9:
					WinDlgBox(HWND_DESKTOP, hwnd, AboutDlgProc, NULLHANDLE, IDD_ABOUT, NULL);
					return 0;
			}
			sprintf(szBuffer, "Red: %d Green: %d Blue: %d", buttonColour.rgb.red, buttonColour.rgb.green, buttonColour.rgb.blue);
			WinSetWindowText(hwndButton[2], szBuffer);
			WinCalcFrameRect(hwndFrame, &rcl, FALSE);
			WinSetWindowPos(hwndFrame, NULLHANDLE, rcl.xLeft, rcl.yBottom, rcl.xRight - rcl.xLeft, rcl.yTop - rcl.yBottom, SWP_MOVE | SWP_SIZE);
			WinPostMsg(hwndButton[9], GBM_SETCOLOR, MPFROMLONG(buttonColour.Index), NULL);
			return 0;
		case WM_ERASEBACKGROUND:
			WinFillRect((HPS)LONGFROMMP(mp1), PVOIDFROMMP(mp2), CLR_PALEGRAY);
			return 0;
	}
	return WinDefWindowProc(hwnd, msg, mp1, mp2);
}