|
|
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:
1.1.1.2 ! root 589: /* Allocate space for string, including potential UNICODE_NULL */
! 590: pSourceData = ManageMemory (MMALLOC, MMSOURCE, nBytesSource +2, pSourceData);
1.1 root 591: if (pSourceData == NULL) {
592: CloseHandle (hFile);
593: return 0;
594: }
595:
596: /* first read two bytes and look for BOM */
597: if (!ReadFile (hFile, pSourceData,SIZEOFBOM, &nBytesRead, NULL)) {
598: MessageBox (hwnd, TEXT("ReadFile() failed."),MBTitle, MBFlags);
599: CloseHandle (hFile);
600: pSourceData = ManageMemory (MMFREE, MMSOURCE, 0, pSourceData);
601: return 0;
602: }
603:
604:
605:
606: /* If file begins with BOM, then we know the type,
607: * we'll decrement the number of bytes by two,
608: * and read the rest of the data.
609: */
610: if (IsBOM (pSourceData)) {
611: gTypeSource = TYPEUNICODE;
612: nBytesSource -=SIZEOFBOM;
613:
614: /* If file begins with Reverse BOM, then we know the type,
615: * we'll decrement the number of bytes by two,
616: * and read the rest of the data, and post a message so
617: * that we know to swap the order later.
618: */
619: } else if (IsRBOM (pSourceData)) {
620: gTypeSource = TYPEUNICODE;
621: nBytesSource -=SIZEOFBOM;
622: MessageBox (hwnd, TEXT("Reverse byte order mark detected.\n Automatically swapping byte order."),MBTitle, MBFlags);
623: PostMessage (hwnd, WM_COMMAND, MID_SWAPSOURCE, 0);
624:
625: /* Oops, does not begin with BOM.
626: * Reset file pointer, and read data.
627: */
628: } else {
629: gTypeSource = TYPEUNKNOWN;
630: SetFilePointer (hFile, -SIZEOFBOM, NULL, FILE_CURRENT);
631: }
632:
633:
634:
635: /* try to read all of it into memory */
636: if (!ReadFile (hFile, pSourceData,nBytesSource, &nBytesRead, NULL)) {
637: MessageBox (hwnd, TEXT("ReadFile() failed."),MBTitle, MBFlags);
638: CloseHandle (hFile);
639: pSourceData = ManageMemory (MMFREE, MMSOURCE, 0, pSourceData);
640: return 0;
641: }
642:
643: CloseHandle (hFile);
644:
645: /* If we don't know the file type at this point,
646: * try to determine if it is unicode.
647: */
648: if (gTypeSource == TYPEUNKNOWN) {
1.1.1.2 ! root 649: if (IsUnicode (pSourceData)) {
1.1 root 650: gTypeSource = TYPEUNICODE;
1.1.1.2 ! root 651: pSourceData[nBytesSource] = 0; // UNICODE_NULL
! 652: pSourceData[nBytesSource+1] = 0;
! 653: } else {
1.1 root 654: gTypeSource = TYPECODEPAGE;
1.1.1.2 ! root 655: pSourceData[nBytesSource] = 0;
! 656: }
1.1 root 657: }
658:
659: SendMessage (hwnd, WMU_ADJUSTFORNEWSOURCE, 0, (LPARAM)szFile);
660:
661:
662:
663: } break; /* end case MID_OPEN */
664:
665:
666:
667: /******************************************************************\
668: * WM_COMMAND, MID_SAVEAS
669: *
670: * Put up common dialog, try to open file, and write data to it.
671: \******************************************************************/
672: case MID_SAVEAS: {
673: HANDLE hFile;
674: DWORD nBytesRead;
675: TCHAR szFile[MAX_PATH],szFileTitle[MAX_PATH];
676:
677: if (nBytesDestination == NODATA ) {
678: MessageBox (hwnd, TEXT("No text to save"),MBTitle, MBFlags);
679: return 0;
680: }
681:
682:
683: /* Set up the structure for the GetSaveFileName
684: * common dialog.
685: */
686: {
687: OPENFILENAME OpenFileName;
688: /* buffers for the file names. */
689:
690: wsprintf (szFile, szBlank);
691: wsprintf (szFileTitle, szBlank);
692:
693: OpenFileName.lStructSize = sizeof(OPENFILENAME);
694: OpenFileName.hwndOwner = hwnd;
695: OpenFileName.hInstance = (HANDLE) hInst;
696: OpenFileName.lpstrFilter = szFilter;
697: OpenFileName.lpstrCustomFilter = NULL;
698: OpenFileName.nMaxCustFilter = 0L;
699: OpenFileName.nFilterIndex = 1L;
700: OpenFileName.lpstrFile = szFile;
701: OpenFileName.nMaxFile = MAX_PATH;
702: OpenFileName.lpstrFileTitle = szFileTitle;
703: OpenFileName.nMaxFileTitle = MAX_PATH;
704: OpenFileName.lpstrInitialDir = NULL;
705: OpenFileName.lpstrTitle = TEXT("Save As");
706:
707: OpenFileName.nFileOffset = 0;
708: OpenFileName.nFileExtension = 0;
709: OpenFileName.lpstrDefExt = NULL;
710:
711: OpenFileName.lCustData = 0;
712: OpenFileName.lpfnHook = NULL;
713: OpenFileName.lpTemplateName = NULL;
714:
715: OpenFileName.Flags = OFN_HIDEREADONLY;
716:
717: if (!GetSaveFileName(&OpenFileName)) return 0;
718: }
719:
720:
721: /* User has filled in the file information.
722: * Try to open that file for writing.
723: */
724: hFile = CreateFile(szFile,
725: GENERIC_WRITE,
726: 0,
727: NULL,
728: CREATE_ALWAYS,
729: FILE_ATTRIBUTE_NORMAL,
730: NULL);
731:
732: if (hFile == INVALID_HANDLE_VALUE) {
733: MessageBox (hwnd, TEXT("CreateFile() failed."),MBTitle, MBFlags);
734: return 0;
735: }
736:
737:
738: /* if destination is unicode, try to write BOM first.
739: * unless the bytes have been swapped
740: * (criterion: hwndByteOrder contains text)
741: * in which case, write a Reverse Byte Order Mark.
742: */
743: if (gTypeSource == TYPECODEPAGE) {
744: if (GetWindowTextLength (hwndByteOrder1) == 0) {
745:
746: if (!WriteFile (hFile, szBOM, SIZEOFBOM, &nBytesRead, NULL)) {
747: MessageBox (hwnd, TEXT("WriteFile() failed."),MBTitle, MBFlags);
748: CloseHandle (hFile);
749: return 0;
750: }
751:
752: }else {
753: if (!WriteFile (hFile, szRBOM, SIZEOFBOM, &nBytesRead, NULL)) {
754: MessageBox (hwnd, TEXT("WriteFile() failed."),MBTitle, MBFlags);
755: CloseHandle (hFile);
756: return 0;
757: }
758:
759: }
760: }
761:
762:
763: /* try to write all of it into memory */
764: if (!WriteFile (hFile, pDestinationData,nBytesDestination, &nBytesRead, NULL)) {
765: MessageBox (hwnd, TEXT("WriteFile() failed."),MBTitle, MBFlags);
766: CloseHandle (hFile);
767: return 0;
768: }
769:
770: SetWindowText (hwndName1, szFile);
771: CloseHandle (hFile);
772:
773: } break;
774:
775:
776: /**********************************************************************\
777: * WM_COMMAND, MID_PASTESOURCE
778: *
779: * Paste the clipboard's prefered data format into the source.
780: * Fills pSourceData.
781: \**********************************************************************/
782: case MID_PASTESOURCE: {
783: UINT iFormat;
784: PVOID pData;
785:
786: OpenClipboard (hwnd);
787:
788: iFormat = 0;
789: while (iFormat = EnumClipboardFormats(iFormat))
790: if ((iFormat == CF_UNICODETEXT) || (iFormat == CF_OEMTEXT) || (iFormat == CF_TEXT)) {
791:
792: pData = GetClipboardData (iFormat);
793:
794: switch (iFormat) {
795: case CF_UNICODETEXT:
796: nBytesSource = lstrlenW (pData) *2;
797: pSourceData= ManageMemory (MMALLOC, MMSOURCE, nBytesSource+2, pSourceData);
798: lstrcpyW ((LPVOID)pSourceData, pData);
799: gTypeSource = TYPEUNICODE;
800: break;
801:
802: case CF_OEMTEXT:
803: nBytesSource = lstrlenA (pData);
804: pSourceData= ManageMemory (MMALLOC, MMSOURCE, nBytesSource+1, pSourceData);
805: lstrcpyA (pSourceData, pData);
806: gTypeSource = TYPECODEPAGE;
807: giSourceCodePage = GetOEMCP();
808: break;
809:
810: case CF_TEXT:
811: nBytesSource = lstrlenA (pData);
812: pSourceData= ManageMemory (MMALLOC, MMSOURCE, nBytesSource+1, pSourceData);
813: lstrcpyA (pSourceData, pData);
814: gTypeSource = TYPECODEPAGE;
815: giSourceCodePage = GetACP();
816: break;
817:
818: default: break; // shouldn't get here
819: } /* end switch (iFormat) */
820:
821: SendMessage (hwnd, WMU_ADJUSTFORNEWSOURCE, 0,
822: (LPARAM)TEXT("<from Clipboard>"));
823:
824: break; /* break out of while loop. */
825: } /* end if iFormat */
826:
827:
828: CloseClipboard ();
829:
830: } break;
831:
832:
833:
834: /**********************************************************************\
835: * WM_COMMAND, MID_COPYDESTINATION
836: *
837: * Copy destination data to the clipboard.
838: \**********************************************************************/
839: case MID_COPYDESTINATION:
840: if (pDestinationData == NULL) return FALSE;
841:
842: OpenClipboard (hwnd);
843: EmptyClipboard();
844:
845: /* if source NOT unicode, then destination is, else look at dest CP */
846: if (gTypeSource != TYPEUNICODE)
847: SetClipboardData (CF_UNICODETEXT, pDestinationData);
848: else if (giDestinationCodePage == GetOEMCP())
849: SetClipboardData (CF_OEMTEXT, pDestinationData);
850: else
851: SetClipboardData (CF_TEXT, pDestinationData);
852:
853: CloseClipboard ();
854:
855: break;
856:
857:
858:
859: /******************************************************************\
860: * WM_COMMAND, MID_CONVERTNOW
861: *
862: * This is where the conversion actually takes place.
863: * In either case, make the call twice. Once to determine how
864: * much memory is needed, allocate space, and then make the call again.
865: *
866: * If conversion succeeds, it fills pDestinationData.
867: \******************************************************************/
868: case MID_CONVERTNOW: {
869: int nBytesNeeded, nWCharNeeded, nWCharSource;
870:
871:
872: if (nBytesSource == NODATA ) {
873: MessageBox (hwnd, TEXT("Load Source File"),MBTitle, MBFlags);
874: return 0;
875: }
876:
877:
878: /* Converting UNICODE -> giDestinationCodePage*/
879: if (gTypeSource == TYPEUNICODE) {
880:
881: nWCharSource = nBytesSource/2;
882:
883: /* Query the number of bytes required to store the Dest string */
884: nBytesNeeded = WideCharToMultiByte(giDestinationCodePage, gWCFlags,
885: (LPWSTR)pSourceData, nWCharSource,
886: NULL, 0,
887: glpDefaultChar, &gUsedDefaultChar);
888:
1.1.1.2 ! root 889: /* Allocate the required amount of space, including trailing NULL */
! 890: pDestinationData= ManageMemory (MMALLOC, MMDESTINATION, nBytesNeeded +1, pDestinationData);
1.1 root 891:
892: /* Do the conversion */
893: nBytesDestination = WideCharToMultiByte(giDestinationCodePage, gWCFlags,
894: (LPWSTR)pSourceData, nWCharSource,
895: pDestinationData, nBytesNeeded, glpDefaultChar, &gUsedDefaultChar);
1.1.1.2 ! root 896:
! 897: /* Null terminate string. */
! 898: pDestinationData[nBytesDestination] = 0;
1.1 root 899: }
900:
901:
902: /* converting giSourceCodePage -> UNICODE */
903: else if (gTypeSource == TYPECODEPAGE) {
904:
905: /* Query the number of WChar required to store the Dest string */
906: nWCharNeeded = MultiByteToWideChar(giSourceCodePage, gMBFlags,
907: pSourceData, nBytesSource, NULL, 0 );
908:
1.1.1.2 ! root 909: /* Allocate the required amount of space, including trailing NULL */
! 910: pDestinationData= ManageMemory (MMALLOC, MMDESTINATION, (nWCharNeeded +1)*2, pDestinationData);
1.1 root 911:
912: /* Do the conversion */
913: nWCharNeeded = MultiByteToWideChar(giSourceCodePage, gMBFlags,
914: pSourceData, nBytesSource,
915: (LPWSTR)pDestinationData, nWCharNeeded);
916:
917: /* MultiByteToWideChar returns # WCHAR, so multiply by 2 */
918: nBytesDestination = 2*nWCharNeeded ;
1.1.1.2 ! root 919:
! 920: /* Null terminate string. */
! 921: pDestinationData[nBytesDestination] = 0; // UNICODE_NULL
! 922: pDestinationData[nBytesDestination+1] = 0;
1.1 root 923: } else {
924: MessageBox (hwnd, TEXT("Source type unknown.\n Specify Source Options"),MBTitle, MBFlags);
925: return 0;
926: }
927:
928:
929: /* code common to all conversions... */
930: SetWindowText (hwndName1, TEXT("Data not saved yet!!"));
931: wsprintf (buffer, szNBytes, nBytesDestination);
932: SetWindowText (hwndSize1, buffer);
933: SetWindowText (hwndByteOrder1, szBlank);
934:
935:
936: /* Throw up "Save as" dialog to help the user along.
937: * They can always <esc> if need be.
938: */
939: SendMessage (hwnd, WM_COMMAND, MID_SAVEAS, 0);
940:
941: } break; /* end case BID_CONVERT */
942:
943:
944:
945: /******************************************************************\
946: * WM_COMMAND, BID_VIEWSOURCE
947: *
948: \******************************************************************/
949: case BID_VIEWSOURCE:
950: if (gTypeSource == TYPEUNICODE)
951: DialogBoxW (hInst, L"ShowTextDlg", hwnd, (DLGPROC)ViewSourceProc);
952: else
953: DialogBoxA (hInst, "ShowTextDlg", hwnd, (DLGPROC)ViewSourceProc);
954: break;
955:
956: /******************************************************************\
957: * WM_COMMAND, BID_VIEWDESTINATION
958: *
959: \******************************************************************/
960: case BID_VIEWDESTINATION:
961: if (gTypeSource == TYPEUNICODE)
962: DialogBoxA (hInst, "ShowTextDlg", hwnd, (DLGPROC)ViewDestinationProc);
963: else
964: DialogBoxW (hInst, L"ShowTextDlg", hwnd, (DLGPROC)ViewDestinationProc);
965: break;
966:
967:
968:
969: /******************************************************************\
970: * WM_COMMAND, MID_SOURCEOPT
971: *
972: * Allows user to change interpretation options for the source data.
973: *
974: * Put up appropriate dialog box, and reset window text in response.
975: \******************************************************************/
976: case MID_SOURCEOPT:
977: if (DialogBox (hInst, TEXT("DataOptionsDlg"), hwnd, (DLGPROC)SourceOptionsProc)) {
978: SendMessage (hwnd, WMU_SETTYPESTRINGS, 0,0);
979: SendMessage (hwnd, WM_COMMAND, MID_CLEARDESTINATION, 0);
980: }
981: break;
982:
983: /******************************************************************\
984: * WM_COMMAND, MID_DESTINATIONOPT
985: *
986: * Allows user to change options for destination data.
987: *
988: * Put up appropriate dialog box, and reset window text in response.
989: \******************************************************************/
990: case MID_DESTINATIONOPT:
991: if (DialogBox (hInst, TEXT("DataOptionsDlg"), hwnd, (DLGPROC)DestinationOptionsProc)) {
992: SendMessage (hwnd, WMU_SETTYPESTRINGS, 0,0);
993: SendMessage (hwnd, WM_COMMAND, MID_CLEARDESTINATION, 0);
994: }
995: break;
996:
997: /******************************************************************\
998: * WM_COMMAND, MID_CONVERSIONOPT
999: *
1000: \******************************************************************/
1001: case MID_CONVERSIONOPT:
1002: if (DialogBox (hInst, TEXT("ConversionOptionsDlg"), hwnd, (DLGPROC)ConversionOptionsProc)) {
1003: SendMessage (hwnd, WM_COMMAND, MID_CLEARDESTINATION, 0);
1004: }
1005: break;
1006:
1007:
1008:
1009: /******************************************************************\
1010: * WM_COMMAND, MID_SWAPSOURCE
1011: *
1012: * Allows user to reverse byte order of data.
1013: *
1014: \******************************************************************/
1015: case MID_SWAPSOURCE: {
1016: int i, end;
1017: BYTE temp;
1018:
1019: if (pSourceData == NULL) return FALSE;
1020:
1021: end = nBytesSource - 2;
1022: for (i = 0; i<= end; i+=2) {
1023: temp = pSourceData[i];
1024: pSourceData[i] = pSourceData[i+1];
1025: pSourceData[i+1] = temp;
1026: }
1027:
1028: if (GetWindowTextLength (hwndByteOrder0) == 0)
1029: SetWindowText (hwndByteOrder0, szByteOrderReversed);
1030: else
1031: SetWindowText (hwndByteOrder0, szBlank);
1032:
1033: /* Since source is different, invalidate Destination data. */
1034: SendMessage (hwnd, WM_COMMAND, MID_CLEARDESTINATION, 0);
1035:
1036: } break;
1037:
1038:
1039:
1040: /******************************************************************\
1041: * WM_COMMAND, MID_SWAPDESTINATION
1042: *
1043: * Allows user to reverse byte order of data.
1044: *
1045: \******************************************************************/
1046: case MID_SWAPDESTINATION: {
1047: int i, end;
1048: BYTE temp;
1049:
1050: if (pDestinationData == NULL) return FALSE;
1051:
1052: end = nBytesDestination - 2;
1053: for (i = 0; i<= end; i+=2) {
1054: temp = pDestinationData[i];
1055: pDestinationData[i] = pDestinationData[i+1];
1056: pDestinationData[i+1] = temp;
1057: }
1058:
1059: if (GetWindowTextLength (hwndByteOrder1) == 0)
1060: SetWindowText (hwndByteOrder1, szByteOrderReversed);
1061: else
1062: SetWindowText (hwndByteOrder1, szBlank);
1063:
1064: } break;
1065:
1066:
1067: /**********************************************************************\
1068: * WM_COMMAND, MID_CLEARDESTINATION
1069: *
1070: * Clear the destination information. May cause data to be lost.
1071: \**********************************************************************/
1072: case MID_CLEARDESTINATION:
1073: SetWindowText (hwndSize1, szBlank);
1074: SetWindowText (hwndName1, szBlank);
1075: SetWindowText (hwndByteOrder1, szBlank);
1076: pDestinationData= ManageMemory (MMFREE, MMDESTINATION, 0, pDestinationData);
1077: break;
1078:
1079:
1080: /**********************************************************************\
1081: * WM_COMMAND, MID_CLEARSOURCE
1082: *
1083: * Clear the SOURCE information. May cause data to be lost.
1084: \**********************************************************************/
1085: case MID_CLEARSOURCE:
1086: SetWindowText (hwndSize0, szBlank);
1087: SetWindowText (hwndName0, szBlank);
1088: SetWindowText (hwndByteOrder0, szBlank);
1089: pSourceData= ManageMemory (MMFREE, MMSOURCE, 0, pSourceData);
1090: break;
1091:
1092:
1093:
1094:
1095:
1096: /******************************************************************\
1097: * WM_COMMAND, MID_INSTALLTABLES
1098: *
1099: \******************************************************************/
1100: case MID_INSTALLTABLES:
1101: DialogBox (hInst, TEXT("InstallTableDlg"), hwnd, (DLGPROC)InstallTableProc);
1102: break;
1103:
1104:
1105:
1106:
1107: /* Simply call WinHelp to display the OnLine help file. */
1108: case MID_HELP:
1109: WinHelp( hwnd, szHelpPathName, HELP_INDEX, (DWORD) NULL );
1110: break;
1111:
1112:
1113: /* No-op Window procedure to simply display the dialog box. */
1114: case MID_ABOUT:
1115: DialogBox (hInst, TEXT("aboutBox"), hwnd, (DLGPROC) AboutProc);
1116: break;
1117:
1118: /* Just close the window. */
1119: case MID_EXIT:
1120: PostMessage (hwnd, WM_CLOSE, 0,0);
1121: break;
1122:
1123:
1124:
1125:
1126: } /* end switch (LOWORD(wParam)) */
1127: break; /* end WM_COMMAND */
1128:
1129:
1130:
1131: default: break;
1132: } /* end switch */
1133:
1134: return (DefWindowProc(hwnd, message, wParam, lParam));
1135: }
1136:
1137:
1138:
1139:
1140:
1141: /**************************************************************************\
1142: *
1143: * function: IsUnicode()
1144: *
1145: * HACK... eventually use a proper function for IsUnicode
1146: * Use function from unipad?
1147: *
1148: \**************************************************************************/
1149: BOOL IsUnicode (PBYTE pb)
1150: {
1151: return (IsBOM (pb));
1152: }
1153:
1154:
1155:
1156: /**************************************************************************\
1157: *
1158: * function: IsBOM()
1159: *
1160: * true iff pb points to a Byte Order Mark.
1161: *
1162: \**************************************************************************/
1163: BOOL IsBOM (PBYTE pb)
1164: {
1165: if ((*pb == 0xFF) & (*(pb+1) == 0xFE)) // BOM
1166: return TRUE;
1167: else
1168: return FALSE;
1169: }
1170:
1171:
1172: /**************************************************************************\
1173: *
1174: * function: IsRBOM()
1175: *
1176: * true iff pb points to a reversed Byte Order Mark.
1177: *
1178: \**************************************************************************/
1179: BOOL IsRBOM (PBYTE pb)
1180: {
1181: if ((*pb == 0xFE) & (*(pb+1) == 0xFF)) // RBOM
1182: return TRUE;
1183: else
1184: return FALSE;
1185: }
1186:
1187:
1188:
1189:
1190: /**************************************************************************\
1191: *
1192: * function: framechildwindow()
1193: *
1194: * Simply draw a 3D frame around child window.
1195: *
1196: \**************************************************************************/
1197: VOID framechildwindow (HDC hdc, HWND hwndParent, HWND hwndChild)
1198: {
1199: RECT rect;
1200:
1201: GetWindowRect (hwndChild, &rect);
1202:
1203: /* minor hack... assumes RECT is two points, right field starting first */
1204: ScreenToClient (hwndParent, (LPPOINT)&rect);
1205: ScreenToClient (hwndParent, (LPPOINT)&(rect.right));
1206:
1207: InflateRect (&rect, 1, 1);
1208: FrameRect (hdc, &rect, GetStockObject (GRAY_BRUSH));
1209: InflateRect (&rect, -1, -1);
1210: SelectObject (hdc, GetStockObject (WHITE_PEN));
1211: MoveToEx (hdc, rect.right, rect.top, NULL);
1212: LineTo (hdc,rect.right, rect.bottom);
1213: LineTo (hdc,rect.left, rect.bottom);
1214:
1215: return;
1216: }
1217:
1218:
1219: /**************************************************************************\
1220: *
1221: * function: underlinechildwindow()
1222: *
1223: * Underline child window.
1224: *
1225: \**************************************************************************/
1226: VOID underlinechildwindow (HDC hdc, HWND hwndParent, HWND hwndChild)
1227: {
1228: RECT rect;
1229:
1230: GetWindowRect (hwndChild, &rect);
1231:
1232: /* minor hack... assumes RECT is two points, right field starting first */
1233: ScreenToClient (hwndParent, (LPPOINT)&rect);
1234: ScreenToClient (hwndParent, (LPPOINT)&(rect.right));
1235:
1236: InflateRect (&rect, 1, 1);
1237: rect.top = rect.bottom-1;
1238: FrameRect (hdc, &rect, GetStockObject (GRAY_BRUSH));
1239: SelectObject (hdc, GetStockObject (WHITE_PEN));
1240: MoveToEx (hdc, rect.right, rect.bottom, NULL);
1241: LineTo (hdc,rect.left, rect.bottom);
1242:
1243: return;
1244: }
1245:
1246:
1247:
1248:
1249:
1250:
1251:
1252: /**************************************************************************\
1253: *
1254: * function: createwindows()
1255: *
1256: * Create the child windows and pass the handles back in parameters.
1257: * Each Window is created relative to (inside of) prect.
1258: * top is a spacial pointer to the Y coordinate of the next window.
1259: *
1260: \**************************************************************************/
1261: VOID createwindows(PRECT prect,
1262: HWND hwndParent,
1263: HWND* hwndLabel,
1264: HWND* hwndName,
1265: HWND* hwndSize,
1266: HWND* hwndCodePage,
1267: HWND* hwndByteOrder,
1268: HWND* hwndButton)
1269: {
1270: int top;
1271:
1272: top = prect->top;
1273: *hwndLabel = CreateWindow(
1274: TEXT("STATIC"),
1275: szBlank,
1276: WS_CHILD | WS_VISIBLE | SS_CENTER,
1277: prect->left,
1278: top,
1279: prect->right - prect->left,
1280: WHEIGHT,
1281: hwndParent, NULL, hInst, 0);
1282:
1283: top += WHEIGHT*5/2;
1284: *hwndName = CreateWindow(
1285: TEXT("STATIC"),
1286: szBlank,
1287: WS_CHILD | WS_VISIBLE | SS_RIGHT,
1288: prect->left,
1289: top,
1290: prect->right - prect->left,
1291: WHEIGHT,
1292: hwndParent, NULL, hInst, 0);
1293:
1294: top += WHEIGHT*2;
1295: *hwndSize = CreateWindow(
1296: TEXT("STATIC"),
1297: szBlank,
1298: WS_CHILD | WS_VISIBLE | SS_LEFT,
1299: prect->left,
1300: top,
1301: (prect->right - prect->left) *3/4,
1302: WHEIGHT,
1303: hwndParent, NULL, hInst, 0);
1304:
1305: top += WHEIGHT*2;
1306: *hwndCodePage = CreateWindow(
1307: TEXT("STATIC"),
1308: szBlank,
1309: WS_CHILD | WS_VISIBLE | SS_LEFT,
1310: prect->left,
1311: top,
1312: (prect->right - prect->left) *3/4,
1313: WHEIGHT,
1314: hwndParent, NULL, hInst, 0);
1315:
1316: top += WHEIGHT*2;
1317: *hwndByteOrder = CreateWindow(
1318: TEXT("STATIC"),
1319: szBlank,
1320: WS_CHILD | WS_VISIBLE | SS_LEFT,
1321: prect->left,
1322: top,
1323: (prect->right - prect->left) *3/4,
1324: WHEIGHT,
1325: hwndParent, NULL, hInst, 0);
1326:
1327: top += WHEIGHT*2;
1328: *hwndButton = CreateWindow(
1329: TEXT("BUTTON"),
1330: TEXT("ViewText"),
1331: WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
1332: prect->left,
1333: top,
1334: prect->right - prect->left,
1335: WHEIGHT*9/7,
1336: hwndParent, NULL, hInst, 0);
1337:
1338: return;
1339: }
1340:
1341:
1342: /**************************************************************************\
1343: *
1344: * function: ManageMemory()
1345: *
1346: * Do all memory management here for the source and destination pointers.
1347: * We also enable/disable the "View..." buttons to reflect existence of data.
1348: *
1349: *
1350: * PARAMETERS
1351: *
1352: * message : {MMALLOC, MMFREE}
1353: * Alloc when requested by MMALLOC, and free the existing, passed in, pointer.
1354: * Free when requested by MMFREE.
1355: * sourcedestination : {MMSOURCE, MMDESTINATION}
1356: * nBytes - number to alloc on MMALLOC messages.
1357: * p - old pointer to be freed.
1358: *
1359: *
1360: * GLOBALS
1361: *
1362: * hwndButton0, hwndButton1
1363: *
1364: \**************************************************************************/
1365: LPVOID ManageMemory (UINT message, UINT sourcedestination, DWORD nBytes, LPVOID p)
1366: {
1367: switch (message) {
1368: case MMFREE :
1369: if (sourcedestination == MMSOURCE)
1370: EnableWindow (hwndButton0, FALSE);
1371: else if (sourcedestination == MMDESTINATION)
1372: EnableWindow (hwndButton1, FALSE);
1373:
1374: if (p != NULL) GlobalFree (GlobalHandle (p));
1375: return NULL;
1376: break;
1377:
1378: case MMALLOC :
1379: if (sourcedestination == MMSOURCE)
1380: EnableWindow (hwndButton0, TRUE);
1381: else if (sourcedestination == MMDESTINATION)
1382: EnableWindow (hwndButton1, TRUE);
1383:
1384: if (p != NULL) GlobalFree (GlobalHandle (p));
1385: p = (LPVOID) GlobalAlloc (GPTR, nBytes);
1386: return p;
1387: break;
1388:
1389: } /* end switch (message) */
1390: return NULL;
1391: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.