Annotation of pmsdk/samples/petzold/chap14/sqbtn.c, revision 1.1

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:      }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.