|
|
1.1 root 1: /**************************************************************************\
2: * uconvert.c -- convert to/from unicode using
3: * MulitByteToWideChar & WideCharToMulitByte
4: *
5: * Steve Firebaugh
6: * Microsoft Developer Support
7: * Copyright (c) 1992, 1993 Microsoft Corporation
8: *
9: \**************************************************************************/
10: #define UNICODE
11:
12:
13: #include <windows.h>
14: #include <commdlg.h>
15: #include "uconvert.h"
16: #include "install.h"
17:
18:
19:
20:
21:
22:
23: /**************************************************************************\
24: * Global variables.
25: \**************************************************************************/
26:
27: HANDLE hInst;
28:
29: /* declare global HWNDs for the child windows.
30: * They are created at WM_CREATE of the main window.
31: * Also used in the "View" dialogs.
32: */
33: HWND hwndLabel0, hwndLabel1;
34: HWND hwndName0, hwndName1;
35: HWND hwndSize0, hwndSize1;
36: HWND hwndCodePage0, hwndCodePage1;
37: HWND hwndByteOrder0, hwndByteOrder1;
38: HWND hwndButton0, hwndButton1;
39:
40: /* Global variables storing the source and destination "type" information.
41: *
42: * used to communicate between main wnd proc, and *OptionsProc.
43: *
44: * gTypeSource - stores the type interpretation of the source data
45: * (and implicitly the destination data.)
46: * TYPEUNKNOWN: indeterminant... not set. Can not do conversion.
47: * TYPEUNICODE: source unicode & destination giDestinationCodePage.
48: * TYPECODEPAGE: source giSourceCodePage & destination unicode.
49: *
50: * giSourceCodePage stores valid source code page iff gTypeSource == TRUE
51: * giDestinationCodePage stores valid destination code page iff gTypeSource == FALSE
52: *
53: */
54: int gTypeSource;
55: UINT giSourceCodePage;
56: UINT giDestinationCodePage;
57:
58: /* Pointers to the source and destination data, and the
59: * count of bytes in each of the buffers.
60: */
61: #define NODATA 0
62: PBYTE pSourceData = NULL;
63: PBYTE pDestinationData = NULL;
64: int nBytesSource = NODATA;
65: int nBytesDestination = NODATA;
66:
67: /* Conversion Options variables. */
68: DWORD gMBFlags = MB_PRECOMPOSED;
69: DWORD gWCFlags = 0;
70: char glpDefaultChar[4] = ""; // what is max size of multibyte character?
71: BOOL gUsedDefaultChar = FALSE;
72:
73: /* Handling the Byte Order Mark (BOM).
74: *
75: * If the input file begins with a BOM, then we know it is unicode,
76: * we skip over the BOM and decrement the size of data by SIZEOFBOM.
77: *
78: *
79: * Before writing data that we know is unicode, write the szBOM string
80: * to the file.
81: *
82: * Notice that this means that the file sizes we show in the window
83: * do NOT include the BOM.
84: */
85:
86: char szBOM[] = "\377\376"; // 0xFF, 0xFE // leave off TEXT() macro.
87: char szRBOM[] = "\376\377"; // 0xFF, 0xFE // leave off TEXT() macro.
88: #define SIZEOFBOM 2
89:
90: /* Title of main window */
91: TCHAR TitleMBToWC[]= TEXT("UConvert -- MultiByteToWideChar()");
92: TCHAR TitleWCToMB[]= TEXT("UConvert -- WideCharToMultiByte()");
93: TCHAR TitleUnknown[]= TEXT("UConvert.");
94:
95: /* file name of the online help file */
96: TCHAR szHelpPathName[] = TEXT("uconvert.HLP");
97:
98: /* Strings used to fill onscreen windows. */
99: TCHAR szBlank[] = TEXT("");
100: TCHAR szNBytes[] = TEXT("bytes: %d");
101: TCHAR szByteOrderReversed[]=TEXT("Byte Order Reversed.");
102:
103: /* MessageBox() strings and flags. */
104: TCHAR MBTitle[]= TEXT("Application Warning");
105: UINT MBFlags = MB_OK | MB_ICONEXCLAMATION;
106:
107:
108: /* misc. defines affecting size and placement of child windows */
109: #define BORDER GetSystemMetrics (SM_CXFRAME)*4
110: #define WHEIGHT GetSystemMetrics (SM_CYMENU)
111:
112:
113:
114: /**************************************************************************\
115: *
116: * function: WinMain()
117: *
118: *
119: \**************************************************************************/
120: int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
121: LPSTR lpCmdLine, int nCmdShow)
122: {
123: MSG msg;
124: WNDCLASS wc;
125: HWND hwndMain;
126: HACCEL haccel;
127:
128:
129: UNREFERENCED_PARAMETER( lpCmdLine );
130: UNREFERENCED_PARAMETER( nCmdShow );
131: hInst = hInstance;
132:
133:
134: /* Check for previous instance. If none, then register class. */
135: if (!hPrevInstance) {
136:
137: wc.style = 0;
138: wc.lpfnWndProc = (WNDPROC)MainWndProc;
139:
140: wc.cbClsExtra = 0;
141: wc.cbWndExtra = 0;
142: wc.hInstance = hInstance;
143: wc.hIcon = LoadIcon(hInstance, TEXT("uconvertIcon"));
144: wc.hCursor = LoadCursor(NULL, IDC_ARROW);
145: wc.hbrBackground = GetStockObject (LTGRAY_BRUSH);
146: wc.lpszMenuName = TEXT("uconvertMenu");
147: wc.lpszClassName = TEXT("uconvert");
148:
149: if (!RegisterClass(&wc)) return (FALSE);
150:
151: } /* class registered o.k. */
152:
153:
154: /* Create the main window. Return false if CreateWindow() fails */
155: hwndMain = CreateWindow(
156: TEXT("uconvert"),
157: TitleUnknown,
158: (WS_OVERLAPPEDWINDOW & ~(WS_THICKFRAME | WS_MAXIMIZEBOX)) | WS_VISIBLE,
159: CW_USEDEFAULT,
160: CW_USEDEFAULT,
161: 512, // Big enough for most of the text.
162: 16*WHEIGHT,
163: NULL, NULL, hInst, NULL);
164:
165: if (!hwndMain) return (FALSE);
166:
167:
168: /* Load the accelerator table that provides clipboard support. */
169: haccel = LoadAccelerators (hInst, TEXT("uconvertAccel"));
170:
171:
172:
173: /* Loop getting messages and dispatching them. */
174: while (GetMessage(&msg, NULL, 0,0)) {
175: if (!TranslateAccelerator(hwndMain, haccel, &msg)) {
176: TranslateMessage(&msg);
177: DispatchMessage(&msg);
178: }
179: }
180:
181: return (msg.wParam);
182: }
183:
184:
185:
186:
187: /**************************************************************************\
188: *
189: * function: MainWndProc()
190: *
191: *
192: * On WM_CREATE create all of the child windows.
193: * On WM_DESTROY make sure that all dynamically allocated memory is freed.
194: * On WM_PAINT, outline many of the child windows.
195: * On WM_COMMAND, respond to the command messages properly.
196: *
197: \**************************************************************************/
198: LRESULT CALLBACK MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
199: {
200:
201:
202: /* misc. variables used in multiple messages cases. */
203: RECT clientrect;
204: RECT rect;
205: TCHAR buffer[50];
206: static TCHAR szFilter[MAX_PATH];
207:
208: switch (message) {
209:
210: /**********************************************************************\
211: * WM_CREATE
212: *
213: * Create all of the child windows used on this main window.
214: * Assign the HWNDs to the correct static variables.
215: *
216: \**********************************************************************/
217: case WM_CREATE: {
218: GetClientRect (hwnd, &clientrect);
219:
220: /* Create Source Windows. */
221: CopyRect (&rect, &clientrect);
222: rect.right = (clientrect.right - clientrect.left) /2;
223: InflateRect (&rect, -2*BORDER, -BORDER);
224: createwindows(&rect,
225: hwnd,
226: &hwndLabel0,
227: &hwndName0,
228: &hwndSize0,
229: &hwndCodePage0,
230: &hwndByteOrder0,
231: &hwndButton0);
232:
233: /* Create Destination Windows. */
234: CopyRect (&rect, &clientrect);
235: rect.left = (clientrect.right - clientrect.left) /2;
236: InflateRect (&rect, -2*BORDER, -BORDER);
237: createwindows(&rect,
238: hwnd,
239: &hwndLabel1,
240: &hwndName1,
241: &hwndSize1,
242: &hwndCodePage1,
243: &hwndByteOrder1,
244: &hwndButton1);
245:
246: /* fill in window information that is different for source/destination */
247: SetWindowText (hwndLabel0, TEXT("Source:" ));
248: SetWindowText (hwndLabel1, TEXT("Destination:"));
249:
250: SetWindowText (hwndButton0, TEXT("View &Source..." ));
251: SetWindowText (hwndButton1, TEXT("View &Destination..."));
252: SetWindowLong (hwndButton0, GWL_ID, BID_VIEWSOURCE );
253: SetWindowLong (hwndButton1, GWL_ID, BID_VIEWDESTINATION );
254:
255: gTypeSource = TYPEUNKNOWN;
256: giSourceCodePage = GetACP(); // Just some reasonable initializer.
257: giDestinationCodePage = GetACP(); // Just some reasonable initializer.
258:
259: /* initialize source & destination data correctly */
260: SendMessage (hwnd, WM_COMMAND, MID_CLEARSOURCE, 0);
261: SendMessage (hwnd, WM_COMMAND, MID_CLEARDESTINATION, 0);
262:
263: /* Build up the correct filter strings for OPENFILENAME structure
264: * Do it here so that we only have to do it once.
265: */
266: {
267: TCHAR *p;
268:
269: p = szFilter;
270: lstrcpy (buffer,TEXT("All Files (*.*)"));
271: lstrcpy (p,buffer);
272: p += lstrlen (buffer) +1;
273: lstrcpy (buffer,TEXT("*.*"));
274: lstrcpy (p,buffer);
275: p += lstrlen (buffer) +1;
276:
277: lstrcpy (buffer,TEXT("Text Files (*.txt)"));
278: lstrcpy (p,buffer);
279: p += lstrlen (buffer) +1;
280: lstrcpy (buffer,TEXT("*.txt"));
281: lstrcpy (p,buffer);
282: p += lstrlen (buffer) +1;
283:
284: lstrcpy (buffer,TEXT("Unicode Files (*.utf)"));
285: lstrcpy (p,buffer);
286: p += lstrlen (buffer) +1;
287: lstrcpy (buffer,TEXT("*.utf"));
288: lstrcpy (p,buffer);
289: p += lstrlen (buffer) +1;
290:
291: lstrcpy (p,TEXT("\0"));
292: }
293: } break; /* end WM_CREATE */
294:
295:
296:
297: /**********************************************************************\
298: * WM_DESTROY
299: *
300: * Release the Online help, and free allocated memory if any.
301: \**********************************************************************/
302: case WM_DESTROY:
303: WinHelp( hwnd, szHelpPathName, (UINT) HELP_QUIT, (DWORD) NULL );
304: ManageMemory (MMFREE, MMSOURCE, 0, pSourceData);
305: ManageMemory (MMFREE, MMDESTINATION, 0, pDestinationData);
306: PostQuitMessage(0);
307: break;
308:
309:
310: /**********************************************************************\
311: * WM_CTLCOLOR*
312: *
313: * Set the background of the child controls to be gray here.
314: \**********************************************************************/
315: case WM_CTLCOLORBTN:
316: case WM_CTLCOLORSTATIC: {
317: HDC hdc;
318:
319: hdc = (HDC) wParam;
320: SetBkMode (hdc, TRANSPARENT);
321: return (LRESULT)GetStockObject (LTGRAY_BRUSH);
322: } break;
323:
324:
325:
326:
327: /**********************************************************************\
328: * WM_PAINT
329: *
330: * Simply draw the two vertical divider lines, and 3D frame the children.
331: *
332: \**********************************************************************/
333: case WM_PAINT: {
334: HDC hdc;
335: PAINTSTRUCT ps;
336:
337: hdc = BeginPaint(hwnd, &ps);
338: GetClientRect (hwnd, &clientrect);
339:
340: /* draw vertical separator line in the center */
341: rect.left = (clientrect.right - clientrect.left ) /2 -1;
342: rect.top = clientrect.top;
343: rect.right = rect.left +1;;
344: rect.bottom = clientrect.bottom;
345: FrameRect (hdc, &rect, GetStockObject (GRAY_BRUSH));
346: SelectObject (hdc, GetStockObject (WHITE_PEN));
347: MoveToEx (hdc, rect.right, rect.top, NULL);
348: LineTo (hdc,rect.right, rect.bottom);
349:
350: /* draw 3D outlines of child windows. */
351: framechildwindow (hdc, hwnd, hwndName0);
352: framechildwindow (hdc, hwnd, hwndSize0);
353: framechildwindow (hdc, hwnd, hwndCodePage0);
354: framechildwindow (hdc, hwnd, hwndByteOrder0);
355:
356: framechildwindow (hdc, hwnd, hwndName1);
357: framechildwindow (hdc, hwnd, hwndSize1);
358: framechildwindow (hdc, hwnd, hwndCodePage1);
359: framechildwindow (hdc, hwnd, hwndByteOrder1);
360:
361: /* underline the labels */
362: underlinechildwindow (hdc, hwnd, hwndLabel0);
363: underlinechildwindow (hdc, hwnd, hwndLabel1);
364:
365: EndPaint (hwnd, &ps);
366: } break; /* end WM_PAINT */
367:
368:
369:
370:
371: /**********************************************************************\
372: * WMU_ADJUSTFORNEWSOURCE
373: *
374: * lParam - szName of source (file, clipboard, ...)
375: *
376: * global - nBytesSource
377: *
378: * "user message." Set the text of the Source windows
379: \**********************************************************************/
380: case WMU_ADJUSTFORNEWSOURCE: {
381: LPVOID szName;
382:
383: szName = (LPVOID) lParam;
384:
385: /* Set Window text appropriately */
386: wsprintf (buffer, szNBytes, nBytesSource);
387: SetWindowText (hwndSize0, buffer);
388: SetWindowText (hwndName0, szName);
389: SetWindowText (hwndByteOrder0, szBlank);
390:
391: /* Clear the destination data if any to avoid user confusion. */
392: SendMessage (hwnd, WM_COMMAND, MID_CLEARDESTINATION, 0);
393:
394: /* Reset the "type strings" based on new gTypeSource. */
395: SendMessage (hwnd, WMU_SETTYPESTRINGS, 0,0);
396: } break;
397:
398:
399:
400:
401: /**********************************************************************\
402: * WMU_SETTYPESTRINGS
403: *
404: * "user message." Set the text of the "type" windows to reflect
405: * the state stored in gTypeSource and gi*CodePage.
406: *
407: \**********************************************************************/
408: case WMU_SETTYPESTRINGS:
409: switch (gTypeSource) {
410: case TYPEUNICODE:
411: SetWindowText (hwndCodePage0, TEXT("Unicode"));
412: wsprintf (buffer, TEXT("CodePage: %d"), giDestinationCodePage);
413: SetWindowText (hwndCodePage1, buffer);
414: SetWindowText (hwnd, TitleWCToMB);
415: break;
416: case TYPECODEPAGE:
417: wsprintf (buffer, TEXT("CodePage: %d"), giSourceCodePage);
418: SetWindowText (hwndCodePage0, buffer);
419: SetWindowText (hwndCodePage1, TEXT("Unicode"));
420: SetWindowText (hwnd, TitleMBToWC);
421: break;
422: case TYPEUNKNOWN:
423: SetWindowText (hwndCodePage0, szBlank);
424: SetWindowText (hwndCodePage1, szBlank);
425: SetWindowText (hwnd, TitleUnknown);
426: break;
427: } /* end switch gTypeSource */
428: break;
429:
430:
431: /**********************************************************************\
432: * WM_INITMENU
433: *
434: * Manage the enabled state of all of the menus.
435: * Notice that the button enabled state is taken care of in ManageMemory().
436: *
437: * In general, this is dependent upon pSourceData & pDestinationData.
438: * They are either NULL or non-NULL, and menu items are dependent upon
439: * this state.
440: *
441: * One exception is the "Paste from Clipboard menu" which is enabled
442: * conditional upon there being text data in the clipboard.
443: *
444: \**********************************************************************/
445: case WM_INITMENU:
446:
447: /* Adjust the "Paste from Clipboard menu" */
448: OpenClipboard (hwnd);
449: if (IsClipboardFormatAvailable (CF_UNICODETEXT) ||
450: IsClipboardFormatAvailable (CF_OEMTEXT) ||
451: IsClipboardFormatAvailable (CF_TEXT))
452: EnableMenuItem (GetMenu (hwnd),MID_PASTESOURCE, MF_ENABLED);
453: else
454: EnableMenuItem (GetMenu (hwnd),MID_PASTESOURCE, MF_GRAYED);
455: CloseClipboard ();
456:
457:
458: /* Adjust the source data dependent menus. */
459: if (pSourceData != NULL) {
460: EnableMenuItem (GetMenu (hwnd),MID_SOURCEOPT, MF_ENABLED);
461: EnableMenuItem (GetMenu (hwnd),MID_SWAPSOURCE, MF_ENABLED);
462: EnableMenuItem (GetMenu (hwnd),MID_CLEARSOURCE, MF_ENABLED);
463: EnableMenuItem (GetMenu (hwnd),MID_CONVERTNOW, MF_ENABLED);
464: EnableMenuItem (GetMenu (hwnd),MID_CONVERSIONOPT, MF_ENABLED);
465: EnableMenuItem (GetMenu (hwnd),MID_DESTINATIONOPT, MF_ENABLED);
466: } else {
467: EnableMenuItem (GetMenu (hwnd),MID_SOURCEOPT, MF_GRAYED);
468: EnableMenuItem (GetMenu (hwnd),MID_SWAPSOURCE, MF_GRAYED);
469: EnableMenuItem (GetMenu (hwnd),MID_CLEARSOURCE, MF_GRAYED);
470: EnableMenuItem (GetMenu (hwnd),MID_CONVERTNOW, MF_GRAYED);
471: EnableMenuItem (GetMenu (hwnd),MID_CONVERSIONOPT, MF_GRAYED);
472: EnableMenuItem (GetMenu (hwnd),MID_DESTINATIONOPT, MF_GRAYED);
473: }
474:
475:
476: /* Adjust the destination data dependent menus. */
477: if (pDestinationData != NULL) {
478: EnableMenuItem (GetMenu (hwnd),MID_SAVEAS, MF_ENABLED);
479: EnableMenuItem (GetMenu (hwnd),MID_SWAPDESTINATION, MF_ENABLED);
480: EnableMenuItem (GetMenu (hwnd),MID_COPYDESTINATION, MF_ENABLED);
481: EnableMenuItem (GetMenu (hwnd),MID_CLEARDESTINATION, MF_ENABLED);
482: } else {
483: EnableMenuItem (GetMenu (hwnd),MID_SAVEAS, MF_GRAYED);
484: EnableMenuItem (GetMenu (hwnd),MID_SWAPDESTINATION, MF_GRAYED);
485: EnableMenuItem (GetMenu (hwnd),MID_COPYDESTINATION, MF_GRAYED);
486: EnableMenuItem (GetMenu (hwnd),MID_CLEARDESTINATION, MF_GRAYED);
487: }
488:
489: break;
490:
491:
492:
493:
494:
495: /**********************************************************************\
496: * WM_COMMAND
497: *
498: * Just switch() on the command ID. Notice that menu and button
499: * command messages are treated the same.
500: *
501: \**********************************************************************/
502: case WM_COMMAND:
503: switch (LOWORD(wParam)) {
504:
505:
506: /******************************************************************\
507: * WM_COMMAND, MID_OPEN
508: *
509: * Put up common dialog, try to open & read file.
510: * Fill windows with correct text & fill pSourceData.
511: \******************************************************************/
512: case MID_OPEN : {
513: HANDLE hFile;
514: DWORD nBytesRead;
515: TCHAR szFile[MAX_PATH],szFileTitle[MAX_PATH];
516:
517: /* First set up the structure for the GetOpenFileName
518: * common dialog.
519: */
520: {
521: OPENFILENAME OpenFileName;
522: /* buffers for the file names. */
523:
524: wsprintf (szFile, szBlank);
525: wsprintf (szFileTitle, szBlank);
526:
527:
528: OpenFileName.lStructSize = sizeof(OPENFILENAME);
529: OpenFileName.hwndOwner = hwnd;
530: OpenFileName.hInstance = (HANDLE) hInst;
531: OpenFileName.lpstrFilter = szFilter; // built in WM_CREATE
532: OpenFileName.lpstrCustomFilter = NULL;
533: OpenFileName.nMaxCustFilter = 0L;
534: OpenFileName.nFilterIndex = 1L;
535: OpenFileName.lpstrFile = szFile;
536: OpenFileName.nMaxFile = MAX_PATH;
537: OpenFileName.lpstrFileTitle = szFileTitle;
538: OpenFileName.nMaxFileTitle = MAX_PATH;
539: OpenFileName.lpstrInitialDir = NULL;
540: OpenFileName.lpstrTitle = TEXT("Open File");
541:
542: OpenFileName.nFileOffset = 0;
543: OpenFileName.nFileExtension = 0;
544: OpenFileName.lpstrDefExt = NULL;
545:
546: OpenFileName.lCustData = 0;
547: OpenFileName.lpfnHook = NULL;
548: OpenFileName.lpTemplateName = NULL;
549:
550: OpenFileName.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;
551:
552: if (!GetOpenFileName(&OpenFileName)) return 0;
553: }
554:
555:
556: /* User has filled in the file information.
557: * Try to open that file for reading.
558: */
559: hFile = CreateFile(szFile,
560: GENERIC_READ,
561: 0,
562: NULL,
563: OPEN_EXISTING,
564: FILE_ATTRIBUTE_NORMAL,
565: NULL);
566: if (hFile == INVALID_HANDLE_VALUE) {
567: MessageBox (hwnd, TEXT("open file failed."),MBTitle, MBFlags);
568: return 0;
569: }
570:
571:
572: /* make sure file is not too big... i.e. > 2^32
573: * If it is OK, write the file size in hwndSize0
574: */
575: {
576: BY_HANDLE_FILE_INFORMATION bhfi;
577:
578: GetFileInformationByHandle (hFile, &bhfi);
579: if (bhfi.nFileSizeHigh != 0) {
580: MessageBox (hwnd, TEXT("File too big, > 2^32."),MBTitle, MBFlags);
581: CloseHandle (hFile);
582: return 0;
583: }
584:
585: nBytesSource= bhfi.nFileSizeLow;
586:
587: }
588:
589: pSourceData = ManageMemory (MMALLOC, MMSOURCE, nBytesSource, pSourceData);
590: if (pSourceData == NULL) {
591: CloseHandle (hFile);
592: return 0;
593: }
594:
595: /* first read two bytes and look for BOM */
596: if (!ReadFile (hFile, pSourceData,SIZEOFBOM, &nBytesRead, NULL)) {
597: MessageBox (hwnd, TEXT("ReadFile() failed."),MBTitle, MBFlags);
598: CloseHandle (hFile);
599: pSourceData = ManageMemory (MMFREE, MMSOURCE, 0, pSourceData);
600: return 0;
601: }
602:
603:
604:
605: /* If file begins with BOM, then we know the type,
606: * we'll decrement the number of bytes by two,
607: * and read the rest of the data.
608: */
609: if (IsBOM (pSourceData)) {
610: gTypeSource = TYPEUNICODE;
611: nBytesSource -=SIZEOFBOM;
612:
613: /* If file begins with Reverse BOM, then we know the type,
614: * we'll decrement the number of bytes by two,
615: * and read the rest of the data, and post a message so
616: * that we know to swap the order later.
617: */
618: } else if (IsRBOM (pSourceData)) {
619: gTypeSource = TYPEUNICODE;
620: nBytesSource -=SIZEOFBOM;
621: MessageBox (hwnd, TEXT("Reverse byte order mark detected.\n Automatically swapping byte order."),MBTitle, MBFlags);
622: PostMessage (hwnd, WM_COMMAND, MID_SWAPSOURCE, 0);
623:
624: /* Oops, does not begin with BOM.
625: * Reset file pointer, and read data.
626: */
627: } else {
628: gTypeSource = TYPEUNKNOWN;
629: SetFilePointer (hFile, -SIZEOFBOM, NULL, FILE_CURRENT);
630: }
631:
632:
633:
634: /* try to read all of it into memory */
635: if (!ReadFile (hFile, pSourceData,nBytesSource, &nBytesRead, NULL)) {
636: MessageBox (hwnd, TEXT("ReadFile() failed."),MBTitle, MBFlags);
637: CloseHandle (hFile);
638: pSourceData = ManageMemory (MMFREE, MMSOURCE, 0, pSourceData);
639: return 0;
640: }
641:
642: CloseHandle (hFile);
643:
644: /* If we don't know the file type at this point,
645: * try to determine if it is unicode.
646: */
647: if (gTypeSource == TYPEUNKNOWN) {
648: if (IsUnicode (pSourceData))
649: gTypeSource = TYPEUNICODE;
650: else
651: gTypeSource = TYPECODEPAGE;
652: }
653:
654: SendMessage (hwnd, WMU_ADJUSTFORNEWSOURCE, 0, (LPARAM)szFile);
655:
656:
657:
658: } break; /* end case MID_OPEN */
659:
660:
661:
662: /******************************************************************\
663: * WM_COMMAND, MID_SAVEAS
664: *
665: * Put up common dialog, try to open file, and write data to it.
666: \******************************************************************/
667: case MID_SAVEAS: {
668: HANDLE hFile;
669: DWORD nBytesRead;
670: TCHAR szFile[MAX_PATH],szFileTitle[MAX_PATH];
671:
672: if (nBytesDestination == NODATA ) {
673: MessageBox (hwnd, TEXT("No text to save"),MBTitle, MBFlags);
674: return 0;
675: }
676:
677:
678: /* Set up the structure for the GetSaveFileName
679: * common dialog.
680: */
681: {
682: OPENFILENAME OpenFileName;
683: /* buffers for the file names. */
684:
685: wsprintf (szFile, szBlank);
686: wsprintf (szFileTitle, szBlank);
687:
688: OpenFileName.lStructSize = sizeof(OPENFILENAME);
689: OpenFileName.hwndOwner = hwnd;
690: OpenFileName.hInstance = (HANDLE) hInst;
691: OpenFileName.lpstrFilter = szFilter;
692: OpenFileName.lpstrCustomFilter = NULL;
693: OpenFileName.nMaxCustFilter = 0L;
694: OpenFileName.nFilterIndex = 1L;
695: OpenFileName.lpstrFile = szFile;
696: OpenFileName.nMaxFile = MAX_PATH;
697: OpenFileName.lpstrFileTitle = szFileTitle;
698: OpenFileName.nMaxFileTitle = MAX_PATH;
699: OpenFileName.lpstrInitialDir = NULL;
700: OpenFileName.lpstrTitle = TEXT("Save As");
701:
702: OpenFileName.nFileOffset = 0;
703: OpenFileName.nFileExtension = 0;
704: OpenFileName.lpstrDefExt = NULL;
705:
706: OpenFileName.lCustData = 0;
707: OpenFileName.lpfnHook = NULL;
708: OpenFileName.lpTemplateName = NULL;
709:
710: OpenFileName.Flags = OFN_HIDEREADONLY;
711:
712: if (!GetSaveFileName(&OpenFileName)) return 0;
713: }
714:
715:
716: /* User has filled in the file information.
717: * Try to open that file for writing.
718: */
719: hFile = CreateFile(szFile,
720: GENERIC_WRITE,
721: 0,
722: NULL,
723: CREATE_ALWAYS,
724: FILE_ATTRIBUTE_NORMAL,
725: NULL);
726:
727: if (hFile == INVALID_HANDLE_VALUE) {
728: MessageBox (hwnd, TEXT("CreateFile() failed."),MBTitle, MBFlags);
729: return 0;
730: }
731:
732:
733: /* if destination is unicode, try to write BOM first.
734: * unless the bytes have been swapped
735: * (criterion: hwndByteOrder contains text)
736: * in which case, write a Reverse Byte Order Mark.
737: */
738: if (gTypeSource == TYPECODEPAGE) {
739: if (GetWindowTextLength (hwndByteOrder1) == 0) {
740:
741: if (!WriteFile (hFile, szBOM, SIZEOFBOM, &nBytesRead, NULL)) {
742: MessageBox (hwnd, TEXT("WriteFile() failed."),MBTitle, MBFlags);
743: CloseHandle (hFile);
744: return 0;
745: }
746:
747: }else {
748: if (!WriteFile (hFile, szRBOM, SIZEOFBOM, &nBytesRead, NULL)) {
749: MessageBox (hwnd, TEXT("WriteFile() failed."),MBTitle, MBFlags);
750: CloseHandle (hFile);
751: return 0;
752: }
753:
754: }
755: }
756:
757:
758: /* try to write all of it into memory */
759: if (!WriteFile (hFile, pDestinationData,nBytesDestination, &nBytesRead, NULL)) {
760: MessageBox (hwnd, TEXT("WriteFile() failed."),MBTitle, MBFlags);
761: CloseHandle (hFile);
762: return 0;
763: }
764:
765: SetWindowText (hwndName1, szFile);
766: CloseHandle (hFile);
767:
768: } break;
769:
770:
771: /**********************************************************************\
772: * WM_COMMAND, MID_PASTESOURCE
773: *
774: * Paste the clipboard's prefered data format into the source.
775: * Fills pSourceData.
776: \**********************************************************************/
777: case MID_PASTESOURCE: {
778: UINT iFormat;
779: PVOID pData;
780:
781: OpenClipboard (hwnd);
782:
783: iFormat = 0;
784: while (iFormat = EnumClipboardFormats(iFormat))
785: if ((iFormat == CF_UNICODETEXT) || (iFormat == CF_OEMTEXT) || (iFormat == CF_TEXT)) {
786:
787: pData = GetClipboardData (iFormat);
788:
789: switch (iFormat) {
790: case CF_UNICODETEXT:
791: nBytesSource = lstrlenW (pData) *2;
792: pSourceData= ManageMemory (MMALLOC, MMSOURCE, nBytesSource+2, pSourceData);
793: lstrcpyW ((LPVOID)pSourceData, pData);
794: gTypeSource = TYPEUNICODE;
795: break;
796:
797: case CF_OEMTEXT:
798: nBytesSource = lstrlenA (pData);
799: pSourceData= ManageMemory (MMALLOC, MMSOURCE, nBytesSource+1, pSourceData);
800: lstrcpyA (pSourceData, pData);
801: gTypeSource = TYPECODEPAGE;
802: giSourceCodePage = GetOEMCP();
803: break;
804:
805: case CF_TEXT:
806: nBytesSource = lstrlenA (pData);
807: pSourceData= ManageMemory (MMALLOC, MMSOURCE, nBytesSource+1, pSourceData);
808: lstrcpyA (pSourceData, pData);
809: gTypeSource = TYPECODEPAGE;
810: giSourceCodePage = GetACP();
811: break;
812:
813: default: break; // shouldn't get here
814: } /* end switch (iFormat) */
815:
816: SendMessage (hwnd, WMU_ADJUSTFORNEWSOURCE, 0,
817: (LPARAM)TEXT("<from Clipboard>"));
818:
819: break; /* break out of while loop. */
820: } /* end if iFormat */
821:
822:
823: CloseClipboard ();
824:
825: } break;
826:
827:
828:
829: /**********************************************************************\
830: * WM_COMMAND, MID_COPYDESTINATION
831: *
832: * Copy destination data to the clipboard.
833: \**********************************************************************/
834: case MID_COPYDESTINATION:
835: if (pDestinationData == NULL) return FALSE;
836:
837: OpenClipboard (hwnd);
838: EmptyClipboard();
839:
840: /* if source NOT unicode, then destination is, else look at dest CP */
841: if (gTypeSource != TYPEUNICODE)
842: SetClipboardData (CF_UNICODETEXT, pDestinationData);
843: else if (giDestinationCodePage == GetOEMCP())
844: SetClipboardData (CF_OEMTEXT, pDestinationData);
845: else
846: SetClipboardData (CF_TEXT, pDestinationData);
847:
848: CloseClipboard ();
849:
850: break;
851:
852:
853:
854: /******************************************************************\
855: * WM_COMMAND, MID_CONVERTNOW
856: *
857: * This is where the conversion actually takes place.
858: * In either case, make the call twice. Once to determine how
859: * much memory is needed, allocate space, and then make the call again.
860: *
861: * If conversion succeeds, it fills pDestinationData.
862: \******************************************************************/
863: case MID_CONVERTNOW: {
864: int nBytesNeeded, nWCharNeeded, nWCharSource;
865:
866:
867: if (nBytesSource == NODATA ) {
868: MessageBox (hwnd, TEXT("Load Source File"),MBTitle, MBFlags);
869: return 0;
870: }
871:
872:
873: /* Converting UNICODE -> giDestinationCodePage*/
874: if (gTypeSource == TYPEUNICODE) {
875:
876: nWCharSource = nBytesSource/2;
877:
878: /* Query the number of bytes required to store the Dest string */
879: nBytesNeeded = WideCharToMultiByte(giDestinationCodePage, gWCFlags,
880: (LPWSTR)pSourceData, nWCharSource,
881: NULL, 0,
882: glpDefaultChar, &gUsedDefaultChar);
883:
884: /* Allocate the required amount of space */
885: pDestinationData= ManageMemory (MMALLOC, MMDESTINATION, nBytesNeeded, pDestinationData);
886:
887: /* Do the conversion */
888: nBytesDestination = WideCharToMultiByte(giDestinationCodePage, gWCFlags,
889: (LPWSTR)pSourceData, nWCharSource,
890: pDestinationData, nBytesNeeded, glpDefaultChar, &gUsedDefaultChar);
891: }
892:
893:
894: /* converting giSourceCodePage -> UNICODE */
895: else if (gTypeSource == TYPECODEPAGE) {
896:
897: /* Query the number of WChar required to store the Dest string */
898: nWCharNeeded = MultiByteToWideChar(giSourceCodePage, gMBFlags,
899: pSourceData, nBytesSource, NULL, 0 );
900:
901: /* Allocate the required amount of space */
902: pDestinationData= ManageMemory (MMALLOC, MMDESTINATION, nWCharNeeded*2, pDestinationData);
903:
904: /* Do the conversion */
905: nWCharNeeded = MultiByteToWideChar(giSourceCodePage, gMBFlags,
906: pSourceData, nBytesSource,
907: (LPWSTR)pDestinationData, nWCharNeeded);
908:
909: /* MultiByteToWideChar returns # WCHAR, so multiply by 2 */
910: nBytesDestination = 2*nWCharNeeded ;
911: } else {
912: MessageBox (hwnd, TEXT("Source type unknown.\n Specify Source Options"),MBTitle, MBFlags);
913: return 0;
914: }
915:
916:
917: /* code common to all conversions... */
918: SetWindowText (hwndName1, TEXT("Data not saved yet!!"));
919: wsprintf (buffer, szNBytes, nBytesDestination);
920: SetWindowText (hwndSize1, buffer);
921: SetWindowText (hwndByteOrder1, szBlank);
922:
923:
924: /* Throw up "Save as" dialog to help the user along.
925: * They can always <esc> if need be.
926: */
927: SendMessage (hwnd, WM_COMMAND, MID_SAVEAS, 0);
928:
929: } break; /* end case BID_CONVERT */
930:
931:
932:
933: /******************************************************************\
934: * WM_COMMAND, BID_VIEWSOURCE
935: *
936: \******************************************************************/
937: case BID_VIEWSOURCE:
938: if (gTypeSource == TYPEUNICODE)
939: DialogBoxW (hInst, L"ShowTextDlg", hwnd, (DLGPROC)ViewSourceProc);
940: else
941: DialogBoxA (hInst, "ShowTextDlg", hwnd, (DLGPROC)ViewSourceProc);
942: break;
943:
944: /******************************************************************\
945: * WM_COMMAND, BID_VIEWDESTINATION
946: *
947: \******************************************************************/
948: case BID_VIEWDESTINATION:
949: if (gTypeSource == TYPEUNICODE)
950: DialogBoxA (hInst, "ShowTextDlg", hwnd, (DLGPROC)ViewDestinationProc);
951: else
952: DialogBoxW (hInst, L"ShowTextDlg", hwnd, (DLGPROC)ViewDestinationProc);
953: break;
954:
955:
956:
957: /******************************************************************\
958: * WM_COMMAND, MID_SOURCEOPT
959: *
960: * Allows user to change interpretation options for the source data.
961: *
962: * Put up appropriate dialog box, and reset window text in response.
963: \******************************************************************/
964: case MID_SOURCEOPT:
965: if (DialogBox (hInst, TEXT("DataOptionsDlg"), hwnd, (DLGPROC)SourceOptionsProc)) {
966: SendMessage (hwnd, WMU_SETTYPESTRINGS, 0,0);
967: SendMessage (hwnd, WM_COMMAND, MID_CLEARDESTINATION, 0);
968: }
969: break;
970:
971: /******************************************************************\
972: * WM_COMMAND, MID_DESTINATIONOPT
973: *
974: * Allows user to change options for destination data.
975: *
976: * Put up appropriate dialog box, and reset window text in response.
977: \******************************************************************/
978: case MID_DESTINATIONOPT:
979: if (DialogBox (hInst, TEXT("DataOptionsDlg"), hwnd, (DLGPROC)DestinationOptionsProc)) {
980: SendMessage (hwnd, WMU_SETTYPESTRINGS, 0,0);
981: SendMessage (hwnd, WM_COMMAND, MID_CLEARDESTINATION, 0);
982: }
983: break;
984:
985: /******************************************************************\
986: * WM_COMMAND, MID_CONVERSIONOPT
987: *
988: \******************************************************************/
989: case MID_CONVERSIONOPT:
990: if (DialogBox (hInst, TEXT("ConversionOptionsDlg"), hwnd, (DLGPROC)ConversionOptionsProc)) {
991: SendMessage (hwnd, WM_COMMAND, MID_CLEARDESTINATION, 0);
992: }
993: break;
994:
995:
996:
997: /******************************************************************\
998: * WM_COMMAND, MID_SWAPSOURCE
999: *
1000: * Allows user to reverse byte order of data.
1001: *
1002: \******************************************************************/
1003: case MID_SWAPSOURCE: {
1004: int i, end;
1005: BYTE temp;
1006:
1007: if (pSourceData == NULL) return FALSE;
1008:
1009: end = nBytesSource - 2;
1010: for (i = 0; i<= end; i+=2) {
1011: temp = pSourceData[i];
1012: pSourceData[i] = pSourceData[i+1];
1013: pSourceData[i+1] = temp;
1014: }
1015:
1016: if (GetWindowTextLength (hwndByteOrder0) == 0)
1017: SetWindowText (hwndByteOrder0, szByteOrderReversed);
1018: else
1019: SetWindowText (hwndByteOrder0, szBlank);
1020:
1021: /* Since source is different, invalidate Destination data. */
1022: SendMessage (hwnd, WM_COMMAND, MID_CLEARDESTINATION, 0);
1023:
1024: } break;
1025:
1026:
1027:
1028: /******************************************************************\
1029: * WM_COMMAND, MID_SWAPDESTINATION
1030: *
1031: * Allows user to reverse byte order of data.
1032: *
1033: \******************************************************************/
1034: case MID_SWAPDESTINATION: {
1035: int i, end;
1036: BYTE temp;
1037:
1038: if (pDestinationData == NULL) return FALSE;
1039:
1040: end = nBytesDestination - 2;
1041: for (i = 0; i<= end; i+=2) {
1042: temp = pDestinationData[i];
1043: pDestinationData[i] = pDestinationData[i+1];
1044: pDestinationData[i+1] = temp;
1045: }
1046:
1047: if (GetWindowTextLength (hwndByteOrder1) == 0)
1048: SetWindowText (hwndByteOrder1, szByteOrderReversed);
1049: else
1050: SetWindowText (hwndByteOrder1, szBlank);
1051:
1052: } break;
1053:
1054:
1055: /**********************************************************************\
1056: * WM_COMMAND, MID_CLEARDESTINATION
1057: *
1058: * Clear the destination information. May cause data to be lost.
1059: \**********************************************************************/
1060: case MID_CLEARDESTINATION:
1061: SetWindowText (hwndSize1, szBlank);
1062: SetWindowText (hwndName1, szBlank);
1063: SetWindowText (hwndByteOrder1, szBlank);
1064: pDestinationData= ManageMemory (MMFREE, MMDESTINATION, 0, pDestinationData);
1065: break;
1066:
1067:
1068: /**********************************************************************\
1069: * WM_COMMAND, MID_CLEARSOURCE
1070: *
1071: * Clear the SOURCE information. May cause data to be lost.
1072: \**********************************************************************/
1073: case MID_CLEARSOURCE:
1074: SetWindowText (hwndSize0, szBlank);
1075: SetWindowText (hwndName0, szBlank);
1076: SetWindowText (hwndByteOrder0, szBlank);
1077: pSourceData= ManageMemory (MMFREE, MMSOURCE, 0, pSourceData);
1078: break;
1079:
1080:
1081:
1082:
1083:
1084: /******************************************************************\
1085: * WM_COMMAND, MID_INSTALLTABLES
1086: *
1087: \******************************************************************/
1088: case MID_INSTALLTABLES:
1089: DialogBox (hInst, TEXT("InstallTableDlg"), hwnd, (DLGPROC)InstallTableProc);
1090: break;
1091:
1092:
1093:
1094:
1095: /* Simply call WinHelp to display the OnLine help file. */
1096: case MID_HELP:
1097: WinHelp( hwnd, szHelpPathName, HELP_INDEX, (DWORD) NULL );
1098: break;
1099:
1100:
1101: /* No-op Window procedure to simply display the dialog box. */
1102: case MID_ABOUT:
1103: DialogBox (hInst, TEXT("aboutBox"), hwnd, (DLGPROC) AboutProc);
1104: break;
1105:
1106: /* Just close the window. */
1107: case MID_EXIT:
1108: PostMessage (hwnd, WM_CLOSE, 0,0);
1109: break;
1110:
1111:
1112:
1113:
1114: } /* end switch (LOWORD(wParam)) */
1115: break; /* end WM_COMMAND */
1116:
1117:
1118:
1119: default: break;
1120: } /* end switch */
1121:
1122: return (DefWindowProc(hwnd, message, wParam, lParam));
1123: }
1124:
1125:
1126:
1127:
1128:
1129: /**************************************************************************\
1130: *
1131: * function: IsUnicode()
1132: *
1133: * HACK... eventually use a proper function for IsUnicode
1134: * Use function from unipad?
1135: *
1136: \**************************************************************************/
1137: BOOL IsUnicode (PBYTE pb)
1138: {
1139: return (IsBOM (pb));
1140: }
1141:
1142:
1143:
1144: /**************************************************************************\
1145: *
1146: * function: IsBOM()
1147: *
1148: * true iff pb points to a Byte Order Mark.
1149: *
1150: \**************************************************************************/
1151: BOOL IsBOM (PBYTE pb)
1152: {
1153: if ((*pb == 0xFF) & (*(pb+1) == 0xFE)) // BOM
1154: return TRUE;
1155: else
1156: return FALSE;
1157: }
1158:
1159:
1160: /**************************************************************************\
1161: *
1162: * function: IsRBOM()
1163: *
1164: * true iff pb points to a reversed Byte Order Mark.
1165: *
1166: \**************************************************************************/
1167: BOOL IsRBOM (PBYTE pb)
1168: {
1169: if ((*pb == 0xFE) & (*(pb+1) == 0xFF)) // RBOM
1170: return TRUE;
1171: else
1172: return FALSE;
1173: }
1174:
1175:
1176:
1177:
1178: /**************************************************************************\
1179: *
1180: * function: framechildwindow()
1181: *
1182: * Simply draw a 3D frame around child window.
1183: *
1184: \**************************************************************************/
1185: VOID framechildwindow (HDC hdc, HWND hwndParent, HWND hwndChild)
1186: {
1187: RECT rect;
1188:
1189: GetWindowRect (hwndChild, &rect);
1190:
1191: /* minor hack... assumes RECT is two points, right field starting first */
1192: ScreenToClient (hwndParent, (LPPOINT)&rect);
1193: ScreenToClient (hwndParent, (LPPOINT)&(rect.right));
1194:
1195: InflateRect (&rect, 1, 1);
1196: FrameRect (hdc, &rect, GetStockObject (GRAY_BRUSH));
1197: InflateRect (&rect, -1, -1);
1198: SelectObject (hdc, GetStockObject (WHITE_PEN));
1199: MoveToEx (hdc, rect.right, rect.top, NULL);
1200: LineTo (hdc,rect.right, rect.bottom);
1201: LineTo (hdc,rect.left, rect.bottom);
1202:
1203: return;
1204: }
1205:
1206:
1207: /**************************************************************************\
1208: *
1209: * function: underlinechildwindow()
1210: *
1211: * Underline child window.
1212: *
1213: \**************************************************************************/
1214: VOID underlinechildwindow (HDC hdc, HWND hwndParent, HWND hwndChild)
1215: {
1216: RECT rect;
1217:
1218: GetWindowRect (hwndChild, &rect);
1219:
1220: /* minor hack... assumes RECT is two points, right field starting first */
1221: ScreenToClient (hwndParent, (LPPOINT)&rect);
1222: ScreenToClient (hwndParent, (LPPOINT)&(rect.right));
1223:
1224: InflateRect (&rect, 1, 1);
1225: rect.top = rect.bottom-1;
1226: FrameRect (hdc, &rect, GetStockObject (GRAY_BRUSH));
1227: SelectObject (hdc, GetStockObject (WHITE_PEN));
1228: MoveToEx (hdc, rect.right, rect.bottom, NULL);
1229: LineTo (hdc,rect.left, rect.bottom);
1230:
1231: return;
1232: }
1233:
1234:
1235:
1236:
1237:
1238:
1239:
1240: /**************************************************************************\
1241: *
1242: * function: createwindows()
1243: *
1244: * Create the child windows and pass the handles back in parameters.
1245: * Each Window is created relative to (inside of) prect.
1246: * top is a spacial pointer to the Y coordinate of the next window.
1247: *
1248: \**************************************************************************/
1249: VOID createwindows(PRECT prect,
1250: HWND hwndParent,
1251: HWND* hwndLabel,
1252: HWND* hwndName,
1253: HWND* hwndSize,
1254: HWND* hwndCodePage,
1255: HWND* hwndByteOrder,
1256: HWND* hwndButton)
1257: {
1258: int top;
1259:
1260: top = prect->top;
1261: *hwndLabel = CreateWindow(
1262: TEXT("STATIC"),
1263: szBlank,
1264: WS_CHILD | WS_VISIBLE | SS_CENTER,
1265: prect->left,
1266: top,
1267: prect->right - prect->left,
1268: WHEIGHT,
1269: hwndParent, NULL, hInst, 0);
1270:
1271: top += WHEIGHT*5/2;
1272: *hwndName = CreateWindow(
1273: TEXT("STATIC"),
1274: szBlank,
1275: WS_CHILD | WS_VISIBLE | SS_RIGHT,
1276: prect->left,
1277: top,
1278: prect->right - prect->left,
1279: WHEIGHT,
1280: hwndParent, NULL, hInst, 0);
1281:
1282: top += WHEIGHT*2;
1283: *hwndSize = CreateWindow(
1284: TEXT("STATIC"),
1285: szBlank,
1286: WS_CHILD | WS_VISIBLE | SS_LEFT,
1287: prect->left,
1288: top,
1289: (prect->right - prect->left) *3/4,
1290: WHEIGHT,
1291: hwndParent, NULL, hInst, 0);
1292:
1293: top += WHEIGHT*2;
1294: *hwndCodePage = CreateWindow(
1295: TEXT("STATIC"),
1296: szBlank,
1297: WS_CHILD | WS_VISIBLE | SS_LEFT,
1298: prect->left,
1299: top,
1300: (prect->right - prect->left) *3/4,
1301: WHEIGHT,
1302: hwndParent, NULL, hInst, 0);
1303:
1304: top += WHEIGHT*2;
1305: *hwndByteOrder = CreateWindow(
1306: TEXT("STATIC"),
1307: szBlank,
1308: WS_CHILD | WS_VISIBLE | SS_LEFT,
1309: prect->left,
1310: top,
1311: (prect->right - prect->left) *3/4,
1312: WHEIGHT,
1313: hwndParent, NULL, hInst, 0);
1314:
1315: top += WHEIGHT*2;
1316: *hwndButton = CreateWindow(
1317: TEXT("BUTTON"),
1318: TEXT("ViewText"),
1319: WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
1320: prect->left,
1321: top,
1322: prect->right - prect->left,
1323: WHEIGHT*9/7,
1324: hwndParent, NULL, hInst, 0);
1325:
1326: return;
1327: }
1328:
1329:
1330: /**************************************************************************\
1331: *
1332: * function: ManageMemory()
1333: *
1334: * Do all memory management here for the source and destination pointers.
1335: * We also enable/disable the "View..." buttons to reflect existence of data.
1336: *
1337: *
1338: * PARAMETERS
1339: *
1340: * message : {MMALLOC, MMFREE}
1341: * Alloc when requested by MMALLOC, and free the existing, passed in, pointer.
1342: * Free when requested by MMFREE.
1343: * sourcedestination : {MMSOURCE, MMDESTINATION}
1344: * nBytes - number to alloc on MMALLOC messages.
1345: * p - old pointer to be freed.
1346: *
1347: *
1348: * GLOBALS
1349: *
1350: * hwndButton0, hwndButton1
1351: *
1352: \**************************************************************************/
1353: LPVOID ManageMemory (UINT message, UINT sourcedestination, DWORD nBytes, LPVOID p)
1354: {
1355: switch (message) {
1356: case MMFREE :
1357: if (sourcedestination == MMSOURCE)
1358: EnableWindow (hwndButton0, FALSE);
1359: else if (sourcedestination == MMDESTINATION)
1360: EnableWindow (hwndButton1, FALSE);
1361:
1362: if (p != NULL) GlobalFree (GlobalHandle (p));
1363: return NULL;
1364: break;
1365:
1366: case MMALLOC :
1367: if (sourcedestination == MMSOURCE)
1368: EnableWindow (hwndButton0, TRUE);
1369: else if (sourcedestination == MMDESTINATION)
1370: EnableWindow (hwndButton1, TRUE);
1371:
1372: if (p != NULL) GlobalFree (GlobalHandle (p));
1373: p = (LPVOID) GlobalAlloc (GPTR, nBytes);
1374: return p;
1375: break;
1376:
1377: } /* end switch (message) */
1378: return NULL;
1379: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.