|
|
1.1 ! root 1: /*---------------------------------------------------------------- ! 2: SQBTN.C -- Contains window procedure for square 3D push button ! 3: ----------------------------------------------------------------*/ ! 4: ! 5: #define INCL_WIN ! 6: #define INCL_GPI ! 7: #include <os2.h> ! 8: #include <malloc.h> ! 9: #include <string.h> ! 10: ! 11: #define LCID_ITALIC 1L ! 12: ! 13: /*-------------------------------------------------- ! 14: Structure for storing data unique to each window ! 15: --------------------------------------------------*/ ! 16: typedef struct ! 17: { ! 18: PSZ pszText ; ! 19: BOOL fHaveCapture ; ! 20: BOOL fHaveFocus ; ! 21: BOOL fInsideRect ; ! 22: BOOL fSpaceDown ; ! 23: } ! 24: SQBTN ; ! 25: ! 26: typedef SQBTN FAR *PSQBTN ; ! 27: ! 28: MRESULT EXPENTRY SqBtnWndProc (HWND, USHORT, MPARAM, MPARAM) ; ! 29: VOID DrawButton (HWND, HPS, PSQBTN) ; ! 30: ! 31: HAB hab ; ! 32: ! 33: /*-------------------------------------------------------- ! 34: RegisterSqBtnClass function available to other modules ! 35: --------------------------------------------------------*/ ! 36: ! 37: BOOL RegisterSqBtnClass (HAB habIn) ! 38: { ! 39: hab = habIn ; ! 40: ! 41: return WinRegisterClass (hab, "SqBtn", SqBtnWndProc, ! 42: CS_SIZEREDRAW, sizeof (PSQBTN)) ; ! 43: } ! 44: ! 45: /*------------------------------------------- ! 46: String functions that accept far pointers ! 47: -------------------------------------------*/ ! 48: ! 49: USHORT fstrlen (PCHAR pch) ! 50: { ! 51: USHORT usLen ; ! 52: for (usLen = 0 ; pch[usLen] ; usLen++) ; ! 53: return usLen ; ! 54: } ! 55: ! 56: PCHAR fstrcpy (PCHAR pchDst, PCHAR pchSrc) ! 57: { ! 58: USHORT usIndex ; ! 59: for (usIndex = 0 ; pchDst[usIndex] = pchSrc[usIndex] ; usIndex++) ; ! 60: return pchDst ; ! 61: } ! 62: ! 63: /*------------------------------- ! 64: SqBtnWndProc window procedure ! 65: -------------------------------*/ ! 66: ! 67: MRESULT EXPENTRY SqBtnWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2) ! 68: { ! 69: BOOL fTestInsideRect ; ! 70: HPS hps ; ! 71: PCREATESTRUCT pcrst ; ! 72: POINTL ptl ; ! 73: PSQBTN pSqBtn ; ! 74: PWNDPARAMS pwprm ; ! 75: RECTL rcl ; ! 76: ! 77: pSqBtn = WinQueryWindowPtr (hwnd, 0) ; ! 78: ! 79: switch (msg) ! 80: { ! 81: case WM_CREATE: ! 82: pSqBtn = _fmalloc (sizeof (SQBTN)) ; ! 83: ! 84: // Initialize structure ! 85: ! 86: pSqBtn->fHaveCapture = FALSE ; ! 87: pSqBtn->fHaveFocus = FALSE ; ! 88: pSqBtn->fInsideRect = FALSE ; ! 89: pSqBtn->fSpaceDown = FALSE ; ! 90: ! 91: // Get window text from creation structure ! 92: ! 93: pcrst = (PCREATESTRUCT) PVOIDFROMMP (mp2) ; ! 94: ! 95: pSqBtn->pszText = _fmalloc (1 + fstrlen (pcrst->pszText)) ; ! 96: fstrcpy (pSqBtn->pszText, pcrst->pszText) ; ! 97: ! 98: WinSetWindowPtr (hwnd, 0, pSqBtn) ; ! 99: return 0 ; ! 100: ! 101: case WM_SETWINDOWPARAMS: ! 102: pwprm = (PWNDPARAMS) PVOIDFROMMP (mp1) ; ! 103: ! 104: // Get window text from window parameter structure ! 105: ! 106: if (pwprm->fsStatus & WPM_TEXT) ! 107: { ! 108: _ffree (pSqBtn->pszText) ; ! 109: pSqBtn->pszText = _fmalloc (1 + pwprm->cchText) ; ! 110: fstrcpy (pSqBtn->pszText, pwprm->pszText) ; ! 111: } ! 112: return 1 ; ! 113: ! 114: case WM_QUERYWINDOWPARAMS: ! 115: pwprm == (PWNDPARAMS) PVOIDFROMMP (mp1) ; ! 116: ! 117: // Set window parameter structure fields ! 118: ! 119: if (pwprm->fsStatus & WPM_CCHTEXT) ! 120: pwprm->cchText = fstrlen (pSqBtn->pszText) ; ! 121: ! 122: if (pwprm->fsStatus & WPM_TEXT) ! 123: fstrcpy (pwprm->pszText, pSqBtn->pszText) ; ! 124: ! 125: if (pwprm->fsStatus & WPM_CBPRESPARAMS) ! 126: pwprm->cbPresParams = 0 ; ! 127: ! 128: if (pwprm->fsStatus & WPM_PRESPARAMS) ! 129: pwprm->pPresParams = NULL ; ! 130: ! 131: if (pwprm->fsStatus & WPM_CBCTLDATA) ! 132: pwprm->cbCtlData = 0 ; ! 133: ! 134: if (pwprm->fsStatus & WPM_CTLDATA) ! 135: pwprm->pCtlData = NULL ; ! 136: ! 137: return 1 ; ! 138: ! 139: case WM_BUTTON1DOWN: ! 140: WinSetFocus (HWND_DESKTOP, hwnd) ; ! 141: WinSetCapture (HWND_DESKTOP, hwnd) ; ! 142: pSqBtn->fHaveCapture = TRUE ; ! 143: pSqBtn->fInsideRect = TRUE ; ! 144: WinInvalidateRect (hwnd, NULL, FALSE) ; ! 145: return 0 ; ! 146: ! 147: case WM_MOUSEMOVE: ! 148: if (!pSqBtn->fHaveCapture) ! 149: break ; ! 150: ! 151: WinQueryWindowRect (hwnd, &rcl) ; ! 152: ptl.x = MOUSEMSG(&msg)->x ; ! 153: ptl.y = MOUSEMSG(&msg)->y ; ! 154: ! 155: // Test if mouse pointer is still in window ! 156: ! 157: fTestInsideRect = WinPtInRect (hab, &rcl, &ptl) ; ! 158: ! 159: if (pSqBtn->fInsideRect != fTestInsideRect) ! 160: { ! 161: pSqBtn->fInsideRect = fTestInsideRect ; ! 162: WinInvalidateRect (hwnd, NULL, FALSE) ; ! 163: } ! 164: break ; ! 165: ! 166: case WM_BUTTON1UP: ! 167: if (!pSqBtn->fHaveCapture) ! 168: break ; ! 169: ! 170: WinSetCapture (HWND_DESKTOP, NULL) ; ! 171: pSqBtn->fHaveCapture = FALSE ; ! 172: pSqBtn->fInsideRect = FALSE ; ! 173: ! 174: WinQueryWindowRect (hwnd, &rcl) ; ! 175: ptl.x = MOUSEMSG(&msg)->x ; ! 176: ptl.y = MOUSEMSG(&msg)->y ; ! 177: ! 178: // Post WM_COMMAND if mouse pointer is in window ! 179: ! 180: if (WinPtInRect (hab, &rcl, &ptl)) ! 181: WinPostMsg (WinQueryWindow (hwnd, QW_OWNER, FALSE), ! 182: WM_COMMAND, ! 183: MPFROMSHORT (WinQueryWindowUShort (hwnd, QWS_ID)), ! 184: MPFROM2SHORT (CMDSRC_OTHER, TRUE)) ; ! 185: ! 186: WinInvalidateRect (hwnd, NULL, FALSE) ; ! 187: return 0 ; ! 188: ! 189: case WM_ENABLE: ! 190: WinInvalidateRect (hwnd, NULL, FALSE) ; ! 191: return 0 ; ! 192: ! 193: case WM_SETFOCUS: ! 194: pSqBtn->fHaveFocus = SHORT1FROMMP (mp2) ; ! 195: WinInvalidateRect (hwnd, NULL, FALSE) ; ! 196: return 0 ; ! 197: ! 198: case WM_CHAR: ! 199: if (!(CHARMSG(&msg)->fs & KC_VIRTUALKEY) || ! 200: CHARMSG(&msg)->vkey != VK_SPACE || ! 201: CHARMSG(&msg)->fs & KC_PREVDOWN) ! 202: break ; ! 203: ! 204: // Post WM_COMMAND when space bar is released ! 205: ! 206: if (!(CHARMSG(&msg)->fs & KC_KEYUP)) ! 207: pSqBtn->fSpaceDown = TRUE ; ! 208: else ! 209: { ! 210: pSqBtn->fSpaceDown = FALSE ; ! 211: WinPostMsg (WinQueryWindow (hwnd, QW_OWNER, FALSE), ! 212: WM_COMMAND, ! 213: MPFROMSHORT (WinQueryWindowUShort (hwnd, QWS_ID)), ! 214: MPFROM2SHORT (CMDSRC_OTHER, FALSE)) ; ! 215: } ! 216: WinInvalidateRect (hwnd, NULL, FALSE) ; ! 217: return 0 ; ! 218: ! 219: case WM_PAINT: ! 220: hps = WinBeginPaint (hwnd, NULL, NULL) ; ! 221: DrawButton (hwnd, hps, pSqBtn) ; ! 222: WinEndPaint (hps) ; ! 223: return 0 ; ! 224: ! 225: case WM_DESTROY: ! 226: _ffree (pSqBtn->pszText) ; ! 227: _ffree (pSqBtn) ; ! 228: return 0 ; ! 229: } ! 230: return WinDefWindowProc (hwnd, msg, mp1, mp2) ; ! 231: } ! 232: ! 233: /*-------------------------------------------------------- ! 234: Draws filled and outlined polygon (used by DrawButton) ! 235: --------------------------------------------------------*/ ! 236: ! 237: VOID Polygon (HPS hps, LONG lPoints, POINTL aptl[], LONG lColor) ! 238: { ! 239: // Draw interior in specified color ! 240: ! 241: GpiSavePS (hps) ; ! 242: GpiSetColor (hps, lColor) ; ! 243: ! 244: GpiBeginArea (hps, BA_NOBOUNDARY | BA_ALTERNATE) ; ! 245: GpiMove (hps, aptl) ; ! 246: GpiPolyLine (hps, lPoints - 1, aptl + 1) ; ! 247: GpiEndArea (hps) ; ! 248: ! 249: GpiRestorePS (hps, -1L) ; ! 250: ! 251: // Draw boundary in default color ! 252: ! 253: GpiMove (hps, aptl + lPoints - 1) ; ! 254: GpiPolyLine (hps, lPoints, aptl) ; ! 255: } ! 256: ! 257: /*--------------------- ! 258: Draws Square Button ! 259: ---------------------*/ ! 260: ! 261: VOID DrawButton (HWND hwnd, HPS hps, PSQBTN pSqBtn) ! 262: { ! 263: FATTRS fat ; ! 264: FONTMETRICS fm ; ! 265: HDC hdc ; ! 266: LONG lColor, lHorzRes, lVertRes, cxEdge, cyEdge ; ! 267: POINTL aptl[10], aptlTextBox[TXTBOX_COUNT], ptlShadow, ptlText ; ! 268: RECTL rcl ; ! 269: ! 270: // Find 2 millimeter edge width in pixels ! 271: ! 272: hdc = GpiQueryDevice (hps) ; ! 273: DevQueryCaps (hdc, CAPS_HORIZONTAL_RESOLUTION, 1L, &lHorzRes) ; ! 274: DevQueryCaps (hdc, CAPS_VERTICAL_RESOLUTION, 1L, &lVertRes) ; ! 275: ! 276: cxEdge = lHorzRes / 500 ; ! 277: cyEdge = lVertRes / 500 ; ! 278: ! 279: // Set up coordinates for drawing the button ! 280: ! 281: WinQueryWindowRect (hwnd, &rcl) ; ! 282: ! 283: aptl[0].x = 0 ; aptl[0].y = 0 ; ! 284: aptl[1].x = cxEdge ; aptl[1].y = cyEdge ; ! 285: aptl[2].x = rcl.xRight - cxEdge ; aptl[2].y = cyEdge ; ! 286: aptl[3].x = rcl.xRight - 1 ; aptl[3].y = 0 ; ! 287: aptl[4].x = rcl.xRight - 1 ; aptl[4].y = rcl.yTop - 1 ; ! 288: aptl[5].x = rcl.xRight - cxEdge ; aptl[5].y = rcl.yTop - cyEdge ; ! 289: aptl[6].x = cxEdge ; aptl[6].y = rcl.yTop - cyEdge ; ! 290: aptl[7].x = 0 ; aptl[7].y = rcl.yTop - 1 ; ! 291: aptl[8].x = 0 ; aptl[8].y = 0 ; ! 292: aptl[9].x = cxEdge ; aptl[9].y = cyEdge ; ! 293: ! 294: // Paint edges at bottom and right side ! 295: ! 296: GpiSetColor (hps, CLR_BLACK) ; ! 297: lColor = (pSqBtn->fInsideRect || pSqBtn->fSpaceDown) ? ! 298: CLR_PALEGRAY : CLR_DARKGRAY ; ! 299: Polygon (hps, 4L, aptl + 0, lColor) ; ! 300: Polygon (hps, 4L, aptl + 2, lColor) ; ! 301: ! 302: // Paint edges at top and left side ! 303: ! 304: lColor = (pSqBtn->fInsideRect || pSqBtn->fSpaceDown) ? ! 305: CLR_DARKGRAY : CLR_WHITE ; ! 306: Polygon (hps, 4L, aptl + 4, lColor) ; ! 307: Polygon (hps, 4L, aptl + 6, lColor) ; ! 308: ! 309: // Paint interior area ! 310: ! 311: GpiSavePS (hps) ; ! 312: GpiSetColor (hps, (pSqBtn->fInsideRect || pSqBtn->fSpaceDown) ? ! 313: CLR_DARKGRAY : CLR_PALEGRAY) ; ! 314: GpiMove (hps, aptl + 1) ; ! 315: GpiBox (hps, DRO_FILL, aptl + 5, 0L, 0L) ; ! 316: GpiRestorePS (hps, -1L) ; ! 317: GpiBox (hps, DRO_OUTLINE, aptl + 5, 0L, 0L) ; ! 318: ! 319: // If button has focus, use italic font ! 320: ! 321: GpiQueryFontMetrics (hps, (LONG) sizeof fm, &fm) ; ! 322: ! 323: if (pSqBtn->fHaveFocus) ! 324: { ! 325: fat.usRecordLength = sizeof fat ; ! 326: fat.fsSelection = FATTR_SEL_ITALIC ; ! 327: fat.lMatch = 0 ; ! 328: fat.idRegistry = fm.idRegistry ; ! 329: fat.usCodePage = fm.usCodePage ; ! 330: fat.lMaxBaselineExt = fm.lMaxBaselineExt ; ! 331: fat.lAveCharWidth = fm.lAveCharWidth ; ! 332: fat.fsType = 0 ; ! 333: fat.fsFontUse = 0 ; ! 334: strcpy (fat.szFacename, fm.szFacename) ; ! 335: ! 336: GpiCreateLogFont (hps, NULL, LCID_ITALIC, &fat) ; ! 337: GpiSetCharSet (hps, LCID_ITALIC) ; ! 338: } ! 339: // Calculate text position ! 340: ! 341: GpiQueryTextBox (hps, (LONG) fstrlen (pSqBtn->pszText), pSqBtn->pszText, ! 342: TXTBOX_COUNT, aptlTextBox) ; ! 343: ! 344: ptlText.x = (rcl.xRight - aptlTextBox[TXTBOX_CONCAT].x) / 2 ; ! 345: ptlText.y = (rcl.yTop - aptlTextBox[TXTBOX_TOPLEFT].y - ! 346: aptlTextBox[TXTBOX_BOTTOMLEFT].y) / 2 ; ! 347: ! 348: ptlShadow.x = ptlText.x + fm.lAveCharWidth / 3 ; ! 349: ptlShadow.y = ptlText.y - fm.lMaxBaselineExt / 8 ; ! 350: ! 351: // Display text shadow in black, and text in white ! 352: ! 353: GpiSetColor (hps, CLR_BLACK) ; ! 354: GpiCharStringAt (hps, &ptlShadow, (LONG) fstrlen (pSqBtn->pszText), ! 355: pSqBtn->pszText) ; ! 356: GpiSetColor (hps, CLR_WHITE) ; ! 357: GpiCharStringAt (hps, &ptlText, (LONG) fstrlen (pSqBtn->pszText), ! 358: pSqBtn->pszText) ; ! 359: ! 360: // X out button if the window is not enabled ! 361: ! 362: if (!WinIsWindowEnabled (hwnd)) ! 363: { ! 364: GpiMove (hps, aptl + 1) ; ! 365: GpiLine (hps, aptl + 5) ; ! 366: GpiMove (hps, aptl + 2) ; ! 367: GpiLine (hps, aptl + 6) ; ! 368: } ! 369: // Clean up ! 370: ! 371: if (pSqBtn->fHaveFocus) ! 372: { ! 373: GpiSetCharSet (hps, LCID_DEFAULT) ; ! 374: GpiDeleteSetId (hps, LCID_ITALIC) ; ! 375: } ! 376: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.