Annotation of pmsdk/samples/petzold/chap15/hexcalc2.c, revision 1.1

1.1     ! root        1: /*-------------------------------------------------------------------
        !             2:    HEXCALC2.C -- Hexadecimal Calculator with Clipboard Cut and Paste
        !             3:   -------------------------------------------------------------------*/
        !             4: 
        !             5: #define INCL_WIN
        !             6: #include <os2.h>
        !             7: #include <ctype.h>
        !             8: #include <limits.h>
        !             9: #include <stdlib.h>
        !            10: #include <string.h>
        !            11: #include "hexcalc.h"
        !            12: 
        !            13: #define IDM_COPY    256
        !            14: #define IDM_PASTE   257
        !            15: 
        !            16: MRESULT EXPENTRY ClientWndProc (HWND, USHORT, MPARAM, MPARAM) ;
        !            17: 
        !            18: HAB  hab ;
        !            19: 
        !            20: int main (void)
        !            21:      {
        !            22:      HMQ  hmq ;
        !            23:      HWND hwndFrame ;
        !            24:      QMSG qmsg ;
        !            25: 
        !            26:      hab = WinInitialize (0) ;
        !            27:      hmq = WinCreateMsgQueue (hab, 0) ;
        !            28: 
        !            29:      WinRegisterClass (hab, CLIENTCLASS, ClientWndProc, 0L, 0) ;
        !            30: 
        !            31:      hwndFrame = WinLoadDlg (HWND_DESKTOP, HWND_DESKTOP,
        !            32:                              NULL, NULL, ID_HEXCALC, NULL) ;
        !            33: 
        !            34:      WinSendMsg (hwndFrame, WM_SETICON,
        !            35:                  WinLoadPointer (HWND_DESKTOP, NULL, ID_ICON), NULL) ;
        !            36: 
        !            37:      WinSetFocus (HWND_DESKTOP, WinWindowFromID (hwndFrame, FID_CLIENT)) ;
        !            38: 
        !            39:      while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
        !            40:           WinDispatchMsg (hab, &qmsg) ;
        !            41: 
        !            42:      WinDestroyWindow (hwndFrame) ;
        !            43:      WinDestroyMsgQueue (hmq) ;
        !            44:      WinTerminate (hab) ;
        !            45:      return 0 ;
        !            46:      }
        !            47: 
        !            48: HACCEL AddItemsToSysMenu (HWND hwndFrame)
        !            49:      {
        !            50:      static CHAR     *szMenuText [3] = { NULL, "~Copy\tCtrl+Ins",
        !            51:                                                "~Paste\tShift+Ins" } ;
        !            52:      static MENUITEM mi [3] = {
        !            53:                               MIT_END, MIS_SEPARATOR, 0, 0,         NULL, NULL,
        !            54:                               MIT_END, MIS_TEXT,      0, IDM_COPY,  NULL, NULL,
        !            55:                               MIT_END, MIS_TEXT,      0, IDM_PASTE, NULL, NULL
        !            56:                               } ;
        !            57:      ACCELTABLE      *pacct ;
        !            58:      HACCEL          haccel ;
        !            59:      HWND            hwndSysMenu, hwndSysSubMenu ;
        !            60:      MENUITEM        miSysMenu ;
        !            61:      SHORT           idSysMenu, sItem ;
        !            62: 
        !            63:                               // Add items to system menu
        !            64: 
        !            65:      hwndSysMenu = WinWindowFromID (hwndFrame, FID_SYSMENU) ;
        !            66:      idSysMenu = SHORT1FROMMR (WinSendMsg (hwndSysMenu,
        !            67:                                            MM_ITEMIDFROMPOSITION,
        !            68:                                            NULL, NULL)) ;
        !            69: 
        !            70:      WinSendMsg (hwndSysMenu, MM_QUERYITEM,
        !            71:                  MPFROM2SHORT (idSysMenu, FALSE),
        !            72:                  MPFROMP (&miSysMenu)) ;
        !            73: 
        !            74:      hwndSysSubMenu = miSysMenu.hwndSubMenu ;
        !            75: 
        !            76:      for (sItem = 0 ; sItem < 3 ; sItem++)
        !            77:           WinSendMsg (hwndSysSubMenu, MM_INSERTITEM,
        !            78:                       MPFROMP (mi + sItem),
        !            79:                       MPFROMP (szMenuText [sItem])) ;
        !            80: 
        !            81:                               // Create and set accelerator table
        !            82: 
        !            83:      pacct = malloc (sizeof (ACCELTABLE) + sizeof (ACCEL)) ;
        !            84: 
        !            85:      pacct->cAccel        = 2 ;    // Number of accelerators
        !            86:      pacct->codepage      = 0 ;    // Not used
        !            87: 
        !            88:      pacct->aaccel[0].fs  = AF_VIRTUALKEY | AF_CONTROL ;
        !            89:      pacct->aaccel[0].key = VK_INSERT ;
        !            90:      pacct->aaccel[0].cmd = IDM_COPY ;
        !            91: 
        !            92:      pacct->aaccel[1].fs  = AF_VIRTUALKEY | AF_SHIFT ;
        !            93:      pacct->aaccel[1].key = VK_INSERT ;
        !            94:      pacct->aaccel[1].cmd = IDM_PASTE ;
        !            95: 
        !            96:      haccel = WinCreateAccelTable (hab, pacct) ;
        !            97:      WinSetAccelTable (hab, haccel, hwndFrame) ;
        !            98: 
        !            99:      free (pacct) ;
        !           100: 
        !           101:      return haccel ;
        !           102:      }
        !           103: 
        !           104: VOID EnableSysMenuItem (HWND hwnd, USHORT idItem, BOOL fEnable)
        !           105:      {
        !           106:      HWND hwndSysMenu ;
        !           107: 
        !           108:      hwndSysMenu = WinWindowFromID (WinQueryWindow (hwnd, QW_PARENT, FALSE),
        !           109:                                     FID_SYSMENU) ;
        !           110: 
        !           111:      WinSendMsg (hwndSysMenu, MM_SETITEMATTR,
        !           112:                  MPFROM2SHORT (idItem, TRUE),
        !           113:                  MPFROM2SHORT (MIA_DISABLED, fEnable ? 0 : MIA_DISABLED)) ;
        !           114:      }
        !           115: 
        !           116: void ShowNumber (HWND hwnd, ULONG ulNumber)
        !           117:      {
        !           118:      CHAR szBuffer [20] ;
        !           119: 
        !           120:      WinSetWindowText (WinWindowFromID (hwnd, ESCAPE),
        !           121:                        strupr (ltoa (ulNumber, szBuffer, 16))) ;
        !           122:      }
        !           123: 
        !           124: ULONG CalcIt (ULONG ulFirstNum, SHORT sOperation, ULONG ulNum)
        !           125:      {
        !           126:      switch (sOperation)
        !           127:           {
        !           128:           case '=' : return ulNum ;
        !           129:           case '+' : return ulFirstNum +  ulNum ;
        !           130:           case '-' : return ulFirstNum -  ulNum ;
        !           131:           case '*' : return ulFirstNum *  ulNum ;
        !           132:           case '&' : return ulFirstNum &  ulNum ;
        !           133:           case '|' : return ulFirstNum |  ulNum ;
        !           134:           case '^' : return ulFirstNum ^  ulNum ;
        !           135:           case '<' : return ulFirstNum << ulNum ;
        !           136:           case '>' : return ulFirstNum >> ulNum ;
        !           137:           case '/' : return ulNum ? ulFirstNum / ulNum : ULONG_MAX ;
        !           138:           case '%' : return ulNum ? ulFirstNum % ulNum : ULONG_MAX ;
        !           139:           default  : return 0L ;
        !           140:           }
        !           141:      }
        !           142: 
        !           143: MRESULT EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
        !           144:      {
        !           145:      static BOOL   fNewNumber = TRUE ;
        !           146:      static HACCEL haccel ;
        !           147:      static ULONG  ulNumber, ulFirstNum ;
        !           148:      static SHORT  sOperation = '=' ;
        !           149:      HWND          hwndButton ;
        !           150:      PCHAR         pchClipText ;
        !           151:      QMSG          qmsg ;
        !           152:      SEL           selClipText ;
        !           153:      SHORT         s, sLen, idButton ;
        !           154: 
        !           155:      switch (msg)
        !           156:           {
        !           157:           case WM_CREATE:
        !           158:                haccel = AddItemsToSysMenu (
        !           159:                               WinQueryWindow (hwnd, QW_PARENT, FALSE)) ;
        !           160:                return 0 ;
        !           161: 
        !           162:           case WM_CHAR:
        !           163:                if (CHARMSG(&msg)->fs & KC_KEYUP)
        !           164:                     return 0 ;
        !           165: 
        !           166:                if (CHARMSG(&msg)->fs & KC_VIRTUALKEY)
        !           167:                     switch (CHARMSG(&msg)->vkey)
        !           168:                          {
        !           169:                          case VK_LEFT:
        !           170:                               if (!(CHARMSG(&msg)->fs & KC_CHAR))
        !           171:                                    {
        !           172:                                    CHARMSG(&msg)->chr = '\b' ;
        !           173:                                    CHARMSG(&msg)->fs |= KC_CHAR ;
        !           174:                                    }
        !           175:                               break ;
        !           176: 
        !           177:                          case VK_ESC:
        !           178:                               CHARMSG(&msg)->chr = ESCAPE ;
        !           179:                               CHARMSG(&msg)->fs |= KC_CHAR ;
        !           180:                               break ;
        !           181: 
        !           182:                          case VK_NEWLINE:
        !           183:                          case VK_ENTER:
        !           184:                               CHARMSG(&msg)->chr = '=' ;
        !           185:                               CHARMSG(&msg)->fs |= KC_CHAR ;
        !           186:                               break ;
        !           187:                          }
        !           188: 
        !           189:                if (CHARMSG(&msg)->fs & KC_CHAR)
        !           190:                     {
        !           191:                     CHARMSG(&msg)->chr = toupper (CHARMSG(&msg)->chr) ;
        !           192: 
        !           193:                     if (hwndButton = WinWindowFromID (hwnd,CHARMSG(&msg)->chr))
        !           194:                          WinSendMsg (hwndButton, BM_CLICK, NULL, NULL) ;
        !           195:                     else
        !           196:                          WinAlarm (HWND_DESKTOP, WA_ERROR) ;
        !           197:                     }
        !           198:                return 1 ;
        !           199: 
        !           200:           case WM_COMMAND:
        !           201:                idButton = COMMANDMSG(&msg)->cmd ;
        !           202: 
        !           203:                if (idButton == IDM_COPY)                    // "Copy"
        !           204:                     {
        !           205:                     hwndButton = WinWindowFromID (hwnd, ESCAPE) ;
        !           206:                     sLen = WinQueryWindowTextLength (hwndButton) + 1 ;
        !           207: 
        !           208:                     DosAllocSeg (sLen, &selClipText, SEG_GIVEABLE) ;
        !           209:                     pchClipText = MAKEP (selClipText, 0) ;
        !           210:                     WinQueryWindowText (hwndButton, sLen, pchClipText) ;
        !           211: 
        !           212:                     WinOpenClipbrd (hab) ;
        !           213:                     WinEmptyClipbrd (hab) ;
        !           214:                     WinSetClipbrdData (hab, (ULONG) selClipText, CF_TEXT,
        !           215:                                        CFI_SELECTOR) ;
        !           216:                     WinCloseClipbrd (hab) ;
        !           217:                     }
        !           218: 
        !           219:                else if (idButton == IDM_PASTE)              // "Paste"
        !           220:                     {
        !           221:                     EnableSysMenuItem (hwnd, IDM_COPY,  FALSE) ;
        !           222:                     EnableSysMenuItem (hwnd, IDM_PASTE, FALSE) ;
        !           223: 
        !           224:                     WinOpenClipbrd (hab) ;
        !           225: 
        !           226:                     selClipText = (SEL) WinQueryClipbrdData (hab, CF_TEXT) ;
        !           227: 
        !           228:                     if (selClipText != 0)
        !           229:                          {
        !           230:                          pchClipText = MAKEP (selClipText, 0) ;
        !           231: 
        !           232:                          for (s = 0 ; pchClipText[s] ; s++)
        !           233:                               {
        !           234:                               if (pchClipText[s] == '\r')
        !           235:                                    WinSendMsg (hwnd, WM_CHAR,
        !           236:                                                MPFROM2SHORT (KC_CHAR, 1),
        !           237:                                                MPFROM2SHORT ('=', 0)) ;
        !           238: 
        !           239:                               else if (pchClipText[s] != '\n' &&
        !           240:                                        pchClipText[s] != ' ')
        !           241:                                    WinSendMsg (hwnd, WM_CHAR,
        !           242:                                                MPFROM2SHORT (KC_CHAR, 1),
        !           243:                                                MPFROM2SHORT (pchClipText[s],
        !           244:                                                              0)) ;
        !           245: 
        !           246:                               while (WinPeekMsg (hab, &qmsg, NULL, 0, 0,
        !           247:                                                  PM_NOREMOVE))
        !           248:                                    {
        !           249:                                    if (qmsg.msg == WM_QUIT)
        !           250:                                         {
        !           251:                                         WinCloseClipbrd (hab) ;
        !           252:                                         return 0 ;
        !           253:                                         }
        !           254:                                    else
        !           255:                                         {
        !           256:                                         WinGetMsg (hab, &qmsg, NULL, 0, 0) ;
        !           257:                                         WinDispatchMsg (hab, &qmsg) ;
        !           258:                                         }
        !           259:                                    }
        !           260:                               }
        !           261:                          }
        !           262:                     WinCloseClipbrd (hab) ;
        !           263: 
        !           264:                     EnableSysMenuItem (hwnd, IDM_COPY,  TRUE) ;
        !           265:                     EnableSysMenuItem (hwnd, IDM_PASTE, TRUE) ;
        !           266:                     }
        !           267: 
        !           268:                else if (idButton == '\b')                   // backspace
        !           269:                     ShowNumber (hwnd, ulNumber /= 16) ;
        !           270: 
        !           271:                else if (idButton == ESCAPE)                 // escape
        !           272:                     ShowNumber (hwnd, ulNumber = 0L) ;
        !           273: 
        !           274:                else if (isxdigit (idButton))                // hex digit
        !           275:                     {
        !           276:                     if (fNewNumber)
        !           277:                          {
        !           278:                          ulFirstNum = ulNumber ;
        !           279:                          ulNumber = 0L ;
        !           280:                          }
        !           281:                     fNewNumber = FALSE ;
        !           282: 
        !           283:                     if (ulNumber <= ULONG_MAX >> 4)
        !           284:                          ShowNumber (hwnd,
        !           285:                               ulNumber = 16 * ulNumber + idButton -
        !           286:                                    (isdigit (idButton) ? '0' : 'A' - 10)) ;
        !           287:                     else
        !           288:                          WinAlarm (HWND_DESKTOP, WA_ERROR) ;
        !           289:                     }
        !           290:                else                                         // operation
        !           291:                     {
        !           292:                     if (!fNewNumber)
        !           293:                          ShowNumber (hwnd, ulNumber =
        !           294:                               CalcIt (ulFirstNum, sOperation, ulNumber)) ;
        !           295:                     fNewNumber = TRUE ;
        !           296:                     sOperation = idButton ;
        !           297:                     }
        !           298:                return 0 ;
        !           299: 
        !           300:           case WM_BUTTON1DOWN:
        !           301:                WinAlarm (HWND_DESKTOP, WA_ERROR) ;
        !           302:                break ;
        !           303: 
        !           304:           case WM_ERASEBACKGROUND:
        !           305:                return 1 ;
        !           306: 
        !           307:           case WM_DESTROY:
        !           308:                WinDestroyAccelTable (haccel) ;
        !           309:                return 0 ;
        !           310:           }
        !           311:      return WinDefWindowProc (hwnd, msg, mp1, mp2) ;
        !           312:      }

unix.superglobalmegacorp.com

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