home *** CD-ROM | disk | FTP | other *** search
Text File | 1988-08-11 | 57.5 KB | 2,191 lines |
- Microsoft Systems Journal
- Volume 3; Issue 1; January, 1988
-
- Code Listings For:
-
- Saywhat
- pp. 09-30
-
- Author(s): Michael Geary
- Title: Converting Windows Applications For Microsoft OS/2 PM
-
-
-
- Figure 1w
- =========
-
-
- # MAKE file for SAYWHAT (Windows version)
-
- sw.obj: sw.c sw.h
- cl -c -AS -DLINT_ARGS -Gcsw -Oas -W3 -Zdp sw.c
-
- sw.res: sw.rc sw.h
- rc -r sw.rc
-
- saywhat.exe: sw.obj sw.res sw.def
- link4 sw, saywhat/align:16, saywhat/map/line, slibw, sw.def
- rc sw.res saywhat.exe
- mapsym saywhat
-
-
- Figure 3w
- =========
-
-
- ; SW.DEF - Module definition file for SAYWHAT (Windows version)
-
- NAME SayWhat
-
- DESCRIPTION 'Say What!'
-
- STUB 'WINSTUB.EXE'
-
- CODE MOVEABLE
- DATA MOVEABLE MULTIPLE
-
- HEAPSIZE 128
- STACKSIZE 4096
-
- EXPORTS
- SayAboutDlgProc @1
- SayWhatDlgProc @2
- SayWhatWndProc @3
-
-
- Figure 4w
- =========
-
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- #include <style.h>
- #include "sw.h"
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- STRINGTABLE
- BEGIN
- STR_NAME, "SayWhat!"
- STR_TITLE, "Say What!"
- STR_WHAT, "Hello Windows!"
- END
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- SayWhat! MENU
- BEGIN
-
- POPUP "&Say"
- BEGIN
- MENUITEM "&What..." , CMD_WHAT
- MENUITEM SEPARATOR
- MENUITEM "E&xit" , CMD_EXIT
- MENUITEM SEPARATOR
- MENUITEM "A&bout SayWhat!..." , CMD_ABOUT
- END
-
- END
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- DLG_ABOUT DIALOG 19, 17, 130, 83
- STYLE WS_DLGFRAME | WS_POPUP
- BEGIN
- CTEXT "Microsoft Windows", -1, 0, 8, 127, 8
- CTEXT "Say What!", -1, 0, 18, 127, 8
- CTEXT "Version 1.00", -1, 0, 30, 127, 8
- CTEXT "By Michael Geary", -1, 0, 44, 129, 8
- DEFPUSHBUTTON "Ok", IDOK, 48, 62, 32, 14
- END
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- DLG_WHAT DIALOG 49, 41, 177, 103
- CAPTION "Say What!"
- STYLE WS_CAPTION | WS_SYSMENU | WS_VISIBLE | WS_POPUP
- BEGIN
- CONTROL "Say &What:" -1, "Static", SS_LEFT | WS_GROUP, 8, 10, 40, 8
- CONTROL "" ITEM_WHAT, "Edit", ES_LEFT | ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP, 56, 8, 112, 12
- CONTROL "&Time Delay:" -1, "Static", SS_LEFT, 8, 28, 53, 8
- CONTROL "" ITEM_INTBAR, "ScrollBar", SBS_HORZ | WS_TABSTOP, 56, 28, 88, 8
- CONTROL "" ITEM_INTERVAL, "Edit", ES_LEFT | WS_BORDER | WS_TABSTOP, 152, 26, 16, 12
- CONTROL "&Stability:" -1, "Static", SS_LEFT, 8, 46, 56, 8
- CONTROL "" ITEM_DISTBAR, "ScrollBar", SBS_HORZ | WS_TABSTOP, 56, 46, 88, 8
- CONTROL "" ITEM_DISTANCE, "Edit", ES_LEFT | WS_BORDER | WS_TABSTOP, 152, 44, 16, 12
- CONTROL "Painting:" -1, "Static", SS_LEFT, 8, 64, 40, 8
- CONTROL "&Clean" ITEM_CLEAN, "Button", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 56, 62, 36, 12
- CONTROL "&Flicker" ITEM_FLICKER, "Button", BS_AUTORADIOBUTTON, 96, 62, 42, 12
- CONTROL "Enter" IDOK, "Button", BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP, 24, 82, 48, 14
- CONTROL "Esc=Close" IDCANCEL, "Button", BS_PUSHBUTTON | WS_TABSTOP, 104, 82, 48, 14
- END
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-
- Figure 5w
- =========
-
-
- /* SW.H - C header file for SAYWHAT (Windows version) */
-
- /* String table constants */
-
- #define STR_NAME 101
- #define STR_TITLE 102
- #define STR_WHAT 103
-
- /* Menu command IDs */
-
- #define CMD_ABOUT 201
- #define CMD_EXIT 202
- #define CMD_WHAT 203
-
- /* Dialog box resource IDs */
-
- #define DLG_ABOUT 301
- #define DLG_WHAT 302
-
- /* 'What...' dialog box item IDs */
-
- #define ITEM_WHAT 401
- #define ITEM_INTBAR 402
- #define ITEM_INTERVAL 403
- #define ITEM_DISTBAR 404
- #define ITEM_DISTANCE 405
- #define ITEM_CLEAN 406
- #define ITEM_FLICKER 407
-
- /* Timer IDs */
-
- #define TIMER_MOVE 501
- #define TIMER_CHAR 502
-
-
- Figure 6w
- =========
-
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *\
- * SW.C - C code for SayWhat - Windows version *
- \* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- #ifndef LINT_ARGS
- #define LINT_ARGS /* turn on argument checking for C runtime */
- #endif
-
- #include <windows.h>
- #include <limits.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include "sw.h"
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- #define MIN_INTERVAL 1 /* limits for nInterval */
- #define MAX_INTERVAL 999
-
- #define MIN_DISTANCE 1 /* limits for nDistance */
- #define MAX_DISTANCE 99
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Static variables */
-
- HANDLE hInstance; /* application instance handle */
-
- HWND hWndWhat; /* main window handle */
- HWND hWndPanel; /* contral panel dialog handle */
-
- FARPROC lpfnDlgProc; /* ProcInstance for dialog */
-
- char szAppName[10]; /* window class name */
- char szTitle[15]; /* main window title */
-
- char szText[40]; /* current "what" text */
- NPSTR pText = szText; /* ptr into szText for icon mode */
- char cBlank = ' '; /* a blank we can point to */
-
- RECT rcText; /* current text rectangle */
- POINT ptAdvance; /* increments for SayAdvanceText */
- POINT ptCharSize; /* X and Y size of a character */
- POINT ptScreenSize; /* X and Y size of the screen */
-
- int nDisplayPlanes; /* number of display planes */
- DWORD rgbTextColor; /* current text color */
- HBRUSH hbrBkgd; /* brush for erasing background */
-
- int nInterval = 40; /* current "Interval" setting */
- int nDistance = 30; /* current "Distance" setting */
- int nDistLeft = 0; /* change direction when hits 0 */
- BOOL bCleanPaint = TRUE; /* clean or flickery painting? */
- BOOL bMouseDown = FALSE; /* is mouse down? */
- BOOL bIconic = FALSE; /* is main window iconic? */
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Full prototypes for our functions to get type checking */
-
- BOOL FAR PASCAL SayAboutDlgProc( HWND, unsigned, WORD, LONG );
- void SayAdvanceTextChar( HWND );
- void SayAdvanceTextPos( HWND );
- void SayChangeColor( HWND );
- void SayDoBarMsg( HWND, HWND, WORD, int );
- void SayFillRect( HDC, int, int, int, int );
- void SayInitBar( HWND, int, int, int, int );
- BOOL SayInitApp( HANDLE, int );
- void SayInvalidateText( HWND );
- void SayLimitTextPos( HWND );
- void SayMoveText( HWND, POINT );
- void SaySetBar( HWND, int *, int );
- void SayExitApp( int );
- BOOL FAR PASCAL SayWhatDlgProc( HWND, unsigned, WORD, LONG );
- void SayWhatPaint( HWND );
- LONG FAR PASCAL SayWhatWndProc( HWND, unsigned, WORD, LONG );
- void PASCAL WinMain( HANDLE, HANDLE, LPSTR, int );
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Dialog function for the "About" box */
-
- BOOL FAR PASCAL SayAboutDlgProc( hWndDlg, wMsg, wParam, lParam )
- HWND hWndDlg;
- unsigned wMsg;
- WORD wParam;
- LONG lParam;
- {
- switch( wMsg )
- {
- case WM_COMMAND:
- switch( wParam )
- {
- case IDOK:
- EndDialog( hWndDlg, TRUE );
- return TRUE;
- }
- }
- return FALSE;
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Advances to next display character in iconic mode.
- * Forces in a blank when it reaches the end of string.
- */
-
- void SayAdvanceTextChar( hWnd )
- HWND hWnd;
- {
- if( ! bIconic )
- return;
-
- if( pText == &cBlank )
- pText = szText;
- else if( ! *(++pText) )
- pText = &cBlank;
-
- SayChangeColor( hWnd );
- SayInvalidateText( hWnd );
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Advances text position according to ptAdvance. Decrements
- * nDistLeft first, and when it reaches zero, sets a new
- * randomized ptAdvance and nDistLeft, also changes color.
- * Does nothing if mouse is down, so text will track mouse.
- */
-
- void SayAdvanceTextPos( hWnd )
- HWND hWnd;
- {
- int i;
-
- if( bMouseDown )
- return;
-
- SayInvalidateText( hWnd );
-
- if( nDistLeft-- < 0 ) {
- nDistLeft = rand() % nDistance + 1;
- do {
- i = rand();
- ptAdvance.x = (
- i < SHRT_MAX/3 ? -1
- : i < SHRT_MAX/3*2 ? 0
- : 1
- );
- i = rand();
- ptAdvance.y = (
- i < SHRT_MAX/3 ? -1
- : i < SHRT_MAX/3*2 ? 0
- : 1
- );
- } while( ptAdvance.x == 0 && ptAdvance.y == 0 );
- if( ! bIconic )
- SayChangeColor( hWnd );
- } else {
- rcText.left += ptAdvance.x;
- rcText.right += ptAdvance.x;
- rcText.top += ptAdvance.y;
- rcText.bottom += ptAdvance.y;
- }
-
- SayInvalidateText( hWnd );
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Changes color to a random selection, if color is available.
- * Forces a color change - if the random selection is the same
- * as the old one, it tries again.
- */
-
- void SayChangeColor( hWnd )
- HWND hWnd;
- {
- HDC hDC;
- DWORD rgbNew;
- DWORD rgbWindow;
-
- if( nDisplayPlanes <= 1 ) {
- rgbTextColor = GetSysColor(COLOR_WINDOWTEXT);
- } else {
- rgbWindow = GetSysColor(COLOR_WINDOW);
- hDC = GetDC( hWnd );
- do {
- rgbNew = GetNearestColor(
- hDC,
- MAKELONG( rand(), rand() ) & 0x00FFFFFFL
- );
- } while( rgbNew == rgbWindow || rgbNew == rgbTextColor );
- rgbTextColor = rgbNew;
- ReleaseDC( hWnd, hDC );
- }
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Handles scroll bar messages from the control dialog box.
- * Adjusts scroll bar position, taking its limits into account,
- * copies the scroll bar value into the adjacent edit control,
- * then sets the nDistance or nInterval variable appropriately.
- */
-
- void SayDoBarMsg( hWndDlg, hWndBar, wCode, nThumb )
- HWND hWndDlg;
- HWND hWndBar;
- WORD wCode;
- int nThumb;
- {
- int nPos;
- int nOldPos;
- int nMin;
- int nMax;
- int idBar;
-
- idBar = GetWindowWord( hWndBar, GWW_ID );
-
- nOldPos = nPos = GetScrollPos( hWndBar, SB_CTL );
- GetScrollRange( hWndBar, SB_CTL, &nMin, &nMax );
-
- switch( wCode )
- {
- case SB_LINEUP: --nPos; break;
-
- case SB_LINEDOWN: ++nPos; break;
-
- case SB_PAGEUP: nPos -= 10; break;
-
- case SB_PAGEDOWN: nPos += 10; break;
-
- case SB_THUMBPOSITION:
- case SB_THUMBTRACK: nPos = nThumb; break;
-
- case SB_TOP: nPos = nMin; break;
-
- case SB_BOTTOM: nPos = nMax; break;
- }
-
- if( nPos < nMin )
- nPos = nMin;
-
- if( nPos > nMax )
- nPos = nMax;
-
- if( nPos == nOldPos )
- return;
-
- SetScrollPos( hWndBar, SB_CTL, nPos, TRUE );
-
- SetDlgItemInt( hWndDlg, idBar+1, nPos, FALSE );
-
- switch( idBar )
- {
- case ITEM_DISTBAR:
- nDistance = nPos;
- break;
-
- case ITEM_INTBAR:
- KillTimer( hWndWhat, TIMER_MOVE );
- nInterval = nPos;
- SetTimer( hWndWhat, TIMER_MOVE, nInterval, NULL );
- InvalidateRect( hWndWhat, NULL, FALSE );
- break;
- }
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Terminates the application, freeing up allocated resources.
- * Note that this function does NOT return to the caller, but
- * exits the program.
- */
-
- void SayExitApp( nRet )
- int nRet;
- {
- if( GetModuleUsage(hInstance) == 1 ) {
- DeleteObject( hbrBkgd );
- }
-
- exit( nRet );
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Fills a specified rectangle with the background color.
- * Checks that the rectangle is non-empty first.
- */
-
- void SayFillRect( hDC, nLeft, nTop, nRight, nBottom )
- HDC hDC;
- int nLeft;
- int nTop;
- int nRight;
- int nBottom;
-
- {
- RECT rcFill;
-
- if( nLeft >= nRight || nTop >= nBottom )
- return;
-
- SetRect( &rcFill, nLeft, nTop, nRight, nBottom );
-
- FillRect( hDC, &rcFill, hbrBkgd );
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Initializes the application. */
-
- BOOL SayInitApp( hPrevInstance, nCmdShow )
- HANDLE hPrevInstance;
- int nCmdShow;
- {
- WNDCLASS Class;
- HDC hDC;
- TEXTMETRIC Metrics;
-
- LoadString(
- hInstance, STR_NAME, szAppName, sizeof(szAppName)
- );
- LoadString(
- hInstance, STR_TITLE, szTitle, sizeof(szTitle)
- );
- LoadString(
- hInstance, STR_WHAT, szText, sizeof(szText)
- );
-
- hDC = CreateIC( "DISPLAY", NULL, NULL, NULL );
- GetTextMetrics( hDC, &Metrics );
- nDisplayPlanes = GetDeviceCaps( hDC, PLANES );
- DeleteDC( hDC );
-
- ptCharSize.x = Metrics.tmMaxCharWidth;
- ptCharSize.y = Metrics.tmHeight;
-
- ptScreenSize.x = GetSystemMetrics(SM_CXSCREEN);
- ptScreenSize.y = GetSystemMetrics(SM_CYSCREEN);
-
- if( ! hPrevInstance ) {
-
- hbrBkgd = CreateSolidBrush( GetSysColor(COLOR_WINDOW) );
-
- Class.style = 0; /* CS_HREDRAW | CS_VREDRAW; */
- Class.lpfnWndProc = SayWhatWndProc;
- Class.cbClsExtra = 0;
- Class.cbWndExtra = 0;
- Class.hInstance = hInstance;
- Class.hIcon = NULL;
- Class.hCursor = LoadCursor( NULL, IDC_ARROW );
- Class.hbrBackground = COLOR_WINDOW + 1;
- Class.lpszMenuName = szAppName;
- Class.lpszClassName = szAppName;
-
- if( ! RegisterClass( &Class ) )
- return FALSE;
-
- } else {
-
- GetInstanceData(
- hPrevInstance, (NPSTR)&hbrBkgd, sizeof(hbrBkgd)
- );
- }
-
- hWndWhat = CreateWindow(
- szAppName,
- szTitle,
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, 0,
- CW_USEDEFAULT, 0,
- (HWND)NULL,
- (HMENU)NULL,
- hInstance,
- (LPSTR)NULL
- );
-
- if( ! hWndWhat )
- return FALSE;
-
- ShowWindow( hWndWhat, nCmdShow );
- UpdateWindow( hWndWhat );
-
- return TRUE;
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Initializes one scroll bar in the control dialog. */
-
- void SayInitBar( hWndDlg, idBar, nValue, nMin, nMax )
- HWND hWndDlg;
- int idBar;
- int nValue;
- int nMin;
- int nMax;
- {
- HWND hWndBar;
-
- hWndBar = GetDlgItem( hWndDlg, idBar );
-
- SetScrollRange( hWndBar, SB_CTL, nMin, nMax, FALSE );
- SetScrollPos( hWndBar, SB_CTL, nValue, FALSE );
-
- SetDlgItemInt( hWndDlg, idBar+1, nValue, FALSE );
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Invalidates the text within the main window, adjusting the
- * text rectangle if it's gone out of bounds.
- */
-
- void SayInvalidateText( hWnd )
- HWND hWnd;
- {
- SayLimitTextPos( hWnd );
- InvalidateRect( hWnd, &rcText, FALSE );
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Checks the text position against the window client area
- * rectangle. If it's moved off the window in any direction,
- * forces it back inside, and also reverses the ptAdvance value
- * for that direction so it will "bounce" off the edge. Handles
- * both the iconic and open window cases.
- */
-
- void SayLimitTextPos( hWnd )
- HWND hWnd;
- {
- RECT rcClient;
- POINT ptTextSize;
-
- ptTextSize = ptCharSize;
-
- if( ! bIconic ) {
- pText = szText;
- ptTextSize.x *= strlen(szText);
- }
-
- GetClientRect( hWndWhat, &rcClient );
-
- if( rcText.left > rcClient.right - ptTextSize.x ) {
- rcText.left = rcClient.right - ptTextSize.x;
- ptAdvance.x = -ptAdvance.x;
- }
-
- if( rcText.left < rcClient.left ) {
- rcText.left = rcClient.left;
- ptAdvance.x = -ptAdvance.x;
- }
-
- if( rcText.top > rcClient.bottom - ptTextSize.y ) {
- rcText.top = rcClient.bottom - ptTextSize.y;
- ptAdvance.y = -ptAdvance.y;
- }
-
- if( rcText.top < rcClient.top ) {
- rcText.top = rcClient.top;
- ptAdvance.y = -ptAdvance.y;
- }
-
- rcText.right = rcText.left + ptTextSize.x;
- rcText.bottom = rcText.top + ptTextSize.y;
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Moves the text within the window, by invalidating the old
- * position, adjusting rcText according to ptMove, and then
- * invalidating the new position.
- */
-
- void SayMoveText( hWnd, ptMove )
- HWND hWnd;
- POINT ptMove;
- {
- SayInvalidateText( hWnd );
- rcText.left = ptMove.x - (rcText.right - rcText.left >> 1);
- rcText.top = ptMove.y - (rcText.bottom - rcText.top >> 1);
- SayInvalidateText( hWnd );
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Sets one of the dialog scroll bars to *pnValue. If that value
- * is out of range, limits it to the proper range and forces
- * *pnValue to be within the range as well.
- */
-
- void SaySetBar( hWndDlg, pnValue, idBar )
- HWND hWndDlg;
- int * pnValue;
- int idBar;
- {
- HWND hWndBar;
- int nMin;
- int nMax;
- int nValue;
- BOOL bOK;
-
- hWndBar = GetDlgItem( hWndDlg, idBar );
-
- GetScrollRange( hWndBar, SB_CTL, &nMin, &nMax );
-
- nValue = GetDlgItemInt( hWndDlg, idBar+1, &bOK, FALSE );
-
- if( bOK && nValue >= nMin && nValue <= nMax ) {
- *pnValue = nValue;
- SetScrollPos( hWndBar, SB_CTL, nValue, TRUE );
- } else {
- SetDlgItemInt(
- hWndDlg,
- idBar+1,
- GetScrollPos( hWndBar, SB_CTL ),
- FALSE
- );
- }
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Dialog function for the control panel dialog box. */
-
- BOOL FAR PASCAL SayWhatDlgProc( hWndDlg, wMsg, wParam, lParam )
- HWND hWndDlg;
- unsigned wMsg;
- WORD wParam;
- LONG lParam;
- {
- HWND hWndBar;
- RECT rcWin;
- int n;
-
- switch( wMsg )
- {
- case WM_COMMAND:
- switch( wParam )
- {
- case IDOK:
- KillTimer( hWndWhat, TIMER_MOVE );
- GetDlgItemText(
- hWndDlg, ITEM_WHAT, szText, sizeof(szText)
- );
- if( strlen(szText) == 0 )
- LoadString(
- hInstance, STR_WHAT, szText, sizeof(szText)
- );
- pText = szText;
- SaySetBar( hWndDlg, &nInterval, ITEM_INTBAR );
- SaySetBar( hWndDlg, &nDistance, ITEM_DISTBAR );
- SetTimer( hWndWhat, TIMER_MOVE, nInterval, NULL );
- InvalidateRect( hWndWhat, NULL, FALSE );
- return TRUE;
-
- case IDCANCEL:
- DestroyWindow( hWndDlg );
- return TRUE;
-
- case ITEM_CLEAN:
- case ITEM_FLICKER:
- bCleanPaint =
- IsDlgButtonChecked( hWndDlg, ITEM_CLEAN );
- return TRUE;
- }
- return FALSE;
-
- case WM_HSCROLL:
- if( HIWORD(lParam) )
- SayDoBarMsg(
- hWndDlg, HIWORD(lParam), wParam, LOWORD(lParam)
- );
- return TRUE;
-
- case WM_INITDIALOG:
- GetWindowRect( hWndDlg, &rcWin );
- ClientToScreen( hWndWhat, (LPPOINT)&rcWin.left );
- ClientToScreen( hWndWhat, (LPPOINT)&rcWin.right );
- n = rcWin.right - ptScreenSize.x + ptCharSize.x;
- if( n > 0 )
- rcWin.left -= n;
- rcWin.left &= ~7; /* byte align */
- n = rcWin.bottom - ptScreenSize.y + ptCharSize.y;
- if( n > 0 )
- rcWin.top -= n;
- SetWindowPos(
- hWndDlg,
- (HWND)NULL,
- rcWin.left,
- rcWin.top,
- 0, 0,
- SWP_NOSIZE | SWP_NOZORDER |
- SWP_NOREDRAW | SWP_NOACTIVATE
- );
- SetDlgItemText( hWndDlg, ITEM_WHAT, szText );
- SendDlgItemMessage(
- hWndDlg, ITEM_WHAT,
- EM_LIMITTEXT, sizeof(szText)-1, 0L
- );
- SayInitBar(
- hWndDlg, ITEM_INTBAR,
- nInterval, MIN_INTERVAL, MAX_INTERVAL
- );
- SayInitBar(
- hWndDlg, ITEM_DISTBAR,
- nDistance, MIN_DISTANCE, MAX_DISTANCE
- );
- CheckDlgButton( hWndDlg, ITEM_CLEAN, TRUE );
- return TRUE;
-
- case WM_NCDESTROY:
- FreeProcInstance( lpfnDlgProc );
- hWndPanel = NULL;
- return FALSE;
- }
- return FALSE;
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Painting procedure for the main window. Handles both the
- * clean and flickery painting methods for demonstration
- * purposes.
- */
-
- void SayWhatPaint( hWnd )
- HWND hWnd;
- {
- PAINTSTRUCT ps;
-
- BeginPaint( hWnd, &ps );
-
- SetTextColor( ps.hdc, rgbTextColor );
-
- SayLimitTextPos( hWnd );
-
- if( bCleanPaint ) {
-
- /* Clean painting, avoid redundant erasing */
-
- TextOut(
- ps.hdc,
- rcText.left,
- rcText.top,
- pText,
- bIconic ? 1 : strlen(szText)
- );
-
- SayFillRect(
- ps.hdc,
- ps.rcPaint.left,
- ps.rcPaint.top,
- rcText.left,
- ps.rcPaint.bottom
- );
-
- SayFillRect(
- ps.hdc,
- rcText.left,
- ps.rcPaint.top,
- rcText.right,
- rcText.top
- );
-
- SayFillRect(
- ps.hdc,
- rcText.left,
- rcText.bottom,
- rcText.right,
- ps.rcPaint.bottom
- );
-
- SayFillRect(
- ps.hdc,
- rcText.right,
- ps.rcPaint.top,
- ps.rcPaint.right,
- ps.rcPaint.bottom
- );
-
- } else {
-
- /* Flickery painting, erase background and
- paint traditionally */
-
- FillRect( ps.hdc, &ps.rcPaint, hbrBkgd );
-
- TextOut(
- ps.hdc,
- rcText.left,
- rcText.top,
- pText,
- bIconic ? 1 : strlen(szText)
- );
-
- }
-
- EndPaint( hWnd, &ps );
-
- if( ! nInterval )
- SayAdvanceTextPos( hWnd );
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Window function for the main window. */
-
- LONG FAR PASCAL SayWhatWndProc( hWnd, wMsg, wParam, lParam )
- HWND hWnd;
- unsigned wMsg;
- WORD wParam;
- LONG lParam;
- {
- FARPROC lpfnAbout;
-
- switch( wMsg )
- {
- case WM_COMMAND:
- switch( wParam )
- {
- case CMD_ABOUT:
- lpfnAbout =
- MakeProcInstance( SayAboutDlgProc, hInstance );
- DialogBox(
- hInstance, MAKEINTRESOURCE(DLG_ABOUT),
- hWnd, lpfnAbout
- );
- FreeProcInstance( lpfnAbout );
- return 0L;
-
- case CMD_EXIT:
- DestroyWindow( hWndWhat );
- return 0L;
-
- case CMD_WHAT:
- if( hWndPanel ) {
- BringWindowToTop( hWndPanel );
- } else {
- lpfnDlgProc =
- MakeProcInstance( SayWhatDlgProc, hInstance );
- if( ! lpfnDlgProc )
- return 0L;
- hWndPanel = CreateDialog(
- hInstance,
- MAKEINTRESOURCE(DLG_WHAT),
- (HWND)NULL,
- lpfnDlgProc
- );
- if( ! hWndPanel )
- FreeProcInstance( lpfnDlgProc );
- }
- }
- break;
-
- case WM_CREATE:
- srand( (int)time(NULL) );
- SetTimer( hWnd, TIMER_MOVE, nInterval, NULL );
- return 0L;
-
- case WM_DESTROY:
- if( hWndPanel )
- DestroyWindow( hWndPanel );
- PostQuitMessage( 0 );
- return 0L;
-
- case WM_KEYDOWN:
- SayInvalidateText( hWnd );
- switch( wParam )
- {
- case VK_LEFT:
- rcText.left -= ptCharSize.x;
- ptAdvance.x = -1;
- ptAdvance.y = 0;
- break;
-
- case VK_RIGHT:
- rcText.left += ptCharSize.x;
- ptAdvance.x = 1;
- ptAdvance.y = 0;
- break;
-
- case VK_UP:
- rcText.top -= ptCharSize.y >> 1;
- ptAdvance.x = 0;
- ptAdvance.y = -1;
- break;
-
- case VK_DOWN:
- rcText.top += ptCharSize.y >> 1;
- ptAdvance.x = 0;
- ptAdvance.y = 1;
- break;
-
- default:
- return 0L;
- }
- SayInvalidateText( hWnd );
- nDistLeft = nDistance;
- return 0L;
-
- case WM_LBUTTONDOWN:
- if( bMouseDown )
- break;
- KillTimer( hWnd, TIMER_MOVE );
- bMouseDown = TRUE;
- SetCapture( hWnd );
- SayMoveText( hWnd, MAKEPOINT(lParam) );
- break;
-
- case WM_LBUTTONUP:
- if( ! bMouseDown )
- break;
- bMouseDown = FALSE;
- ReleaseCapture();
- SayMoveText( hWnd, MAKEPOINT(lParam) );
- SetTimer( hWnd, TIMER_MOVE, nInterval, NULL );
- break;
-
- case WM_MOUSEMOVE:
- if( bMouseDown )
- SayMoveText( hWnd, MAKEPOINT(lParam) );
- break;
-
- case WM_PAINT:
- SayWhatPaint( hWnd );
- return 0L;
-
- case WM_SIZE:
- if( wParam == SIZEICONIC ) {
- if( ! bIconic )
- SetTimer( hWnd, TIMER_CHAR, 1000, NULL );
- bIconic = TRUE;
- } else {
- if( bIconic )
- KillTimer( hWnd, TIMER_CHAR );
- bIconic = FALSE;
- }
- SayInvalidateText( hWnd );
- nDistLeft = 0;
- SayAdvanceTextPos( hWnd );
- return 0L;
-
- case WM_TIMER:
- switch( wParam )
- {
- case TIMER_MOVE:
- SayAdvanceTextPos( hWnd );
- break;
-
- case TIMER_CHAR:
- SayAdvanceTextChar( hWnd );
- break;
- }
- return 0L;
- }
- return DefWindowProc( hWnd, wMsg, wParam, lParam );
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Main function for the application. */
-
- void PASCAL WinMain( hInst, hPrevInst, lpszCmdLine, nCmdShow )
- HANDLE hInst;
- HANDLE hPrevInst;
- LPSTR lpszCmdLine;
- int nCmdShow;
- {
- MSG msg;
-
- hInstance = hInst;
-
- if( ! SayInitApp( hPrevInst, nCmdShow ) )
- SayExitApp( 1 );
-
- while( GetMessage( &msg, NULL, 0, 0 ) ) {
-
- if( hWndPanel && IsDialogMessage( hWndPanel, &msg ) )
- continue;
-
- TranslateMessage( &msg );
- DispatchMessage( &msg );
- }
-
-
- SayExitApp( msg.wParam );
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-
- Figure 1pm
- =========
-
-
- # MAKE file for SAYWHAT (Presentation Manager version)
-
- swp.obj: swp.c swp.h
- cl -c -AS -DLINT_ARGS -G2csw -Oat -W3 -Zp swp.c
-
- swp.res: swp.rc swp.h
- rc -r swp.rc
-
- saywhatp.exe: swp.obj swp.res swp.def
- link @swp.lnk
- mapsym saywhat
- rc swp.res saywhat.exe
-
-
-
- Figure 2pm
- =========
-
-
- swp
- saywhatp/align:16
- saywhatp/map/co
- wincalls gpicalls doscalls slibc slibc5
- swp.def
-
-
-
- Figure 3pm
- =========
-
-
- ; SWP.DEF - Module definition file for SAYWHAT (PM version)
-
- NAME SayWhat
-
- DESCRIPTION 'Say What!'
-
- STUB 'OS2STUB.EXE'
-
- CODE MOVEABLE
- DATA MOVEABLE MULTIPLE
-
- HEAPSIZE 128
- STACKSIZE 8192
-
- EXPORTS
- SayAboutDlgProc @1
- SayWhatDlgProc @2
- SayWhatWndProc @3
-
-
-
- Figure 4pm
- =========
-
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *\
- * SWP.RC - Resource file for SayWhat - PM version *
- \* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- #include <os2pm.h>
- #include "swp.h"
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- STRINGTABLE
- {
- STR_NAME, "SayWhat!"
- STR_TITLE, "Say What!"
- STR_WHAT, "Hello Windows!"
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- MENU SayWhat!
- {
- SUBMENU "~Say", -1
- {
- MENUITEM "~What...", CMD_WHAT
- MENUITEM SEPARATOR
- MENUITEM "E~xit", CMD_EXIT
- MENUITEM SEPARATOR
- MENUITEM "A~bout SayWhat!...", CMD_ABOUT
- }
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- DLGTEMPLATE DLG_ABOUT
- {
- DIALOG "", DLG_ABOUT, 19, 17, 130, 83, FS_DLGBORDER | WS_SAVEBITS | WS_VISIBLE
- {
- CTEXT "Microsoft Windows", -1, 0, 67, 127, 8
- CTEXT "Say What!", -1, 0, 57, 127, 8
- CTEXT "Version 1.00", -1, 0, 45, 127, 8
- CTEXT "By Michael Geary", -1, 0, 31, 129, 8
- DEFPUSHBUTTON "Ok", IDOK, 48, 7, 32, 14
- }
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- DLGTEMPLATE DLG_WHAT
- {
- DIALOG "Say What!", DLG_WHAT, 49, 41, 177, 103, FS_TITLEBAR | FS_SYSMENU | FS_BORDER | WS_VISIBLE
- {
- CONTROL "Say ~What:" -1, 8, 85, 40, 8, WC_STATIC, SS_LEFT | WS_GROUP
- CONTROL "" ITEM_WHAT, 56, 83, 112, 12, WC_EDIT, ES_LEFT | ES_AUTOSCROLL | ES_MARGIN | WS_TABSTOP
- CONTROL "~Time Delay:" -1, 8, 66, 53, 9, WC_STATIC, SS_LEFT
- CONTROL "" ITEM_INTBAR, 56, 67, 88, 8, WC_SCROLLBAR, SBS_HORZ | WS_TABSTOP
- CONTROL "" ITEM_INTERVAL, 152, 65, 16, 12, WC_EDIT, ES_LEFT | ES_MARGIN | WS_TABSTOP
- CONTROL "~Stability:" -1, 8, 48, 56, 9, WC_STATIC, SS_LEFT
- CONTROL "" ITEM_DISTBAR, 56, 49, 88, 8, WC_SCROLLBAR, SBS_HORZ | WS_TABSTOP
- CONTROL "" ITEM_DISTANCE, 152, 47, 16, 12, WC_EDIT, ES_LEFT | ES_MARGIN | WS_TABSTOP
- CONTROL "Painting:" -1, 8, 31, 40, 8, WC_STATIC, SS_LEFT
- CONTROL "~Clean" ITEM_CLEAN, 56, 29, 36, 12, WC_BUTTON, BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP
- CONTROL "~Flicker" ITEM_FLICKER, 96, 29, 42, 12, WC_BUTTON, BS_AUTORADIOBUTTON
- CONTROL "Enter" IDOK, 24, 7, 48, 14, WC_BUTTON, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
- CONTROL "Esc=Close" IDCANCEL, 104, 7, 48, 14, WC_BUTTON, BS_PUSHBUTTON | WS_TABSTOP
- }
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
-
- Figure 5pm
- =========
-
-
- /* SWP.H - C header file for SAYWHAT (PM version) */
-
- /* String table constants */
-
- #define STR_NAME 101
- #define STR_TITLE 102
- #define STR_WHAT 103
-
- /* Menu command IDs */
-
- #define CMD_ABOUT 201
- #define CMD_EXIT 202
- #define CMD_WHAT 203
-
- /* Dialog box resource IDs */
-
- #define DLG_ABOUT 301
- #define DLG_WHAT 302
-
- /* 'What...' dialog box item IDs */
-
- #define ITEM_WHAT 401
- #define ITEM_INTBAR 402
- #define ITEM_INTERVAL 403
- #define ITEM_DISTBAR 404
- #define ITEM_DISTANCE 405
- #define ITEM_CLEAN 406
- #define ITEM_FLICKER 407
-
- /* Timer IDs */
-
- #define TIMER_MOVE 501
- #define TIMER_CHAR 502
-
- /* Menu resource IDs */
-
- #define MENU_WHAT 601
-
-
- Figure 6pm
- =========
-
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *\
- * SWP.C - C code for SayWhat - Presentation Manager version *
- \* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- #ifndef LINT_ARGS
- #define LINT_ARGS /* turn on argument checking for C runtime */
- #endif
-
- #include <os2pm.h>
- #include <limits.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include "swp.h"
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- #define MIN_INTERVAL 1 /* limits for nInterval */
- #define MAX_INTERVAL 999
-
- #define MIN_DISTANCE 1 /* limits for nDistance */
- #define MAX_DISTANCE 99
-
- #define COLORDATAMAX 5
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Static variables */
-
- HAB hAB = NULL; /* anchor block handle */
- HMQ hMsgQ = NULL; /* message queue handle */
-
- HWND hWndWhatFrame; /* frame window handle */
- HWND hWndWhat; /* client window handle */
- HWND hWndPanel; /* control panel dialog handle */
-
- CHAR szAppName[10]; /* window class name */
- CHAR szTitle[15]; /* main window title */
-
- CHAR szText[40]; /* current "what" text */
- PSZ npszText = szText; /* ptr into szText for icon mode */
- CHAR cBlank = ' '; /* a blank we can point to */
-
- RECT rcText; /* current text rectangle */
- POINT ptAdvance; /* increments for SayAdvanceText */
- POINT ptCharSize; /* X and Y size of a character */
- POINT ptScreenSize; /* X and Y size of the screen */
-
- LONG lColorMax; /* number of available colors */
- LONG lColor; /* current text color index */
-
- SHORT nInterval = 40; /* current "Interval" setting */
- SHORT nDistance = 30; /* current "Distance" setting */
- SHORT nDistLeft = 0; /* change direction when hits 0 */
- BOOL bCleanPaint = TRUE; /* clean or flickery painting? */
- BOOL bMouseDown = FALSE; /* is mouse down? */
- BOOL bIconic = FALSE; /* is main window iconic? */
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Full prototypes for our functions to get type checking */
-
- ULONG FAR PASCAL SayAboutDlgProc( HWND, USHORT, ULONG, ULONG );
- VOID SayAdvanceTextChar( HWND );
- VOID SayAdvanceTextPos( HWND );
- VOID SayChangeColor( HWND );
- VOID SayDoBarMsg( HWND, USHORT, USHORT, SHORT );
- VOID SayExitApp( INT );
- VOID SayFillRect( HPS, SHORT, SHORT, SHORT, SHORT );
- VOID SayInitBar( HWND, SHORT, SHORT, SHORT, SHORT );
- BOOL SayInitApp( VOID );
- VOID SayInvalidateText( HWND );
- VOID SayLimitTextPos( HWND );
- VOID SayMoveText( HWND, POINT );
- VOID SaySetBar( HWND, SHORT *, SHORT );
- ULONG FAR PASCAL SayWhatDlgProc( HWND, USHORT, ULONG, ULONG );
- VOID SayWhatPaint( HWND );
- ULONG FAR PASCAL SayWhatWndProc( HWND, USHORT, ULONG, ULONG );
- void cdecl main( INT, PSZ );
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Dialog function for the "About" box */
-
- ULONG FAR PASCAL SayAboutDlgProc( hWndDlg, wMsg, lParam1, lParam2 )
- HWND hWndDlg;
- USHORT wMsg;
- ULONG lParam1;
- ULONG lParam2;
- {
- switch( wMsg )
- {
- case WM_COMMAND:
- switch( LOUSHORT(lParam1) )
- {
- case IDOK:
- WinDismissDlg( hWndDlg, TRUE );
- break;
- }
- }
- return WinDefDlgProc( hWndDlg, wMsg, lParam1, lParam2 );
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Advances to next display character in iconic mode.
- * Forces in a blank when it reaches the end of string.
- */
-
- VOID SayAdvanceTextChar( hWnd )
- HWND hWnd;
- {
- if( ! bIconic )
- return;
-
- if( npszText == &cBlank )
- npszText = szText;
- else if( ! *(++npszText) )
- npszText = &cBlank;
-
- SayChangeColor( hWnd );
- SayInvalidateText( hWnd );
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Advances text position according to ptAdvance. Decrements
- * nDistLeft first, and when it reaches zero, sets a new
- * randomized ptAdvance and nDistLeft, also changes color.
- * Does nothing if mouse is down, so text will track mouse.
- */
-
- VOID SayAdvanceTextPos( hWnd )
- HWND hWnd;
- {
- SHORT i;
-
- if( bMouseDown )
- return;
-
- SayInvalidateText( hWnd );
-
- if( nDistLeft-- < 0 ) {
- nDistLeft = rand() % nDistance + 1;
- do {
- i = rand();
- ptAdvance.x = (
- i < SHRT_MAX/3 ? -1
- : i < SHRT_MAX/3*2 ? 0
- : 1
- );
- i = rand();
- ptAdvance.y = (
- i < SHRT_MAX/3 ? -1
- : i < SHRT_MAX/3*2 ? 0
- : 1
- );
- } while( ptAdvance.x == 0 && ptAdvance.y == 0 );
- if( ! bIconic )
- SayChangeColor( hWnd );
- } else {
- rcText.xLeft += ptAdvance.x;
- rcText.xRight += ptAdvance.x;
- rcText.yTop += ptAdvance.y;
- rcText.yBottom += ptAdvance.y;
- }
-
- SayInvalidateText( hWnd );
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Changes color to a random selection, if color is available.
- * Forces a color change - if the random selection is the same
- * as the old one, it tries again.
- */
-
- VOID SayChangeColor( hWnd )
- HWND hWnd;
- {
- HPS hPS;
- LONG lWindow;
- LONG lNew;
-
- hPS = WinGetPS( hWnd );
-
- if( lColorMax <= 2 ) {
- lColor = GpiQueryColorIndex(
- hPS,
- WinQuerySysColor( hAB, SCLR_WINDOWTEXT ),
- 0L
- );
- } else {
- lWindow = GpiQueryColorIndex(
- hPS,
- WinQuerySysColor( hAB, SCLR_WINDOW ),
- 0L
- );
- do {
- lNew = rand() % lColorMax;
- } while( lNew == lWindow || lNew == lColor );
- lColor = lNew;
- }
-
- WinReleasePS( hPS );
-
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Handles scroll bar messages from the control dialog box.
- * Adjusts scroll bar position, taking its limits into account,
- * copies the scroll bar value into the adjacent edit control,
- * then sets the nDistance or nInterval variable appropriately.
- */
-
- VOID SayDoBarMsg( hWndDlg, idBar, wCode, nThumb )
- HWND hWndDlg;
- USHORT idBar;
- USHORT wCode;
- SHORT nThumb;
- {
- SHORT nPos;
- SHORT nOldPos;
- ULONG lRange;
-
- nOldPos = nPos =
- (SHORT)WinSendDlgItemMsg(
- hWndDlg, idBar, SBM_QUERYPOS, 0L, 0L
- );
-
- lRange =
- WinSendDlgItemMsg(
- hWndDlg, idBar, SBM_QUERYRANGE, 0L, 0L
- );
-
- switch( wCode ) {
-
- case SB_LINEUP: --nPos; break;
-
- case SB_LINEDOWN: ++nPos; break;
-
- case SB_PAGEUP: nPos -= 10; break;
-
- case SB_PAGEDOWN: nPos += 10; break;
-
- case SB_THUMBPOSITION:
- case SB_THUMBTRACK: nPos = nThumb; break;
-
- case SB_TOP: nPos = LOUSHORT(lRange); break;
-
- case SB_BOTTOM: nPos = HIUSHORT(lRange); break;
-
- }
-
- if( nPos < LOUSHORT(lRange) )
- nPos = LOUSHORT(lRange);
-
- if( nPos > HIUSHORT(lRange) )
- nPos = HIUSHORT(lRange);
-
- if( nPos == nOldPos )
- return;
-
- WinSendDlgItemMsg(
- hWndDlg, idBar, SBM_SETPOS, (LONG)nPos, 0L
- );
-
- WinSetDlgItemShort( hWndDlg, idBar+1, nPos, FALSE );
-
- switch( idBar )
- {
- case ITEM_DISTBAR:
- nDistance = nPos;
- break;
-
- case ITEM_INTBAR:
- WinStopTimer( hAB, hWndWhat, TIMER_MOVE );
- nInterval = nPos;
- WinStartTimer( hAB, hWndWhat, TIMER_MOVE, nInterval );
- WinInvalidateRect( hWndWhat, NULL );
- break;
- }
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Terminates the application, freeing up allocated resources.
- * Note that this function does NOT return to the caller, but
- * exits the program.
- */
-
- VOID SayExitApp( nRet )
- INT nRet;
- {
- if( hWndWhatFrame )
- WinDestroyWindow( hWndWhatFrame );
-
- if( hMsgQ )
- WinDestroyMsgQueue( hMsgQ );
-
- if( hAB )
- WinTerminate( hAB );
-
- exit( nRet );
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Fills a specified rectangle with the background color.
- * Checks that the rectangle is non-empty first.
- */
-
- VOID SayFillRect( hPS, xLeft, xBottom, xRight, xTop )
- HPS hPS;
- SHORT xLeft;
- SHORT xBottom;
- SHORT xRight;
- SHORT xTop;
-
- {
- RECT rcFill;
-
- if( xLeft >= xRight || xBottom >= xTop )
- return;
-
- WinSetRect( hAB, &rcFill, xLeft, xBottom, xRight, xTop );
-
- WinFillRect(
- hPS,
- &rcFill,
- WinQuerySysColor( hAB, SCLR_WINDOW )
- );
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Initializes the application. */
-
- BOOL SayInitApp()
- {
- HPS hPS;
- BOOL bOK;
-
- hAB = WinInitialize();
- if( ! hAB )
- return FALSE;
-
- hMsgQ = WinCreateMsgQueue( hAB, 0 );
- if( ! hMsgQ )
- return FALSE;
-
- WinLoadString(
- hAB, NULL, STR_NAME, szAppName, sizeof(szAppName)
- );
- WinLoadString(
- hAB, NULL, STR_TITLE, szTitle, sizeof(szTitle)
- );
- WinLoadString(
- hAB, NULL, STR_WHAT, szText, sizeof(szText)
- );
-
- bOK = WinRegisterClass(
- hAB,
- szAppName,
- (LPFNWP)SayWhatWndProc,
- CS_SYNCPAINT,
- 0,
- NULL
- );
- if( ! bOK )
- return FALSE;
-
- hWndWhatFrame = WinCreateStdWindow(
- (HWND)NULL,
- FS_TITLEBAR | FS_SYSMENU |
- FS_MENU | FS_MINMAX | FS_SIZEBORDER,
- szAppName,
- szTitle,
- 0L,
- (HMODULE)NULL,
- MENU_WHAT,
- &hWndWhat
- );
-
- if( ! hWndWhatFrame )
- return FALSE;
-
- WinShowWindow( hWndWhat, TRUE );
-
- return TRUE;
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Initializes one scroll bar in the control dialog. */
-
- VOID SayInitBar( hWndDlg, idBar, nValue, nMin, nMax )
- HWND hWndDlg;
- SHORT idBar;
- SHORT nValue;
- SHORT nMin;
- SHORT nMax;
- {
- HWND hWndBar;
-
- hWndBar = WinWindowFromID( hWndDlg, idBar );
-
- WinSendDlgItemMsg(
- hWndDlg,
- idBar,
- SBM_SETSCROLLBAR,
- (LONG)nValue,
- MAKELONG( nMin, nMax )
- );
-
- WinSetDlgItemShort( hWndDlg, idBar+1, nValue, FALSE );
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Invalidates the text within the main window, adjusting the
- * text rectangle if it's gone out of bounds.
- */
-
- VOID SayInvalidateText( hWnd )
- HWND hWnd;
- {
- SayLimitTextPos( hWnd );
- WinInvalidateRect( hWnd, &rcText );
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Checks the text position against the window client area
- * rectangle. If it's moved off the window in any direction,
- * forces it back inside, and also reverses the ptAdvance value
- * for that direction so it will "bounce" off the edge. Handles
- * both the iconic and open window cases.
- */
-
- VOID SayLimitTextPos( hWnd )
- HWND hWnd;
- {
- RECT rcClient;
- POINT ptTextSize;
-
- ptTextSize = ptCharSize;
-
- if( ! bIconic ) {
- npszText = szText;
- ptTextSize.x *= strlen(szText);
- }
-
- WinQueryWindowRect( hWndWhat, &rcClient );
-
- if( rcText.xLeft > rcClient.xRight - ptTextSize.x ) {
- rcText.xLeft = rcClient.xRight - ptTextSize.x;
- ptAdvance.x = -ptAdvance.x;
- }
-
- if( rcText.xLeft < rcClient.xLeft ) {
- rcText.xLeft = rcClient.xLeft;
- ptAdvance.x = -ptAdvance.x;
- }
-
- if( rcText.yBottom < rcClient.yBottom ) {
- rcText.yBottom = rcClient.yBottom;
- ptAdvance.y = -ptAdvance.y;
- }
-
- if( rcText.yBottom > rcClient.yTop - ptTextSize.y ) {
- rcText.yBottom = rcClient.yTop - ptTextSize.y;
- ptAdvance.y = -ptAdvance.y;
- }
-
- rcText.xRight = rcText.xLeft + ptTextSize.x;
- rcText.yTop = rcText.yBottom + ptTextSize.y;
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Moves the text within the window, by invalidating the old
- * position, adjusting rcText according to ptMove, and then
- * invalidating the new position.
- */
-
- VOID SayMoveText( hWnd, ptMove )
- HWND hWnd;
- POINT ptMove;
- {
- SayInvalidateText( hWnd );
- rcText.xLeft =
- ptMove.x - (rcText.xRight - rcText.xLeft >> 1);
- rcText.yBottom =
- ptMove.y - (rcText.yTop - rcText.yBottom >> 1);
- SayInvalidateText( hWnd );
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Sets one of the dialog scroll bars to *pnValue. If that value
- * is out of range, limits it to the proper range and forces
- * *pnValue to be within the range as well.
- */
-
- VOID SaySetBar( hWndDlg, pnValue, idBar )
- HWND hWndDlg;
- SHORT * pnValue;
- SHORT idBar;
- {
- ULONG lRange;
- SHORT nValue;
- BOOL bOK;
-
- lRange =
- WinSendDlgItemMsg(
- hWndDlg, idBar, SBM_QUERYRANGE, 0L, 0L
- );
-
- nValue =
- WinQueryDlgItemShort( hWndDlg, idBar+1, &bOK, FALSE );
-
- if(
- bOK &&
- nValue >= LOUSHORT(lRange) &&
- nValue <= HIUSHORT(lRange)
- ) {
- *pnValue = nValue;
- WinSendDlgItemMsg(
- hWndDlg, idBar, SBM_SETPOS, (LONG)nValue, (LONG)TRUE
- );
- } else {
- WinSetDlgItemShort(
- hWndDlg,
- idBar + 1,
- (INT)WinSendDlgItemMsg(
- hWndDlg, idBar, SBM_QUERYPOS, 0L, 0L
- ),
- FALSE
- );
- }
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Dialog function for the control panel dialog box. */
-
- ULONG FAR PASCAL SayWhatDlgProc( hWndDlg, wMsg, lParam1, lParam2 )
- HWND hWndDlg;
- USHORT wMsg;
- ULONG lParam1;
- ULONG lParam2;
- {
- HWND hWndBar;
- RECT rcWin;
- SHORT n;
-
- switch( wMsg )
- {
- case WM_COMMAND:
- switch( LOUSHORT(lParam1) )
- {
- case IDOK:
- WinStopTimer( hAB, hWndWhat, TIMER_MOVE );
- WinQueryWindowText(
- WinWindowFromID( hWndDlg, ITEM_WHAT ),
- sizeof(szText),
- szText
- );
- if( strlen(szText) == 0 )
- WinLoadString(
- hAB, NULL, STR_WHAT, szText, sizeof(szText)
- );
- npszText = szText;
- SaySetBar( hWndDlg, &nInterval, ITEM_INTBAR );
- SaySetBar( hWndDlg, &nDistance, ITEM_DISTBAR );
- WinStartTimer( hAB, hWndWhat, TIMER_MOVE, nInterval );
- WinInvalidateRect( hWndWhat, NULL );
- break;
-
- case IDCANCEL:
- WinDestroyWindow( hWndDlg );
- break;
-
- case ITEM_CLEAN:
- case ITEM_FLICKER:
- bCleanPaint = (BOOL)WinSendDlgItemMsg(
- hWndDlg, ITEM_CLEAN,
- BM_QUERYCHECK, 0L, 0L
- );
- break;
- }
- break;
-
- case WM_DESTROY:
- hWndPanel = NULL;
- break;
-
- case WM_HSCROLL:
- SayDoBarMsg(
- hWndDlg, LOUSHORT(lParam1),
- HIUSHORT(lParam2), LOUSHORT(lParam2)
- );
- break;
-
- case WM_INITDLG:
- WinQueryWindowRect( hWndDlg, &rcWin );
- WinMapWindowPoints(
- hWndWhat, (HWND)NULL, (LPPOINT)&rcWin.xLeft, 2
- );
- n = rcWin.xRight - ptScreenSize.x + ptCharSize.x;
- if( n > 0 )
- rcWin.xLeft -= n;
- rcWin.xLeft &= ~7; /* byte align */
- n = rcWin.yTop - ptScreenSize.y + ptCharSize.y;
- if( n > 0 )
- rcWin.yBottom -= n;
- WinSetWindowPos(
- hWndDlg,
- (HWND)NULL,
- rcWin.xLeft,
- rcWin.yBottom,
- 0, 0,
- SWP_MOVE
- );
- WinSetWindowText(
- WinWindowFromID( hWndDlg, ITEM_WHAT ), szText
- );
- WinSendDlgItemMsg(
- hWndDlg, ITEM_WHAT, EM_SETTEXTLIMIT,
- (LONG)sizeof(szText)-1, 0L
- );
- SayInitBar(
- hWndDlg, ITEM_INTBAR, nInterval,
- MIN_INTERVAL, MAX_INTERVAL
- );
- SayInitBar(
- hWndDlg, ITEM_DISTBAR, nDistance,
- MIN_DISTANCE, MAX_DISTANCE
- );
- WinSendDlgItemMsg(
- hWndDlg, ITEM_CLEAN, BM_SETCHECK, (LONG)TRUE, 0L
- );
- break;
- }
- return WinDefDlgProc( hWndDlg, wMsg, lParam1, lParam2 );
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Painting procedure for the main window. Handles both the
- * clean and flickery painting methods for demonstration
- * purposes.
- */
-
- VOID SayWhatPaint( hWnd )
- HWND hWnd;
- {
- HPS hPS;
- RECT rcPaint;
- GPOINT gptText;
-
- hPS = WinBeginPaint( hWnd, (HPS)NULL, &rcPaint );
-
- GpiSetColor( hPS, lColor );
-
- SayLimitTextPos( hWnd );
-
- gptText.x = (LONG)rcText.xLeft;
- gptText.y = (LONG)rcText.yBottom;
-
- if( bCleanPaint ) {
-
- /* Clean painting, avoid redundant erasing */
-
- GpiSetBackMix( hPS, MIX_OVERPAINT );
-
- GpiCharStringAt(
- hPS,
- &gptText,
- (LONG)( bIconic ? 1 : strlen(szText) ),
- npszText
- );
-
- SayFillRect(
- hPS,
- rcPaint.xLeft,
- rcPaint.yBottom,
- rcText.xLeft,
- rcPaint.yTop
- );
-
- SayFillRect(
- hPS,
- rcText.xLeft,
- rcText.yTop,
- rcText.xRight,
- rcPaint.yTop
- );
-
- SayFillRect(
- hPS,
- rcText.xLeft,
- rcPaint.yBottom,
- rcText.xRight,
- rcText.yBottom
- );
-
- SayFillRect(
- hPS,
- rcText.xRight,
- rcPaint.yBottom,
- rcPaint.xRight,
- rcPaint.yTop
- );
-
- } else {
-
- /* Flickery painting, erase background and
- paint traditionally */
-
- WinFillRect(
- hPS,
- &rcPaint,
- WinQuerySysColor( hAB, SCLR_WINDOW )
- );
-
- GpiCharStringAt(
- hPS,
- &gptText,
- (LONG)( bIconic ? 1 : strlen(szText) ),
- npszText
- );
- }
-
- WinEndPaint( hPS );
-
- if( ! nInterval )
- SayInvalidateText( hWnd );
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Window function for the main window. */
-
- ULONG FAR PASCAL SayWhatWndProc( hWnd, wMsg, lParam1, lParam2 )
- HWND hWnd;
- USHORT wMsg;
- ULONG lParam1;
- ULONG lParam2;
- {
- POINT ptMouse;
- GSIZE gsChar;
- HPS hPS;
- LONG ColorData[COLORDATAMAX];
- BOOL bNowIconic;
-
- switch( wMsg )
- {
- case WM_BUTTON1DOWN:
- if( bMouseDown )
- break;
- WinStopTimer( hAB, hWnd, TIMER_MOVE );
- bMouseDown = TRUE;
- WinSetCapture( hAB, hWnd );
- ptMouse.x = LOUSHORT(lParam1);
- ptMouse.y = HIUSHORT(lParam1);
- SayMoveText( hWnd, ptMouse );
- return 0L;
-
- case WM_BUTTON1UP:
- if( ! bMouseDown )
- break;
- bMouseDown = FALSE;
- WinSetCapture( hAB, (HWND)NULL );
- ptMouse.x = LOUSHORT(lParam1);
- ptMouse.y = HIUSHORT(lParam1);
- SayMoveText( hWnd, ptMouse );
- WinStartTimer( hAB, hWnd, TIMER_MOVE, nInterval );
- return 0L;
-
- case WM_CHAR:
- if(
- ( LOUSHORT(lParam1) & KC_KEYUP ) ||
- ! ( LOUSHORT(lParam1) & KC_VIRTUALKEY )
- ) {
- break;
- }
- SayInvalidateText( hWnd );
- switch( HIUSHORT(lParam2) )
- {
- case VK_LEFT:
- rcText.xLeft -= ptCharSize.x;
- ptAdvance.x = -1;
- ptAdvance.y = 0;
- break;
- case VK_RIGHT:
- rcText.xLeft += ptCharSize.x;
- ptAdvance.x = 1;
- ptAdvance.y = 0;
- break;
- case VK_UP:
- rcText.yBottom -= ptCharSize.y >> 1;
- ptAdvance.x = 0;
- ptAdvance.y = -1;
- break;
- case VK_DOWN:
- rcText.yBottom += ptCharSize.y >> 1;
- ptAdvance.x = 0;
- ptAdvance.y = 1;
- break;
- default:
- return 0L;
- }
- SayInvalidateText( hWnd );
- nDistLeft = nDistance;
- return 0L;
-
- case WM_COMMAND:
- switch( LOUSHORT(lParam1) )
- {
- case CMD_ABOUT:
- WinDlgBox(
- (HWND)NULL, hWnd, (LPFNWP)SayAboutDlgProc,
- NULL, DLG_ABOUT, NULL
- );
- return 0L;
-
- case CMD_EXIT:
- WinDestroyWindow( hWndWhatFrame );
- return 0L;
-
- case CMD_WHAT:
- if( hWndPanel ) {
- WinSetWindowPos(
- hWndPanel,
- HWND_TOP,
- 0, 0, 0, 0,
- SWP_ZORDER | SWP_ACTIVATE
- );
- } else {
- hWndPanel = WinLoadDlg(
- (HWND)NULL,
- (HWND)NULL,
- (LPFNWP)SayWhatDlgProc,
- NULL,
- DLG_WHAT,
- NULL
- );
- }
- }
- return 0L;
-
- case WM_CREATE:
- /* find out character/screen sizes, number of colors */
- hPS = WinGetPS( hWnd );
- GpiQueryCharBox( hPS, &gsChar );
- GpiQueryColorData( hPS, (LONG)COLORDATAMAX, ColorData );
- WinReleasePS( hPS );
- lColorMax = ColorData[3];
- ptCharSize.x = gsChar.width;
- ptCharSize.y = gsChar.height;
- ptScreenSize.x =
- WinQuerySysValue( (HWND)NULL, SV_CXSCREEN );
- ptScreenSize.y =
- WinQuerySysValue( (HWND)NULL, SV_CYSCREEN );
- /* initialize timer */
- srand( (INT)time(NULL) );
- WinStartTimer( hAB, hWnd, TIMER_MOVE, nInterval );
- return 0L;
-
- case WM_DESTROY:
- if( hWndPanel )
- WinDestroyWindow( hWndPanel );
- WinPostQueueMsg( hMsgQ, WM_QUIT, 0L, 0L );
- return 0L;
-
- case WM_ERASEBACKGROUND:
- return 1L; /* don't erase */
-
- case WM_MINMAX:
- bNowIconic = ( LOUSHORT(lParam1) == SWP_MINIMIZE );
- if( bIconic != bNowIconic ) {
- bIconic = bNowIconic;
- if( bIconic )
- WinStopTimer( hAB, hWnd, TIMER_CHAR );
- else
- WinStartTimer( hAB, hWnd, TIMER_CHAR, 1000 );
- }
- return 1L;
-
- case WM_MOUSEMOVE:
- if( bMouseDown ) {
- ptMouse.x = LOUSHORT(lParam1);
- ptMouse.y = HIUSHORT(lParam1);
- SayMoveText( hWnd, ptMouse );
- }
- return 0L;
-
- case WM_PAINT:
- SayWhatPaint( hWnd );
- return 0L;
-
- case WM_SIZE:
- SayInvalidateText( hWnd );
- nDistLeft = 0;
- SayAdvanceTextPos( hWnd );
- return 0L;
-
- case WM_TIMER:
- switch( LOUSHORT(lParam1) ) {
- case TIMER_MOVE:
- SayAdvanceTextPos( hWnd );
- break;
- case TIMER_CHAR:
- SayAdvanceTextChar( hWnd );
- break;
- }
- return 0L;
- }
- return WinDefWindowProc( hWnd, wMsg, lParam1, lParam2 );
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-
- /* Main function for the application. */
-
- void cdecl main( nArgs, pArgs )
- INT nArgs;
- PSZ pArgs;
- {
- QMSG qMsg;
-
- if( ! SayInitApp() )
- SayExitApp( 1 );
-
- while( WinGetMsg( hAB, &qMsg, (HWND)NULL, 0, 0 ) ) {
-
- if( hWndPanel && WinProcessDlgMsg( hWndPanel, &qMsg ) )
- continue;
-
- WinDispatchMsg( hAB, &qMsg );
- }
-
- SayExitApp( 0 );
- }
-
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
-