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)); }
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 */
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 )); }
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); }