Annotation of pmsdk/samples/petzold/chap16/sqbtnlib.c, revision 1.1

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

unix.superglobalmegacorp.com

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