|
|
1.1.1.2 ! root 1: /* wndproc.c -- Window handling routines ! 2: Created by Microsoft Corporation, 1989 ! 3: */ ! 4: #define INCL_GPI ! 5: #define INCL_WIN ! 6: #include <os2.h> ! 7: ! 8: #include "bio.h" ! 9: #include <time.h> ! 10: #include <stdio.h> ! 11: ! 12: /* Read-only global variables */ ! 13: extern HAB hAB; ! 14: extern HWND hwndApp; ! 15: extern HWND hwndAppFrame, hwndKidFrame; ! 16: extern char szAppName[]; ! 17: extern PFNWP OldFrameWndProc; ! 18: ! 19: /* Write-once Global variables */ ! 20: LONG Color[] = {CLR_RED, CLR_GREEN, CLR_BLUE}; ! 21: FONTMETRICS tmFontInfo; ! 22: SHORT cxLegendField; ! 23: SHORT cxDateField; ! 24: /* parameter used when creating a device context for a memory device */ ! 25: PSZ dcdatablk[9] = {(PSZ)0 ! 26: ,(PSZ)"DISPLAY" ! 27: ,(PSZ)0 ! 28: ,(PSZ)0 ! 29: ,(PSZ)0 ! 30: ,(PSZ)0 ! 31: ,(PSZ)0 ! 32: ,(PSZ)0 ! 33: ,(PSZ)0 ! 34: }; ! 35: ! 36: /* Read-Write global variables */ ! 37: double Born; ! 38: long Day, SelectDay; ! 39: BOOL bKid = TRUE; ! 40: BOOL bBorn = TRUE; ! 41: RECTL rclClient; ! 42: int LinesPerPage; ! 43: void BioGetDate(HWND); ! 44: 1.1 root 45: /* BioWndProc() - Parent WndProc message processing routine. 46: * 47: * Purpose: 48: * WndProc callback function to handle all messages for parent window. 49: * 50: * Arguments: 51: * hWnd - Handle of Window owning message 52: * message - Message itself 53: * mp1 - Extra message-dependent info 54: * mp2 - Extra message-dependent info 55: * 56: * Globals (modified): 1.1.1.2 ! root 57: * Born - Birthdate in julian days. Read from WIN.INI. ! 58: * SelectDay - Current day being tracked, day is highlighted. ! 59: * Value is days from birthdate. ! 60: * Initialized to current day in WM_CREATE processing. 1.1 root 61: * daylight - Defined by environment string TZ. If no such string, 62: * timezone default TZ=PST8PDT used. If daylight field is 63: * used, daylight time correction will occur. See 64: * documentation of tzset() C run-time function. 65: * Day - Day number from date born which is top line being 66: * displayed. Initially three days before SelectDay. 1.1.1.2 ! root 67: * bKid - Boolean indicating whether legend is visible. 1.1 root 68: * bBorn - Boolean indicating whether valid birtdate entered or 69: * defined in WIN.INI. Nothing graphed until valid. 1.1.1.2 ! root 70: * rclClient - Size of client area defined by WM_SIZE message 1.1 root 71: * LinesPerPage - Number of system font lines on client area, defined 72: * by WM_SIZE message handling 73: * Color[] - Set of colored pens used to identify cycles. 74: * tmFontInfo - Text Metric structure defined during WM_CREATE 75: * 76: * Globals (referenced): 77: * hAB - Handle to the Anchor Block 78: * hwndAppFrame - Window handle of parent window's frame 79: * hwndKidFrame - Handle to child window used for showing/moving legend. 1.1.1.2 ! root 80: * szAppName[] - RC file program name (Biorhythm). 1.1 root 81: * 82: * Description: 83: * Handle all messages for the parent window. 84: * 85: * Limits: 86: * N/A 87: * 88: */ 89: 90: 1.1.1.2 ! root 91: MRESULT CALLBACK BioWndProc( hWnd, message, mp1, mp2 ) 1.1 root 92: HWND hWnd; 93: USHORT message; 94: MPARAM mp1; 95: MPARAM mp2; 96: { 1.1.1.2 ! root 97: int iDay, i; ! 98: HPS hPS; ! 99: HPS hMemPS; 1.1 root 100: RECTL rc; 1.1.1.2 ! root 101: POINTL ptlTextBox[5]; ! 102: SIZEL pgsi; ! 103: HDC hdcMem; ! 104: HBITMAP hbm; ! 105: BITMAPINFOHEADER bmih; ! 106: POINTL ptlPoints[3]; 1.1 root 107: 108: switch( message ) 109: { 110: 111: case WM_CREATE: 1.1.1.2 ! root 112: BioGetDate(hWnd); 1.1 root 113: 1.1.1.2 ! root 114: /* Put date of the day three lines down on display */ 1.1 root 115: Day = SelectDay - 3; 1.1.1.2 ! root 116: 1.1 root 117: /* Initially set elevator */ 118: iDay = (int)(Day/365); 119: WinSendMsg( WinWindowFromID( WinQueryWindow(hWnd,QW_PARENT,FALSE), 120: FID_VERTSCROLL), 121: SBM_SETPOS, (MPARAM)MAKEULONG(iDay, 0), 0L ); 122: 123: /* Get System font text metrics */ 124: hPS = WinGetPS( hWnd ); 1.1.1.2 ! root 125: GpiQueryFontMetrics( hPS, (LONG)sizeof tmFontInfo, &tmFontInfo ); ! 126: /* Get sizes of long strings to be used as yard sticks for sizing ! 127: windows and objects. This is necessary because of new system ! 128: proportional fonts. */ ! 129: GpiQueryTextBox( hPS, 10L, "Emotional ", TXTBOX_COUNT, ptlTextBox ); ! 130: cxLegendField = (SHORT)ptlTextBox[TXTBOX_CONCAT].x; ! 131: GpiQueryTextBox( hPS, 10L, "W 99-99-99", TXTBOX_COUNT, ptlTextBox ); ! 132: cxDateField = (SHORT)ptlTextBox[TXTBOX_CONCAT].x; 1.1 root 133: WinReleasePS( hPS ); 134: break; 135: 136: case WM_CLOSE: 137: WinPostMsg( hWnd, WM_QUIT, 0L, 0L ); 138: break; 139: 140: case WM_COMMAND: 141: switch (LOUSHORT(mp1)) { 1.1.1.2 ! root 142: case IDM_DATES: 1.1 root 143: if (WinDlgBox( HWND_DESKTOP, hWnd, (PFNWP)BioDlg, NULL, IDD_DATE, NULL )) { 144: WinInvalidateRect( hWnd, NULL, FALSE ); 145: iDay = (int)(Day/365); 146: WinSendMsg( WinWindowFromID( hwndAppFrame, FID_VERTSCROLL), 147: SBM_SETPOS, (MPARAM)MAKEULONG(iDay, 0), 0L ); 148: } 149: break; 150: 1.1.1.2 ! root 151: case IDM_LEGEND: 1.1 root 152: if (bKid = !bKid) { 153: WinSendMsg( WinWindowFromID( hwndAppFrame, FID_MENU), 154: MM_SETITEMATTR, 1.1.1.2 ! root 155: (MPARAM)MAKEULONG( IDM_LEGEND, TRUE ), 1.1 root 156: (MPARAM)MAKEULONG( MIA_CHECKED, MIA_CHECKED) ); 157: WinShowWindow( hwndKidFrame, TRUE ); 158: } else { 159: WinSendMsg( WinWindowFromID( hwndAppFrame, FID_MENU), 160: MM_SETITEMATTR, 1.1.1.2 ! root 161: (MPARAM)MAKEULONG( IDM_LEGEND, TRUE ), 1.1 root 162: (MPARAM)MAKEULONG( MIA_CHECKED, 0) ); 163: WinShowWindow( hwndKidFrame, FALSE ); 164: } 165: break; 166: 1.1.1.2 ! root 167: case IDM_COPY: ! 168: /* Get access to clipboard. */ ! 169: WinOpenClipbrd( hAB ); ! 170: /* Wipe the slate clean. */ ! 171: WinEmptyClipbrd( hAB ); ! 172: ! 173: /* Bitmap header for bitmap the size of the window. */ ! 174: pgsi.cx = rclClient.xRight; ! 175: pgsi.cy = rclClient.yTop; ! 176: bmih.cbFix = 12; ! 177: bmih.cx = (USHORT)pgsi.cx; ! 178: bmih.cy = (USHORT)pgsi.cy; ! 179: bmih.cPlanes = 1; ! 180: bmih.cBitCount = 24; ! 181: ! 182: /* Get a memory dc. */ ! 183: hdcMem = DevOpenDC( hAB ! 184: , OD_MEMORY ! 185: , (PSZ)"*" ! 186: , 8L ! 187: , (PDEVOPENDATA)dcdatablk ! 188: , (HDC)NULL ! 189: ); ! 190: ! 191: /* Get a memory PS that will be used to manipulate image */ ! 192: hMemPS = GpiCreatePS( hAB ! 193: , hdcMem ! 194: , (PSIZEL)&pgsi ! 195: , (LONG)PU_PELS | GPIT_MICRO | GPIA_ASSOC ! 196: ); ! 197: ! 198: /* Create a bitmap to hold image */ ! 199: hbm = GpiCreateBitmap(hMemPS, &bmih, 0L, (PBYTE)NULL, (PBITMAPINFO)NULL); ! 200: /* Select bitmap into PS */ ! 201: GpiSetBitmap( hMemPS, hbm ); ! 202: /* BitBlt window client area into memory bitmap */ ! 203: ptlPoints[0].x = 0; ! 204: ptlPoints[0].y = 0; ! 205: ptlPoints[1].x = pgsi.cx; ! 206: ptlPoints[1].y = pgsi.cy; ! 207: ptlPoints[2].x = 0; ! 208: ptlPoints[2].y = 0; ! 209: hPS = WinGetPS( hWnd ); ! 210: GpiBitBlt(hMemPS, hPS, 3L, ptlPoints, ROP_SRCCOPY, BBO_OR); ! 211: WinReleasePS( hPS ); ! 212: ! 213: /* Put bitmap into the clipboard. */ ! 214: WinSetClipbrdData( hAB, (ULONG)hbm, CF_BITMAP, CFI_HANDLE ); ! 215: ! 216: /* Tidy up */ ! 217: WinCloseClipbrd( hAB ); ! 218: GpiSetBitmap( hMemPS, NULL ); ! 219: GpiDestroyPS( hMemPS ); ! 220: DevCloseDC( hdcMem ); 1.1 root 221: break; 222: 1.1.1.2 ! root 223: case IDM_ABOUT: 1.1 root 224: WinDlgBox( HWND_DESKTOP, hWnd, (PFNWP)About, NULL, 225: IDD_ABOUT, NULL ); 226: break; 227: 228: default: 229: break; 230: } 231: break; 232: 233: case WM_SIZE: 1.1.1.2 ! root 234: WinQueryWindowRect( hWnd, &rclClient ); ! 235: LinesPerPage = (int)(rclClient.yTop / tmFontInfo.lMaxBaselineExt); 1.1 root 236: WinSetWindowPos( hwndKidFrame, NULL, 10, 10, 0, 0, SWP_MOVE ); 237: break; 238: 239: case WM_CHAR: 1.1.1.2 ! root 240: /* Convert keyboard to scroll bar messages to support scrolling, ! 241: paging, etc. with keyboard interface. */ ! 242: if ( (ULONG)mp1 & KC_KEYUP ) ! 243: return WinDefWindowProc( hWnd, message, mp1, mp2 ); ! 244: switch (HIUSHORT( mp2 )) { ! 245: case VK_UP: ! 246: mp2 = (MPARAM)MAKEULONG( 0, SB_LINEUP ); ! 247: break; ! 248: case VK_DOWN: ! 249: mp2 = (MPARAM)MAKEULONG( 0, SB_LINEDOWN ); ! 250: break; ! 251: case VK_PAGEUP: ! 252: mp2 = (MPARAM)MAKEULONG( 0, SB_PAGEUP ); ! 253: break; ! 254: case VK_PAGEDOWN: ! 255: mp2 = (MPARAM)MAKEULONG( 0, SB_PAGEDOWN ); ! 256: break; ! 257: default: ! 258: return WinDefWindowProc( hWnd, message, mp1, mp2 ); ! 259: break; ! 260: } ! 261: return WinSendMsg( hWnd, WM_VSCROLL, mp1, mp2 ); 1.1 root 262: break; 263: 264: case WM_VSCROLL: 265: /* Don't allow any processing until valid birth date entered */ 266: if (!bBorn) break; 267: 268: /* Setup for scroll window - full width of client area is scrolled */ 1.1.1.2 ! root 269: WinCopyRect( hAB, &rc, &rclClient ); 1.1 root 270: switch (HIUSHORT(mp2)) { 271: case SB_LINEUP: 272: /* Update top day of display */ 273: Day--; 1.1.1.2 ! root 274: rc.yTop = rclClient.yTop - tmFontInfo.lMaxBaselineExt; ! 275: rc.yBottom = rclClient.yTop - (LinesPerPage-1) * tmFontInfo.lMaxBaselineExt + 1; 1.1 root 276: WinScrollWindow( hWnd, 0, (SHORT)-tmFontInfo.lMaxBaselineExt, &rc, 277: NULL, NULL, NULL, SW_INVALIDATERGN ); 278: break; 279: case SB_LINEDOWN: 280: /* Update top day of display */ 281: Day++; 1.1.1.2 ! root 282: rc.yTop = rclClient.yTop - 2*tmFontInfo.lMaxBaselineExt; ! 283: rc.yBottom = rclClient.yTop - (LinesPerPage) * tmFontInfo.lMaxBaselineExt + 1; 1.1 root 284: WinScrollWindow( hWnd, 0, (SHORT)tmFontInfo.lMaxBaselineExt, &rc, 285: NULL, NULL, NULL, SW_INVALIDATERGN ); 286: break; 287: case SB_PAGEUP: 288: Day -= (LinesPerPage-1); 289: break; 290: case SB_PAGEDOWN: 291: Day += (LinesPerPage-1); 292: break; 293: case SB_SLIDERPOSITION: 294: /* Set to birthday of each year because 100 year scale maps to 295: default 100 position scroll bar */ 296: Day = (long)(LOUSHORT(mp2) * 365.25); 297: break; 298: default: 299: return 0L; 300: } 301: /* Update scroll bar elevator */ 302: iDay = (int)(Day/365); 303: WinSendMsg( WinWindowFromID( hwndAppFrame, FID_VERTSCROLL), 304: SBM_SETPOS, (MPARAM)MAKEULONG(iDay, 0), 0L ); 305: /* All but LINEUP/DOWN need full repaint of client area */ 306: if ((HIUSHORT(mp2) != SB_LINEUP) && (HIUSHORT(mp2) != SB_LINEDOWN )) 307: WinInvalidateRect( hWnd, NULL, FALSE ); 308: WinUpdateWindow( hWnd ); 309: break; 310: 311: case WM_PAINT: 312: APPPaint( hWnd ); 1.1.1.2 ! root 313: break; 1.1 root 314: 315: case WM_BUTTON1DOWN: 1.1.1.2 ! root 316: /* Don't allow any processing until valid birthdate entered */ 1.1 root 317: if (!bBorn) break; 318: 319: /* Unhighlight previously selected line and highlight new line */ 1.1.1.2 ! root 320: WinCopyRect( hAB, &rc, &rclClient ); 1.1 root 321: hPS = WinGetPS( hWnd ); 322: for(i=0; i<2; i++) { 323: /* Make sure line is visible before (un)highlighting */ 324: if ((SelectDay >= Day) && (SelectDay - Day < LinesPerPage-1)) { 1.1.1.2 ! root 325: rc.yTop = rclClient.yTop - (int)(SelectDay - Day + 1) * tmFontInfo.lMaxBaselineExt; 1.1 root 326: rc.yBottom = rc.yTop - tmFontInfo.lMaxBaselineExt + 1; 327: WinInvertRect( hPS, &rc ); 328: } 329: /* New line to highlight */ 1.1.1.2 ! root 330: SelectDay = Day + (rclClient.yTop - HIUSHORT(mp1)) / 1.1 root 331: tmFontInfo.lMaxBaselineExt - 1; 332: } 333: WinReleasePS( hPS ); 334: break; 335: 336: /* Draw highlight on selected day */ 337: if ((SelectDay >= Day) && (SelectDay - Day < LinesPerPage - 1)) { 1.1.1.2 ! root 338: rc.xRight = rclClient.xRight; ! 339: rc.xLeft = rclClient.xLeft; 1.1 root 340: } 341: default: 342: return WinDefWindowProc( hWnd, message, mp1, mp2 ); 343: break; 344: } 345: return( 0L ); 346: } 347: 348: /* KidWndProc() - Child WndProc handling legend display. 349: * 350: * Purpose: 351: * WndProc callback function to handle all messages for legend child. 352: * 353: * Arguments: 354: * hWnd - Handle of Window owning message 355: * message - Message itself 356: * mp1 - Extra message-dependent info 357: * mp2 - Extra message-dependent info 358: * 359: * Globals (referenced): 360: * hwndApp - Window handle of parent window's client area 361: * tmFontInfo - Text Metric structure defined during WM_CREATE 362: * Color[] - Set of colored pens used to identify cycles. 363: * 364: * Description: 365: * Display legend information relating graph line styles to each 366: * cyle: physical, emotional and intellectual. Notifies parent 367: * to hide child if child window is instructed to close by user. 368: */ 369: 370: /* Read-only global variables */ 371: extern HWND hwndApp; 372: 1.1.1.2 ! root 373: MRESULT CALLBACK KidWndProc( hWnd, message, mp1, mp2 ) 1.1 root 374: HWND hWnd; 375: USHORT message; 376: MPARAM mp1; 377: MPARAM mp2; 378: { 379: HPS hPS; 380: RECTL rc; 381: POINTL ptl; 382: int i; 383: 384: switch( message ) 385: { 1.1.1.2 ! root 386: case WM_CHAR: ! 387: /* Convert keyboard to scroll bar messages to support scrolling, ! 388: paging, etc. with keyboard interface. */ ! 389: WinSendMsg( hwndApp, message, mp1, mp2 ); ! 390: break; ! 391: 1.1 root 392: case WM_PAINT: 393: hPS = WinBeginPaint( hWnd, NULL, NULL ); 394: 395: /* Erase client area */ 396: WinQueryWindowRect( hWnd, &rc ); 397: WinFillRect( hPS, &rc, CLR_PALEGRAY ); 398: 399: ptl.x = 0; 400: ptl.y = tmFontInfo.lMaxDescender; 1.1.1.2 ! root 401: GpiCharStringAt( hPS, &ptl, 8L, (PCH)"Physical" ); 1.1 root 402: ptl.y += tmFontInfo.lMaxBaselineExt; 403: GpiCharStringAt( hPS, &ptl, 9L, (PCH)"Emotional" ); 404: ptl.y += tmFontInfo.lMaxBaselineExt; 405: GpiCharStringAt( hPS, &ptl, 9L, (PCH)"Intellect" ); 406: 407: for (i=0; i<3; i++ ) { 408: GpiSetColor( hPS, Color[i] ); 1.1.1.2 ! root 409: ptl.x = cxLegendField; 1.1 root 410: ptl.y = i * tmFontInfo.lMaxBaselineExt + 411: tmFontInfo.lMaxBaselineExt/2; 412: GpiMove( hPS, &ptl ); 1.1.1.2 ! root 413: ptl.x = rc.xRight - tmFontInfo.lAveCharWidth; 1.1 root 414: GpiLine( hPS, &ptl ); 415: } 416: 417: WinEndPaint( hPS ); 418: break; 419: 1.1.1.2 ! root 420: case WM_BUTTON1UP: ! 421: /* Quick way to make Legend window disappear using mouse. */ ! 422: WinPostMsg( hwndApp, WM_COMMAND, (MPARAM)MAKEULONG(IDM_LEGEND, 0), 0L ); 1.1 root 423: break; 424: 1.1.1.2 ! root 425: case WM_TRANSLATEACCEL: ! 426: /* Change window handle. Child window's frame will block ! 427: ALT handling, so bypass frame. Return window handle ! 428: of main window's client area. Now the ALT key message ! 429: handling will be passed on up the chain of windows to ! 430: the main window's frame for proper ALT key message ! 431: handling. The main window's menu bar will highlight ! 432: even if the child window has the focus. */ ! 433: return WinDefWindowProc( hwndApp, message, mp1, mp2 ); ! 434: break; ! 435: 1.1 root 436: default: 437: return WinDefWindowProc( hWnd, message, mp1, mp2 ); 438: break; 439: } 440: return( 0L ); 441: } 1.1.1.2 ! root 442: /* ! 443: */ ! 444: ! 445: /* FrameWndProc() - Subclass routine for frame. ! 446: * ! 447: * Purpose: ! 448: * Handle WM_QUERYTRACKINFO message so that a minimum horizontal and ! 449: * vertical window size can be controlled. This minimum size keeps ! 450: * the tabulated data from overlapping and leaves at least 4 rows ! 451: * of data visible. ! 452: * ! 453: * Arguments: ! 454: * hWnd - Handle of Window owning message ! 455: * message - Message itself ! 456: * mp1 - Extra message-dependent info ! 457: * mp2 - Extra message-dependent info ! 458: * ! 459: * Globals (referenced): ! 460: * OldFrameWndProc - Original Frame Window procedure. ! 461: * ! 462: * Limits: ! 463: * N/A ! 464: * ! 465: */ ! 466: ! 467: MRESULT CALLBACK FrameWndProc( hWnd, message, mp1, mp2 ) ! 468: HWND hWnd; ! 469: USHORT message; ! 470: MPARAM mp1; ! 471: MPARAM mp2; ! 472: { ! 473: switch( message ) ! 474: { ! 475: case WM_QUERYTRACKINFO: ! 476: (*OldFrameWndProc)( hWnd, message, mp1, mp2 ); ! 477: /* Limit vertical and horizontal minimum size. Must take into ! 478: account menu, title, border and font widths and heights for ! 479: device independence. */ ! 480: ((PTRACKINFO)mp2)->ptlMinTrackSize.x = cxDateField * 2 + cxDateField/2; ! 481: ((PTRACKINFO)mp2)->ptlMinTrackSize.y = ! 482: tmFontInfo.lMaxBaselineExt * 5 + ! 483: WinQuerySysValue( HWND_DESKTOP, SV_CYMENU ) + ! 484: WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR ) + ! 485: WinQuerySysValue( HWND_DESKTOP, SV_CYSIZEBORDER ) * 2 + ! 486: WinQuerySysValue( HWND_DESKTOP, SV_CYBORDER ) * 2; ! 487: return TRUE; ! 488: break; ! 489: ! 490: default: ! 491: return (*OldFrameWndProc)( hWnd, message, mp1, mp2 ); ! 492: break; ! 493: } ! 494: return( 0L ); ! 495: } ! 496: ! 497: void BioGetDate(HWND hWnd) { ! 498: int year, month; ! 499: double day; ! 500: ! 501: /* Read in birth date from OS2.INI. Error value is 12-31-1899, ! 502: which is out of range for valid entries. */ ! 503: year = WinQueryProfileInt( hAB, szAppName, "Year", 1899 ); ! 504: month = WinQueryProfileInt( hAB, szAppName, "Month", 12 ); ! 505: day = (double)WinQueryProfileInt( hAB, szAppName, "Day", 31 ); ! 506: ! 507: /* Compute date of birth in julian days */ ! 508: Born = julian( year, month, day ); ! 509: ! 510: /* Get time zone environment information */ ! 511: tzset(); ! 512: /* ! 513: System clock starts 1-1-1970. Get julian date then and how many ! 514: days have elapsed since, so that number of days since birth date ! 515: can be determined ! 516: */ ! 517: SelectDay = (long)(julian( 1970, 1, 1.0 ) + ! 518: (double)((time(NULL) - timezone + (long)daylight*3600)/86400) - ! 519: Born ); ! 520: ! 521: /* If no valid OS2.INI info then automatically bring up dialog box */ ! 522: if (year < 1900) { ! 523: bBorn = FALSE; ! 524: WinPostMsg( hWnd, WM_COMMAND, (MPARAM)MAKEULONG(IDM_DATES, 0), 0L ); ! 525: } ! 526: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.