|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.