Annotation of pmsdk/samples/petzold/chap15/hexcalc2.c, revision 1.1.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.