home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sdktools / porttool / porttool.c < prev    next >
C/C++ Source or Header  |  1996-06-12  |  42KB  |  1,573 lines

  1.  
  2. /******************************************************************************\
  3. *       This is a part of the Microsoft Source Code Samples. 
  4. *       Copyright (C) 1993-96 Microsoft Corporation.
  5. *       All rights reserved. 
  6. *       This source code is only intended as a supplement to 
  7. *       Microsoft Development Tools and/or WinHelp documentation.
  8. *       See these sources for detailed information regarding the 
  9. *       Microsoft samples programs.
  10. \******************************************************************************/
  11.  
  12. #include "porttool.h"
  13. #include "port.h"
  14.  
  15. /* forward declarations of helper functions in this module */
  16. HWND   WINAPI StartInteractive (HANDLE, char *, int);
  17. HANDLE WINAPI StartBackground (HANDLE, HWND, char *);
  18. VOID   WINAPI InitializeMenu (HWND, HANDLE);
  19. LONG   WINAPI CommandHandler (HWND, UINT, LONG);
  20. int    WINAPI SetWrap (HWND);
  21. BOOL   WINAPI GetCmdLine (char *, char *, BOOL *, char *);
  22. int    WINAPI Save_YNC (HWND);
  23. VOID   WINAPI SetWindowTitle (HWND, char*);
  24. VOID   WINAPI GetEditSubString (HWND, PUINT, PUINT, char *);
  25.  
  26. UINT    uSearchMsg;
  27. HWND    hDlgPortStatus;
  28. HWND    hDlgPort;
  29.  
  30. DWORD   dwVersion=0; // Global variable to store current system version info
  31.  
  32.  
  33. /* test case static variables for background porting */
  34. HANDLE              hEvents[nBKPORTEVENTS];
  35. BKPORTFILESTRUCT    BkPort;
  36.  
  37.  
  38.  
  39. /* entry point ot this executable */
  40. int WINAPI WinMain (hInstance, hPrevInstance, lpCmdLine, nCmdShow)
  41.     HANDLE hInstance;
  42.     HANDLE hPrevInstance;
  43.     LPSTR  lpCmdLine;
  44.     int    nCmdShow;
  45. {
  46.     MSG        msg;
  47.     HWND       hWnd;
  48.     HANDLE     hAccel;
  49.     BOOL       bBkgnd = 0;
  50.     char       *lpszBuff = NULL;
  51.     char       *lpszCmdLine = NULL;
  52.     char       *lpCL;
  53.  
  54.  
  55.     /* previous instances do not exist in Win32 */
  56.     if (hPrevInstance)
  57.     return 0;
  58.  
  59.     /* Get OS version info, and store in a global variable */
  60.     dwVersion = GetVersion();
  61.  
  62.     lpszPortIniFilePath[0] = 0;
  63.  
  64.     /* parse and copy command line parameters to local memory */
  65.     lpCL = GetCommandLine ();
  66.     if (lpszCmdLine = (char *)LocalAlloc (LPTR, strlen (lpCL) + 1))
  67.     GetCmdLine (lpCL, lpszCmdLine, &bBkgnd, lpszPortIniFilePath);
  68.  
  69.     /* if /b switch, start background porting session */
  70.     if (bBkgnd)
  71.     {
  72.     /* invoke background port status dialog */
  73.     // MessageBox(NULL, "Backgroud Porting Disabled","Porttool",MB_OK);
  74.  
  75.     if (lpszPortIniFilePath[0] == 0 )
  76.     {
  77.        ErrorNotify (NULL, IDS_PORTFILEBACKMSG);
  78.        return FALSE;
  79.     }
  80.     else if ( ! InitPortData(lpszPortIniFilePath) )
  81.        ErrorNotify (NULL, IDS_PORTINITFAILED);
  82.  
  83.     if (!(hDlgPortStatus = StartBackground (hInstance, NULL, lpszCmdLine)))
  84.         return FALSE;
  85.     }
  86.  
  87.     /* start interactive porting session */
  88.     else
  89.     {
  90.     if (!(hWnd = StartInteractive (hInstance, lpszCmdLine, nCmdShow)))
  91.         return FALSE;
  92.     }
  93.  
  94.     /* free memory allocated for pCmdLine */
  95.     if (lpszCmdLine)
  96.     LocalFree ((HLOCAL)lpszCmdLine);
  97.  
  98.     /* load main accelerator table */
  99.     hAccel = LoadAccelerators (hInstance, MAKEINTRESOURCE (IDA_PORTTOOL));
  100.  
  101.     /* main window message loop */
  102.     while (GetMessage (&msg, NULL, 0, 0))
  103.     {
  104.     if ((!hDlgSearch     || !IsDialogMessage (hDlgSearch, &msg))     &&
  105.         (!hDlgPort       || !IsDialogMessage (hDlgPort, &msg))       &&
  106.         (!hDlgPortStatus || !IsDialogMessage (hDlgPortStatus, &msg)) &&
  107.         (!hAccel         || !TranslateAccelerator (hWnd, hAccel, &msg)))
  108.         {
  109.         TranslateMessage (&msg);
  110.         DispatchMessage (&msg);
  111.         }
  112.     }
  113.  
  114.     /* return success of application */
  115.     return TRUE;
  116. }
  117.  
  118.  
  119. //
  120. // Used only on FE versions to screen out vertical fonts
  121. //
  122.  
  123. BOOL APIENTRY ChooseFontHookProc(
  124.     HWND hDlg,              /* window handle of the dialog box */
  125.     UINT message,           /* type of message                 */
  126.     WPARAM wParam,          /* message-specific information    */
  127.     LPARAM lParam)
  128. {
  129.     switch (message) {
  130.     case WM_INITDIALOG:
  131.         {
  132.             LOGFONT lf;
  133.             char szFaceName[LF_FACESIZE];
  134.             UINT uiId, uiCount;
  135.  
  136.             uiCount = SendDlgItemMessage(hDlg, cmb1, CB_GETCOUNT, 0, 0L);
  137.             /* Delete vertical font */
  138.             for (uiId = 0; uiId < uiCount; uiId++) {
  139.                 SendDlgItemMessage(hDlg, cmb1, CB_GETLBTEXT,
  140.                                    uiId, (LPARAM)(LPSTR)szFaceName);
  141.                 if (szFaceName[0] == '@') {
  142.                     SendDlgItemMessage(hDlg, cmb1, CB_DELETESTRING, uiId, 0L);
  143.                     uiId--;
  144.                     uiCount--;
  145.                 }
  146.             }
  147.             /* Set selection current selected facename */
  148.             SendMessage(hDlg, WM_CHOOSEFONT_GETLOGFONT, 0, (LPARAM)(LPSTR)&lf);
  149.             uiId = SendDlgItemMessage(hDlg, cmb1, CB_FINDSTRING,
  150.                                      0, (LPARAM)(LPSTR)lf.lfFaceName);
  151.             SendDlgItemMessage(hDlg, cmb1, CB_SETCURSEL, uiId, 0L);
  152.         }
  153.         return (TRUE);
  154.         break;
  155.     }
  156.     return (FALSE);
  157. }
  158.  
  159.  
  160.  
  161. /* start background port status dialog */
  162. HANDLE WINAPI StartBackground (
  163.     HANDLE    hModule,
  164.     HWND      hWndParent,
  165.     char      *lpszCmdLine)
  166. {
  167.     return (CreateDialogParam (hModule,
  168.                    IDD_BKPORTDIALOG,
  169.                    hWndParent,
  170.                    BkPortDlgProc,
  171.                    (LPARAM)lpszCmdLine));
  172. }
  173.  
  174.  
  175. /* start interactive version of app */
  176. HWND WINAPI StartInteractive (
  177.     HANDLE    hInstance,
  178.     char      *lpszCmdLine,
  179.     int       nCmdShow)
  180.     {
  181.     WNDCLASS   wc;
  182.     char       lpszClass[MAX_PATH];
  183.     HWND       hWnd;
  184.     char       lpszFileName[MAX_PATH];
  185.  
  186.     /* load resources strings */
  187.     LoadString (hInstance, IDS_APPNAME, lpszClass, sizeof (lpszClass));
  188.  
  189.     /* Register the frame class */
  190.     wc.style         = 0;
  191.     wc.lpfnWndProc   = (WNDPROC)MainWndProc;
  192.     wc.cbClsExtra    = 0;
  193.     wc.cbWndExtra    = CBWNDEXTRA;
  194.     wc.hInstance     = hInstance;
  195.     wc.hIcon         = LoadIcon (hInstance, IDPortTool);
  196.     wc.hCursor       = LoadCursor (NULL,IDC_ARROW);
  197.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  198.     wc.lpszMenuName  = IDPortTool;
  199.     wc.lpszClassName = lpszClass;
  200.  
  201.     if (!RegisterClass (&wc) )
  202.     return FALSE;
  203.  
  204.     /* Create the frame */
  205.     hWnd = CreateWindow (lpszClass,
  206.              "Win32 Port",
  207.              WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | DS_LOCALEDIT,
  208.              CW_USEDEFAULT,
  209.              0,
  210.              CW_USEDEFAULT,
  211.              0,
  212.              NULL,
  213.              NULL,
  214.              hInstance,
  215.              (*lpszCmdLine ? lpszCmdLine : 0));
  216.  
  217.     /* make sure window was created */
  218.     if (!hWnd)
  219.     return FALSE;
  220.  
  221.     /* register search/replace message for common dialog use */
  222.     uSearchMsg = RegisterWindowMessage ((char *)FINDMSGSTRING);
  223.  
  224.     /* show and update main window */
  225.     ShowWindow (hWnd, nCmdShow);
  226.     UpdateWindow (hWnd);
  227.  
  228.     /* Ask for Port Information File */
  229.     if (lpszPortIniFilePath[0] == 0 )
  230.        if ( !GetPortIniFileName (hWnd, lpszFileName, lpszPortIniFilePath) )
  231.           return FALSE;
  232.  
  233.     if ( ! InitPortData(lpszPortIniFilePath) )
  234.        ErrorNotify (hWnd, IDS_PORTINITFAILED);
  235.  
  236.     return hWnd;
  237. }
  238.  
  239. /* main window procedure */
  240. LONG WINAPI MainWndProc (
  241.     HWND    hWnd,
  242.     UINT    uMsg,
  243.     UINT    uParam,
  244.     LONG    lParam)
  245. {
  246.     LONG    lRet = 1;
  247.     int     nResult;
  248.     RECT    rc;
  249.  
  250.     switch (uMsg)
  251.     {
  252.     case WM_CREATE:
  253.         {
  254.         HWND              hWndEdit;
  255.         LPCREATESTRUCT    lpcs = (LPCREATESTRUCT)lParam;
  256.         char              lpszBuff[MAX_PATH];
  257.         LOGFONT           lfEditFont;
  258.         HFONT             hFont;
  259.         HCURSOR           hOldCursor;
  260.  
  261.         /* put hourglass cursor up */
  262.         hOldCursor = (HCURSOR)SetClassLong (hWnd, GCL_HCURSOR, 0);
  263.         SetCursor (LoadCursor (NULL, IDC_WAIT));
  264.  
  265.         /* Create an edit control */
  266.         GetClientRect (hWnd, &rc);
  267.         hWndEdit = CreateWindow ("edit",
  268.                      " ",
  269.                      WS_CHILD | WS_VISIBLE |
  270.                      WS_HSCROLL | WS_VSCROLL |
  271.                      ES_AUTOHSCROLL | ES_AUTOVSCROLL |
  272.                      ES_MULTILINE,
  273.                      rc.left,
  274.                      rc.top,
  275.                      rc.right-rc.left,
  276.                      rc.bottom-rc.top,
  277.                      hWnd,
  278.                      (HMENU)IDC_EDIT,
  279.                      (HANDLE)GetModuleHandle (NULL),
  280.                      0);
  281.  
  282.         /* if edit control failed, abort aplication */
  283.         if (!IsWindow (hWndEdit))
  284.         {
  285.         ErrorNotify (hWnd, IDS_EDITWNDFAILED);
  286.         return FALSE;
  287.         }
  288.  
  289.         /* increase edit control max character limit beyond 30,000 default */
  290.         SendMessage (hWndEdit, EM_LIMITTEXT, 0x0FFFFFFF, 0);
  291.  
  292.         /* save edit window handle and init state variables */
  293.         SetWindowLong (hWnd, WL_HWNDEDIT, (LONG) hWndEdit);
  294.         SetWindowWord (hWnd, WW_SCROLL, TRUE);
  295.         SetWindowWord (hWnd, WW_UNTITLED, TRUE);
  296.         SetWindowWord (hWnd, WW_SEARCHCASE, TRUE);
  297.         SetWindowWord (hWnd, WW_SEARCHDN, TRUE);
  298.         SetWindowLong (hWnd, WL_HPTRDEVNAMES, 0);
  299.  
  300.         /* get printer configuration */
  301.         if (!GetPrinterConfig (hWnd))
  302.         ErrorNotify (hWnd, IDS_PTRCONFIGFAILED);
  303.  
  304.         /* if initialization file passed, load file now */
  305.         if (lpcs->lpCreateParams)
  306.         {
  307.         /* load filename passed at initialization */
  308.         if ((nResult = LoadFile (hWnd, lpcs->lpCreateParams)) > 0)
  309.             {
  310.             /* save filename and path in global string */
  311.             strcpy (lpszFilePath, lpcs->lpCreateParams);
  312.  
  313.             /* The file has a title, so reset the UNTITLED flag. */
  314.             SetWindowWord(hWnd, WW_UNTITLED, FALSE);
  315.  
  316.             /* extract filename from path */
  317.             GetFileFromPath (lpszFilePath, lpszBuff);
  318.  
  319.             /* set window text title to be "AppName - filename" */
  320.             SetWindowTitle (hWnd, lpszBuff);
  321.             }
  322.         else
  323.             {
  324.             /* notify user of error */
  325.             ErrorNotify (hWnd, 0-nResult);
  326.  
  327.             /* set window title to "AppName - Untitled" */
  328.             LoadString ((HANDLE)GetModuleHandle (NULL),
  329.                 IDS_UNTITLED,
  330.                 lpszBuff,
  331.                 sizeof (lpszBuff));
  332.             SetWindowTitle (hWnd, lpszBuff);
  333.             }
  334.         }
  335.         else
  336.         {
  337.         /* set window title to "AppName - Untitled" */
  338.         LoadString ((HANDLE)GetModuleHandle (NULL),
  339.                 IDS_UNTITLED,
  340.                 lpszBuff,
  341.                 sizeof (lpszBuff));
  342.         SetWindowTitle (hWnd, lpszBuff);
  343.  
  344.         /* set global file and path variables to null */
  345.         *lpszFilePath = 0;
  346.         }
  347.  
  348.         //
  349.         // Use system font if Japanese system,
  350.         //  may want to add other DBCS languages later
  351.         //
  352.         if (PRIMARYLANGID(GetUserDefaultLangID ()) == LANG_JAPANESE) {
  353.           GetObject(GetStockObject(SYSTEM_FIXED_FONT),
  354.                         sizeof(LOGFONT), &lfEditFont);
  355.  
  356.         } else {
  357.           /* create fixed pitch font as default font */
  358.           lfEditFont.lfHeight = 16;
  359.           lfEditFont.lfWidth = 0;
  360.           lfEditFont.lfEscapement = 0;
  361.           lfEditFont.lfOrientation = 0;
  362.           lfEditFont.lfWeight = 400;
  363.           lfEditFont.lfItalic = FALSE;
  364.           lfEditFont.lfUnderline = FALSE;
  365.           lfEditFont.lfStrikeOut = FALSE;
  366.           lfEditFont.lfCharSet = ANSI_CHARSET;
  367.           lfEditFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
  368.           lfEditFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  369.           lfEditFont.lfQuality = DEFAULT_QUALITY;
  370.           lfEditFont.lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
  371.           *lfEditFont.lfFaceName = 0;
  372.         }
  373.  
  374.         /* make scroll bars initially visible */
  375.         SetScrollRange (hWndEdit, SB_VERT, 0, 100, TRUE);
  376.         SetScrollRange (hWndEdit, SB_HORZ, 0, 100, TRUE);
  377.  
  378.         /* create the logical font */
  379.         if (hFont = CreateFontIndirect (&lfEditFont))
  380.         SendMessage (hWndEdit, WM_SETFONT, (UINT)hFont, 0);
  381.         else
  382.         ErrorNotify (hWnd, IDS_FONTFAILEDTOCREATE);
  383.  
  384.         /* remove hourglass cursor */
  385.         SetClassLong (hWnd, GCL_HCURSOR, (LONG)hOldCursor);
  386.         SetCursor (hOldCursor);
  387.  
  388.         // Is there anything specific we need to do on different platforms?
  389. #if defined (WIN32)
  390.         if (dwVersion < 0x80000000) {
  391.         // Windows NT
  392.         } else if (LOBYTE(LOWORD(dwVersion))<4) {
  393.         // Win32s
  394.         // Threads aren't available, so disable background porting:
  395.         EnableMenuItem (GetMenu(hWnd), IDM_PORTBKGND, MF_GRAYED);
  396.         } else {
  397.         // Windows 95
  398.         }
  399. #else
  400.         // Win16
  401. #endif
  402.  
  403.         /* set focus to edit window */
  404.         SetFocus (hWndEdit);
  405.         }
  406.         break;
  407.  
  408.     case WM_SIZE:
  409.         {
  410.         HWND    hWndEdit;
  411.  
  412.         /* resize the edit control to match the client area */
  413.         hWndEdit = (HWND)GetWindowLong (hWnd, WL_HWNDEDIT);
  414.         InvalidateRect(hWndEdit, (LPRECT)NULL, TRUE);
  415.         MoveWindow (hWndEdit,
  416.             0,
  417.             0,
  418.             LOWORD(lParam),
  419.             HIWORD(lParam),
  420.             TRUE);
  421.         }
  422.         break;
  423.  
  424.     case WM_SETFOCUS:
  425.         SetFocus ((HWND)GetWindowLong (hWnd, WL_HWNDEDIT));
  426.         break;
  427.  
  428.     case WM_INITMENU:
  429.         /* initialize menuitems */
  430.         InitializeMenu (hWnd, (HMENU)uParam);
  431.         break;
  432.  
  433.     case WM_WININICHANGE:
  434.     case WM_DEVMODECHANGE:
  435.         /* get printer configuration */
  436.         GetPrinterConfig (hWnd);
  437.         break;
  438.  
  439.     case WM_COMMAND:
  440.         /* handle all command messages in a localized function */
  441.         lRet = CommandHandler (hWnd, uParam, lParam);
  442.         break;
  443.  
  444.     case WM_CLOSE:
  445.     case WM_QUERYENDSESSION:
  446.         {
  447.         HWND    hWndEdit = (HWND)GetWindowLong (hWnd, WL_HWNDEDIT);
  448.  
  449.         /* check if there are changes to the edit contents, and offer to save first */
  450.         if (SendMessage (hWndEdit, EM_GETMODIFY, 0, 0))
  451.         {
  452.         switch (Save_YNC (hWnd))
  453.             {
  454.             case IDCANCEL:
  455.             /* abort exit */
  456.             return FALSE;
  457.             case IDYES:
  458.             /* save data then continue */
  459.             if (!SendMessage (hWnd, WM_COMMAND, (UINT)UM_SAVEFILE, 0))
  460.                 return FALSE;
  461.             case IDNO:
  462.             /* just fall through */
  463.             break;
  464.             }
  465.         }
  466.  
  467.         /* call destroy window to cleanup and go away */
  468.         DestroyWindow (hWnd);
  469.         }
  470.         break;
  471.  
  472.     case WM_DESTROY:
  473.         {
  474.         HFONT    hFont = (HFONT)SendMessage ((HWND)GetWindowLong (hWnd, WL_HWNDEDIT),
  475.                          WM_GETFONT,
  476.                          0,
  477.                          0);
  478.  
  479.         /* destroy font handle from edit control if exists */
  480.         if (hFont)
  481.         DeleteObject (hFont);
  482.  
  483.         PostQuitMessage (0);
  484.         }
  485.         break;
  486.  
  487.     default:
  488.         /* process common dialog search message here, then break */
  489.         if (uMsg == uSearchMsg)
  490.         {
  491.         LPFINDREPLACE    lpfr = (LPFINDREPLACE)lParam;
  492.  
  493.         if (lpfr->Flags & FR_DIALOGTERM)
  494.             {
  495.             /* save case and direction */
  496.             SetWindowWord (hWnd, WW_SEARCHCASE, (WORD)(lpfr->Flags & FR_MATCHCASE));
  497.             SetWindowWord (hWnd, WW_SEARCHDN, (WORD)(lpfr->Flags & FR_DOWN));
  498.             hDlgSearch = NULL;
  499.             }
  500.  
  501.         else if (lpfr->Flags & FR_FINDNEXT)
  502.             if (!LocateText (hWnd,
  503.                      (WORD)(lpfr->Flags & FR_MATCHCASE),
  504.                      (WORD)(lpfr->Flags & FR_DOWN),
  505.                      lpszSearch))
  506.             ErrorNotify (hWnd, IDS_STRINGNOTFOUND);
  507.         break;
  508.         }
  509.  
  510.         /* pass all unhandled messages to DefWindowProc */
  511.         lRet = DefWindowProc (hWnd, uMsg, uParam, lParam);
  512.         break;
  513.     }
  514.  
  515.     /* return 1 if handled message, 0 if not */
  516.     return lRet;
  517. }
  518.  
  519.  
  520. /* about box dialog procedure */
  521. BOOL WINAPI AboutDlgProc (
  522.     HWND    hwnd,
  523.     UINT    uMsg,
  524.     UINT    uParam,
  525.     LONG    lParam)
  526. {
  527.     BOOL    bRet = TRUE;
  528.     static  HFONT hfontDlg;
  529.     char szVersion[80];
  530.  
  531.     switch (uMsg)
  532.     {
  533.     case WM_INITDIALOG:  // message: initialize dialog box
  534.  
  535.         // Create a font to use
  536.         hfontDlg = CreateFont(14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, VARIABLE_PITCH | FF_SWISS, "");
  537.  
  538.         SendMessage (GetDlgItem (hwnd, IDC_SYSTEM), WM_SETFONT, (UINT)hfontDlg, TRUE);
  539.         SendMessage (GetDlgItem (hwnd, IDC_APP), WM_SETFONT, (UINT)hfontDlg, TRUE);
  540.         SendMessage (GetDlgItem (hwnd, IDC_VERSION), WM_SETFONT, (UINT)hfontDlg, TRUE);
  541.         SendMessage (GetDlgItem (hwnd, IDC_COPYRIGHT), WM_SETFONT, (UINT)hfontDlg, TRUE);
  542.         //SendMessage (GetDlgItem (hwnd, IDC_OSVERSION), WM_SETFONT, (UINT)hfontDlg, TRUE);
  543.  
  544.  
  545.         //dwVersion = GetVersion();
  546. #if defined (WIN32)
  547.         if (dwVersion < 0x80000000) {
  548.         // Windows NT
  549.         wsprintf (szVersion, "Microsoft WindowsNT %u.%u (Build: %u)",
  550.             (DWORD)(LOBYTE(LOWORD(dwVersion))),
  551.             (DWORD)(HIBYTE(LOWORD(dwVersion))),
  552.             (DWORD)(HIWORD(dwVersion)));
  553.         } else if (LOBYTE(LOWORD(dwVersion))<4) {
  554.         // Win32s
  555.         wsprintf (szVersion, "Microsoft Win32s %u.%u (Build: %u)",
  556.             (DWORD)(LOBYTE(LOWORD(dwVersion))),
  557.             (DWORD)(HIBYTE(LOWORD(dwVersion))),
  558.             (DWORD)(HIWORD(dwVersion) & ~0x8000));
  559.         } else {
  560.         // Windows 95
  561.         wsprintf (szVersion, "Microsoft Windows 95 %u.%u",
  562.             (DWORD)(LOBYTE(LOWORD(dwVersion))),
  563.             (DWORD)(HIBYTE(LOWORD(dwVersion))));
  564.         }
  565.  
  566. #else
  567.         wsprintf (szVersion, " Windows %u.%u - DOS %u.%u",
  568.         (DWORD)(LOBYTE(LOWORD(dwVersion))),
  569.         (DWORD)(HIBYTE(LOWORD(dwVersion))),
  570.         (DWORD)(HIBYTE(HIWORD(dwVersion))),
  571.         (DWORD)(LOBYTE(HIWORD(dwVersion))));
  572.  
  573.       
  574. #endif
  575.         SetWindowText (GetDlgItem(hwnd, IDC_OSVERSION), szVersion);
  576.  
  577.  
  578.         return (TRUE);
  579.  
  580.     case WM_COMMAND:
  581.         switch (LOWORD (uParam))
  582.         {
  583.         /* end dialog with TRUE or FALSE for OK or CANCEL */
  584.         case IDOK:
  585.         case IDCANCEL:
  586.             EndDialog(hwnd, (LOWORD (uParam) == IDOK));
  587.             break;
  588.  
  589.         default:
  590.             bRet = FALSE;
  591.         }
  592.         break;
  593.  
  594.     default:
  595.         bRet =  FALSE;
  596.         break;
  597.     }
  598.     return bRet;
  599. }
  600.  
  601.  
  602.  
  603. /* initialize menu function */
  604. VOID WINAPI InitializeMenu (
  605.     HWND    hWnd,
  606.     HANDLE  hMenu)
  607. {
  608.     WORD    mfStatus;
  609.     DWORD   dwSel;
  610.     HWND    hWndEdit = (HWND)GetWindowLong (hWnd, WL_HWNDEDIT);
  611.     WORD    wScroll;
  612.  
  613.     /* see if edit control can undo last command */
  614.     if (SendMessage (hWndEdit, EM_CANUNDO, 0, 0L))
  615.     mfStatus = MF_ENABLED;
  616.     else
  617.     mfStatus = MF_GRAYED;
  618.     EnableMenuItem (hMenu, IDM_EDITUNDO, mfStatus);
  619.  
  620.     /* enable menuitems CUT, COPY and CLEAR if selected text */
  621.     dwSel = SendMessage (hWndEdit, EM_GETSEL, 0, 0);
  622.     mfStatus = (WORD)((LOWORD(dwSel) == HIWORD(dwSel))?MF_GRAYED:MF_ENABLED);
  623.     EnableMenuItem (hMenu, IDM_EDITCUT, mfStatus);
  624.     EnableMenuItem (hMenu, IDM_EDITCOPY, mfStatus);
  625.     EnableMenuItem (hMenu, IDM_EDITCLEAR, mfStatus);
  626.  
  627.     /* if text allow for new file, enable menuitem */
  628.     if (SendMessage (hWndEdit, WM_GETTEXTLENGTH, 0, 0))
  629.     EnableMenuItem (hMenu, IDM_FILENEW, MF_ENABLED);
  630.     else
  631.     EnableMenuItem (hMenu, IDM_FILENEW, MF_GRAYED);
  632.  
  633.     /* if CF_TEXT format data is available in clipboard */
  634.     if (OpenClipboard (hWnd) & IsClipboardFormatAvailable (CF_TEXT))
  635.     EnableMenuItem (hMenu, IDM_EDITPASTE, MF_ENABLED);
  636.     else
  637.     EnableMenuItem (hMenu, IDM_EDITPASTE, MF_GRAYED);
  638.     CloseClipboard ();
  639.  
  640.     /* set the scroll bars menuitem */
  641.     wScroll = GetWindowWord (hWnd, WW_SCROLL);
  642.     CheckMenuItem (hMenu, IDM_EDITSCROLL, (UINT)(wScroll ? MF_CHECKED : MF_UNCHECKED));
  643.  
  644.     /* set the word wrap state for the window */
  645.     dwSel = GetWindowLong (hWndEdit, GWL_STYLE);
  646.     CheckMenuItem (hMenu,
  647.            IDM_EDITWRAP,
  648.            (UINT)((dwSel & ES_AUTOHSCROLL) ? MF_UNCHECKED : MF_CHECKED));
  649.  
  650.     /* enable search menuitems if a search string exists */
  651.     if (*lpszSearch)
  652.     {
  653.     EnableMenuItem (hMenu, IDM_SEARCHNEXT, MF_ENABLED);
  654.     EnableMenuItem (hMenu, IDM_SEARCHPREV, MF_ENABLED);
  655.     }
  656.     else
  657.     {
  658.     EnableMenuItem (hMenu, IDM_SEARCHNEXT, MF_GRAYED);
  659.     EnableMenuItem (hMenu, IDM_SEARCHPREV, MF_GRAYED);
  660.     }
  661.  
  662.     /* enable Print menuitems if a printer is available */
  663.     if (GetWindowLong (hWnd, WL_HPTRDEVNAMES))
  664.     {
  665.     EnableMenuItem (hMenu, IDM_FILEPRINT, MF_ENABLED);
  666.     EnableMenuItem ( hMenu, IDM_FILESETUP, MF_ENABLED);
  667.     }
  668.     else
  669.     {
  670.     EnableMenuItem (hMenu, IDM_FILEPRINT, MF_GRAYED);
  671.     EnableMenuItem ( hMenu, IDM_FILESETUP, MF_GRAYED);
  672.     }
  673.  
  674.     /* menuitems that are always enabled */
  675.     EnableMenuItem(hMenu, IDM_EDITSCROLL, MF_ENABLED);
  676.     EnableMenuItem(hMenu, IDM_EDITSELECT, MF_ENABLED);
  677.     EnableMenuItem(hMenu, IDM_EDITWRAP, MF_ENABLED);
  678.     EnableMenuItem(hMenu, IDM_SEARCHFIND, MF_ENABLED);
  679. }
  680.  
  681.  
  682.  
  683. /* handle all WM_COMMAND messages here */
  684. LONG WINAPI CommandHandler (
  685.     HWND    hWnd,
  686.     UINT    uParam,
  687.     LONG    lParam)
  688. {
  689.     int     nResult;
  690.     HWND    hWndEdit = (HWND)GetWindowLong (hWnd, WL_HWNDEDIT);
  691.  
  692.     switch (LOWORD(uParam))
  693.     {
  694.     case IDM_FILENEW:
  695.         {
  696.         char    lpszMsg[MAX_PATH];
  697.  
  698.         /* check if there are changes, and offer to save first */
  699.         if (SendMessage (hWndEdit, EM_GETMODIFY, 0, 0))
  700.         {
  701.         switch (Save_YNC (hWnd))
  702.             {
  703.             case IDCANCEL:
  704.             /* abort operation */
  705.             return FALSE;
  706.             case IDYES:
  707.             /* save data then continue if successful */
  708.             if (!SendMessage (hWnd, WM_COMMAND, (UINT)UM_SAVEFILE, 0))
  709.                 return FALSE;
  710.             case IDNO:
  711.             /* just fall through */
  712.             break;
  713.             }
  714.  
  715.         /* reset edit changes flag */
  716.         SendMessage (hWndEdit, EM_SETMODIFY, FALSE, 0);
  717.         }
  718.  
  719.         /* clear edit control */
  720.         SetWindowText (hWndEdit, "");
  721.  
  722.         /* set window title to "Untitled" */
  723.         LoadString ((HANDLE)GetModuleHandle (NULL),
  724.             IDS_UNTITLED,
  725.             lpszMsg,
  726.             sizeof (lpszMsg));
  727.         SetWindowTitle (hWnd, lpszMsg);
  728.         SetWindowWord (hWnd, WW_UNTITLED, TRUE);
  729.  
  730.         /* reset caret position by sending WM_KILLFOCUS/WM_SETFOCUS messages */
  731.         SetFocus (NULL);
  732.         SetFocus (hWndEdit);
  733.         }
  734.         break;
  735.  
  736.     case IDM_FILEOPEN:
  737.         {
  738.         char    lpszFileName[MAX_PATH];
  739.         int     nResult;
  740.  
  741.         /* if changes to current file, ask to save first */
  742.         if (SendMessage (hWndEdit, EM_GETMODIFY, 0, 0))
  743.         {
  744.         switch (Save_YNC (hWnd))
  745.             {
  746.             case IDCANCEL:
  747.             /* abort operation */
  748.             return FALSE;
  749.             case IDYES:
  750.             /* save data then continue */
  751.             if (!SendMessage (hWnd, WM_COMMAND, (UINT)UM_SAVEFILE, 0))
  752.                 return FALSE;
  753.             case IDNO:
  754.             /* just fall through */
  755.             break;
  756.             }
  757.  
  758.         /* reset edit changes flag */
  759.         SendMessage (hWndEdit, EM_SETMODIFY, FALSE, 0);
  760.         }
  761.  
  762.         /* get new filename and load into edit control */
  763.         if (GetFileName (hWnd, lpszFileName, lpszFilePath))
  764.         {
  765.         if ((nResult = LoadFile (hWnd, lpszFilePath)) < 0)
  766.             /* notify user of error */
  767.             ErrorNotify (hWnd, 0-nResult);
  768.         else
  769.             {
  770.             /* update window text */
  771.             SetWindowTitle (hWnd, lpszFileName);
  772.             SetWindowWord (hWnd, WW_UNTITLED, FALSE);
  773.             }
  774.         }
  775.         else
  776.         return FALSE;
  777.         }
  778.         break;
  779.  
  780.     case IDM_FILESAVEAS:
  781.         {
  782.         char    lpszFileTitle[MAX_PATH];
  783.         int     nResult;
  784.  
  785.         /* get a valid filename and path */
  786.         if (SaveAsFileName (hWnd, lpszFileTitle, lpszFilePath))
  787.         {
  788.         /* if file saves okay */
  789.         if ((nResult = SaveFile (hWnd, lpszFilePath)) > 0)
  790.             {
  791.             /* reset changed flag, and window title */
  792.             SendMessage (hWndEdit, EM_SETMODIFY, FALSE, 0);
  793.             SetWindowTitle (hWnd, lpszFileTitle);
  794.             SetWindowWord (hWnd, WW_UNTITLED, FALSE);
  795.             }
  796.         else
  797.             {
  798.             /* unable to save file, return error */
  799.             ErrorNotify (hWnd, nResult);
  800.             return FALSE;
  801.             }
  802.         }
  803.         else
  804.         return FALSE;
  805.         }
  806.         break;
  807.  
  808.     case IDM_FILESAVE:
  809.         {
  810.         char    lpszFileTitle[MAX_PATH];
  811.         int     nResult;
  812.  
  813.         /* if called from menu, check to see if file modified */
  814.         if (!lParam && !SendMessage (hWndEdit, EM_GETMODIFY, 0, 0))
  815.           return FALSE;
  816.  
  817.     /* user defined msg is sent from Exit, Open and New menuitems */
  818.     case UM_SAVEFILE:
  819.  
  820.         /* if untitled, get new name */
  821.         if (GetWindowWord (hWnd, WW_UNTITLED) &&
  822.         !(SaveAsFileName(hWnd, lpszFileTitle, lpszFilePath)))
  823.         {
  824.         /* make sure no name was saved */
  825.         *lpszFilePath = 0;
  826.         return FALSE;
  827.         }
  828.  
  829.         /* save buffer and reset flag */
  830.         if ((nResult = SaveFile (hWnd, lpszFilePath)) > 0)
  831.         {
  832.         // get lpszFileTitle
  833.         char szDrive[_MAX_DRIVE], szDir[_MAX_DIR], szExt[_MAX_EXT];
  834.         _splitpath(lpszFilePath,szDrive,szDir,lpszFileTitle,szExt);
  835.         lstrcat(lpszFileTitle,szExt);
  836.  
  837.         /* if new file name, set window title */
  838.         if (*lpszFileTitle)
  839.             {
  840.             SetWindowTitle (hWnd, lpszFileTitle);
  841.             SetWindowWord (hWnd, WW_UNTITLED, FALSE);
  842.             }
  843.         SendMessage (hWndEdit, EM_SETMODIFY, FALSE, 0);
  844.         }
  845.         else
  846.         {
  847.         /* unable to save file, return error */
  848.         ErrorNotify (hWnd, nResult);
  849.         return FALSE;
  850.         }
  851.         }
  852.         break;
  853.  
  854.     case IDM_FILEPRINT:
  855.         {
  856.         int    nRes;
  857.  
  858.         /* print the file */
  859.         if ((nRes = PrintFile (hWnd)) < 0)
  860.         ErrorNotify (hWnd, nRes);
  861.         }
  862.         break;
  863.  
  864.     case IDM_FILESETUP:
  865.         {
  866.         int    nRes;
  867.  
  868.         /* set up the printer environment */
  869.         if ((nRes = PrinterSetup (hWnd)) < 0)
  870.         ErrorNotify (hWnd, nRes);
  871.         }
  872.         break;
  873.  
  874.     case IDM_FILEEXIT:
  875.         /* exit application */
  876.         PostMessage (hWnd, WM_CLOSE, 0, 0L);
  877.         break;
  878.  
  879.     case IDM_FILEABOUT:
  880.         /* call about dialog box */
  881.         DialogBox ((HANDLE)GetModuleHandle (NULL),
  882.                (LPSTR)IDD_ABOUT,
  883.                hWnd,
  884.                AboutDlgProc);
  885.         break;
  886.  
  887.     case IDM_EDITUNDO:
  888.         SendMessage (hWndEdit, EM_UNDO, 0, 0);
  889.         break;
  890.  
  891.     case IDM_EDITCUT:
  892.         SendMessage (hWndEdit, WM_CUT, 0, 0);
  893.         break;
  894.  
  895.     case IDM_EDITCOPY:
  896.         SendMessage (hWndEdit, WM_COPY, 0, 0);
  897.         break;
  898.  
  899.     case IDM_EDITCLEAR:
  900.         SendMessage (hWndEdit, WM_CLEAR, 0, 0);
  901.         break;
  902.  
  903.     case IDM_EDITPASTE:
  904.         SendMessage (hWndEdit, WM_PASTE, 0, 0L);
  905.         break;
  906.  
  907.     case IDM_EDITSELECT:
  908.         /* 0, -1 selects the entire string */
  909.         SendMessage (hWndEdit, EM_SETSEL, 0, (LONG)(int)-1);
  910.         break;
  911.  
  912.     case IDM_EDITSCROLL:
  913.         {
  914.         WORD    wScroll = !GetWindowWord (hWnd, WW_SCROLL);
  915.  
  916.         /* toggle vertical scroll bar */
  917.         SetScrollRange (hWndEdit, SB_VERT, 0, (int)(wScroll ? 100 : 0), TRUE);
  918.  
  919.         /* if not word wrap, toggle horizontal scroll */
  920.         if (ES_AUTOHSCROLL & GetWindowLong (hWndEdit, GWL_STYLE))
  921.         SetScrollRange (hWndEdit, SB_HORZ, 0, (int)(wScroll ? 100 : 0), TRUE);
  922.  
  923.         /* set scroll flag */
  924.         SetWindowWord (hWnd, WW_SCROLL, wScroll);
  925.         }
  926.         break;
  927.  
  928.     case IDM_EDITWRAP:
  929.         /* change edit control */
  930.         if ((nResult = SetWrap (hWnd)) < 0)
  931.         /* notify user of error */
  932.         ErrorNotify (hWnd, nResult);
  933.         break;
  934.  
  935.     case IDM_EDITFONT:
  936.         {
  937.         CHOOSEFONT    cf;
  938.         LOGFONT       lfEditFont;
  939.         HFONT         hEditFont;
  940.  
  941.         /* get logical font structure from current font */
  942.         if (hEditFont = (HFONT)SendMessage (hWndEdit, WM_GETFONT, 0, 0))
  943.         {
  944.         GetObject (hEditFont, sizeof (lfEditFont), &lfEditFont);
  945.         cf.Flags = CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
  946.         }
  947.         else
  948.         cf.Flags = CF_SCREENFONTS;
  949.  
  950.         /* call common dialog to select a font */
  951.         cf.lStructSize    = sizeof (CHOOSEFONT);
  952.         cf.hwndOwner      = hWnd;
  953.         cf.hDC            = NULL;
  954.         cf.lpLogFont      = &lfEditFont;
  955.         cf.iPointSize     = 0;
  956.         cf.rgbColors      = 0;
  957.         cf.lCustData      = 0;
  958.  
  959.         //
  960.         // On Japanese system set font filter proc,
  961.         //  may want to add other DBCS languages later
  962.         //
  963.         if (PRIMARYLANGID(GetUserDefaultLangID ()) == LANG_JAPANESE) {
  964.           cf.lpfnHook = (LPCFHOOKPROC)MakeProcInstance(ChooseFontHookProc, NULL);
  965.           cf.Flags |= CF_ENABLEHOOK;
  966.         } else {
  967.           cf.lpfnHook       = NULL;
  968.         }
  969.  
  970.         cf.lpTemplateName = NULL;
  971.         cf.hInstance      = NULL;
  972.         cf.lpszStyle      = NULL;
  973.         cf.nFontType      = SCREEN_FONTTYPE;
  974.         cf.nSizeMin       = 0;
  975.         cf.nSizeMax       = 0;
  976.  
  977.         if (ChooseFont (&cf))
  978.         {
  979.         /* create new font and put in edit control */
  980.         SendMessage (hWndEdit,
  981.                  WM_SETFONT,
  982.                  (UINT)CreateFontIndirect
  983.                  (&lfEditFont),
  984.                  TRUE);
  985.  
  986.         if (hEditFont)
  987.             DeleteObject (hEditFont);
  988.         }
  989.         }
  990.         break;
  991.  
  992.     case IDM_SEARCHFIND:
  993.         {
  994.         UINT    uBegSel, uEndSel;
  995.         WORD    wCase = GetWindowWord (hWnd, WW_SEARCHCASE);
  996.         WORD    wDir = GetWindowWord (hWnd, WW_SEARCHDN);
  997.  
  998.         /* if selected text, replace global search string */
  999.         SendMessage (hWndEdit, EM_GETSEL, (UINT)&uBegSel, (UINT)&uEndSel);
  1000.         if (uBegSel != uEndSel)
  1001.         GetEditSubString (hWndEdit, &uBegSel, &uEndSel, lpszSearch);
  1002.  
  1003.         /* Put up the find dialog box */
  1004.         if (!FindDialog (hWnd, wCase, wDir, lpszSearch))
  1005.         ErrorNotify (hWnd, IDS_SEARCHDLGFAILED);
  1006.         }
  1007.         break;
  1008.  
  1009.     case IDM_SEARCHNEXT:
  1010.         /* locate next search string in edit control */
  1011.         if (!LocateText (hWnd,
  1012.                  GetWindowWord (hWnd, WW_SEARCHCASE),
  1013.                  TRUE,
  1014.                  lpszSearch))
  1015.         ErrorNotify (hWnd, IDS_STRINGNOTFOUND);
  1016.         break;
  1017.  
  1018.     case IDM_SEARCHPREV:
  1019.         /* locate previous search string in edit control */
  1020.         if (!LocateText (hWnd,
  1021.                  GetWindowWord (hWnd, WW_SEARCHCASE),
  1022.                  FALSE,
  1023.                  lpszSearch))
  1024.         ErrorNotify (hWnd, IDS_STRINGNOTFOUND);
  1025.         break;
  1026.  
  1027.     case IDM_PORTCURFILE:
  1028.         /* if untitled, save first */
  1029.         if (GetWindowWord (hWnd, WW_UNTITLED) &&
  1030.         !SendMessage (hWnd, WM_COMMAND, IDM_FILEOPEN, 0))
  1031.         {
  1032.         ErrorNotify (hWnd, IDS_NOFILETOPORT);
  1033.         break;
  1034.         }
  1035.  
  1036.         /* start port dialog with flags */
  1037.         hDlgPort = CreateDialog (GetModuleHandle (NULL),
  1038.                      IDD_PORTDIALOG,
  1039.                      hWnd,
  1040.                      PortDlgProc);
  1041.         break;
  1042.  
  1043.     case IDM_PORTBKGND:
  1044.         if (IsWindow (hDlgPortStatus))
  1045.         ShowWindow (hDlgPortStatus, SW_SHOWNORMAL);
  1046.         else if (!(hDlgPortStatus = StartBackground (GetModuleHandle (NULL),
  1047.                              hWnd,
  1048.                              NULL)))
  1049.         ErrorNotify (hWnd, IDS_BKPORTSTARTFAILED);
  1050.         break;
  1051.  
  1052.     default:
  1053.         return FALSE;
  1054.     }
  1055.     return TRUE;
  1056. }
  1057.  
  1058.  
  1059.  
  1060. /* change the word wrapping in an edit control */
  1061. int WINAPI SetWrap (
  1062.     HWND    hWnd)
  1063.  
  1064. {
  1065.     DWORD   dwStyle;
  1066.     HANDLE    hNewData;
  1067.     char    *lpNewData;
  1068.     HWND    hWndOld = (HWND)GetWindowLong (hWnd, WL_HWNDEDIT);
  1069.     HWND    hWndNew;
  1070.     RECT    rc;
  1071.     UINT    uLen;
  1072.     UINT    uBegSel, uEndSel;
  1073.     WORD    wScroll = GetWindowWord (hWnd, WW_SCROLL);
  1074.     HFONT    hEditFont = (HFONT)SendMessage (hWndOld, WM_GETFONT, 0, 0);
  1075.  
  1076. #ifndef WIN32
  1077.     HANDLE    hOldData;
  1078.     char    *lpOldData;
  1079. #endif
  1080.  
  1081.     char sz[40]; // temporary string for error messages
  1082.  
  1083.  
  1084.     /* turn off scroll bars if currently present */
  1085.     if (wScroll)
  1086.     {
  1087.     SetScrollRange (hWndOld, SB_VERT, 0, 0, FALSE);
  1088.     SetScrollRange (hWndOld, SB_HORZ, 0, 0, FALSE);
  1089.     }
  1090.  
  1091.     /* new edit style = old style XOR ES_AUTOHSCROLL */
  1092.     dwStyle = ES_AUTOHSCROLL ^ (DWORD)GetWindowLong (hWndOld, GWL_STYLE);
  1093.  
  1094.     /* save text selection */
  1095.     SendMessage (hWndOld, EM_GETSEL, (UINT)&uBegSel, (UINT)&uEndSel);
  1096.  
  1097.     /* create a new edit control with the new style */
  1098.     GetClientRect (hWnd, &rc);
  1099.     hWndNew = CreateWindow ("edit",
  1100.                 "",
  1101.                 dwStyle,
  1102.                 rc.left,
  1103.                 rc.top,
  1104.                 rc.right-rc.left,
  1105.                 rc.bottom-rc.top,
  1106.                 hWnd,
  1107.                 (HMENU)IDC_EDIT,
  1108.                 (HANDLE)GetModuleHandle (NULL),
  1109.                 0);
  1110.  
  1111.     /* check for window created */
  1112.     if (!IsWindow (hWndNew))
  1113.     return IDS_EDITWNDFAILED;
  1114.  
  1115.     /* reset to no format lines */
  1116.     if (dwStyle & ES_AUTOHSCROLL)
  1117.         SendMessage (hWndOld, EM_FMTLINES, FALSE, 0);
  1118.  
  1119. #if defined (WIN32)
  1120.     uLen = GetWindowTextLength (hWndOld);
  1121.  
  1122.     hNewData = LocalAlloc (LHND, uLen+1);
  1123.     if (hNewData == NULL) {
  1124.     wsprintf (sz, "Unable to allocate %u bytes", uLen+1);
  1125.     MessageBox (GetFocus, sz, "PORTTOOL::SetWrap", MB_OK);
  1126.     DestroyWindow(hWndNew);
  1127.     return IDS_GETHANDLEFAILED;
  1128.     }
  1129.  
  1130.     lpNewData = LocalLock (hNewData);
  1131.     if (lpNewData == NULL) {
  1132.     MessageBox (GetFocus, "Unable to lock memory", "PORTTOOL::SetWrap", MB_OK);
  1133.     DestroyWindow(hWndNew);
  1134.     LocalFree (hNewData);
  1135.     return IDS_GETHANDLEFAILED;
  1136.     }
  1137.  
  1138.     GetWindowText (hWndOld, lpNewData, uLen+1);
  1139.     SetWindowText (hWndNew, lpNewData);
  1140.     LocalUnlock (hNewData);
  1141.  
  1142. #else
  1143.     /* get the data handle of the old control */
  1144.     if (!(hOldData = (HANDLE)SendMessage (hWndOld, EM_GETHANDLE, 0, 0)))
  1145.     {
  1146.     /* delete new edit window and return error */
  1147.     DestroyWindow (hWndNew);
  1148.     return IDS_GETHANDLEFAILED;
  1149.     }
  1150.  
  1151.     /* increase edit control max character limit beyond 30,000 default */
  1152.     SendMessage (hWndNew, EM_LIMITTEXT, 0x0FFFFFFF, 0);
  1153.  
  1154.     /* get data handle to new edit control and reallocate to size of old edit text */
  1155.     hNewData = (HANDLE)SendMessage (hWndNew, EM_GETHANDLE, 0, 0);
  1156.     uLen = GetWindowTextLength (hWndOld);
  1157.     if (LocalReAlloc(hNewData, uLen+1, LHND) == NULL)
  1158.     {
  1159.     /* abort, clean up and return error */
  1160.     DestroyWindow (hWndNew);
  1161.     return IDS_REALLOCFAILED;
  1162.     }
  1163.  
  1164.     lpOldData = LocalLock (hOldData);
  1165.     lpNewData = LocalLock (hNewData);
  1166.     lpNewData[uLen+1] = 0;
  1167.  
  1168.     /* copy from one buffer to the other */
  1169.     while (uLen-- > 0)
  1170.     lpNewData[uLen] = lpOldData[uLen];
  1171.  
  1172.     /* unlock and release data buffers */
  1173.     LocalUnlock (hOldData);
  1174.     LocalUnlock (hNewData);
  1175.  
  1176. #endif
  1177.  
  1178.     /* swap windows */
  1179.     SetWindowLong (hWnd, WL_HWNDEDIT, (LONG)hWndNew);
  1180.     DestroyWindow (hWndOld);
  1181.  
  1182. #if !defined(WIN32)
  1183.     SendMessage (hWndNew, EM_SETHANDLE, (UINT)hNewData, 0);
  1184. #endif
  1185.  
  1186.     /* set line formatting */
  1187.     if (dwStyle & ES_AUTOHSCROLL)
  1188.         SendMessage (hWndNew, EM_FMTLINES, FALSE, 0);
  1189.  
  1190.     /* replace font in new edit control */
  1191.     if (hEditFont)
  1192.     SendMessage (hWndNew, WM_SETFONT, (UINT)hEditFont, 0);
  1193.  
  1194.     /* set scroll bars if appropriate */
  1195.     if (wScroll)
  1196.     {
  1197.     SetScrollRange (hWndNew, SB_VERT, 0, 100, TRUE);
  1198.     SetScrollRange (hWndNew, SB_HORZ, 0, (ES_AUTOHSCROLL & dwStyle ? 100 : 0), TRUE);
  1199.     }
  1200.  
  1201.     /* Set limit to greater than 30K */
  1202.     SendMessage (hWndNew, EM_LIMITTEXT, 0x0FFFFFFF, 0);
  1203.  
  1204.     /* restore text selection, repaint and set focus */
  1205.     InvalidateRect (hWndNew, NULL, TRUE);
  1206.     UpdateWindow (hWndNew);
  1207.     SendMessage (hWndNew, EM_SETSEL, uBegSel, uEndSel);
  1208.     SetFocus (hWndNew);
  1209.  
  1210. #if defined(WIN32)
  1211.     LocalFree (hNewData);
  1212. #endif
  1213.  
  1214.     /* return success */
  1215.     return TRUE;
  1216. }
  1217.  
  1218.  
  1219.  
  1220. /* get win32 command line parameters */
  1221. BOOL WINAPI GetCmdLine(
  1222.     char    *lpStr,
  1223.     char    *lpszCmdLine,
  1224.     BOOL    *bBkgnd,
  1225.     char    *lpszPortFileName)
  1226. {
  1227.     if (*lpStr)
  1228.     {
  1229.     /* skip application name which precedes parameters */
  1230.     while (*lpStr != ' ' && *lpStr != 0)
  1231.         lpStr = CharNext(lpStr);;
  1232.  
  1233.     /* skip spaces */
  1234.     while (*lpStr == ' ' && *lpStr != 0)
  1235.         lpStr++;
  1236.  
  1237.     /* indeed command line parameter(s) present */
  1238.     if (*lpStr != 0)
  1239.         {
  1240.         /* if background switch, set flag and remove switch from command line */
  1241.         if ((*lpStr == '/' || *lpStr == '-') &&
  1242.         (*(lpStr+1) == 'b' || *(lpStr+1) == 'B'))
  1243.         {
  1244.         *bBkgnd = TRUE;
  1245.         lpStr += 2;
  1246.  
  1247.         if (*lpStr == 0)
  1248.             *lpszCmdLine = 0;
  1249.         else
  1250.             strcpy (lpszCmdLine, lpStr);
  1251.         }
  1252.         /* maybe switch is embedded in parameter(s) somewhere */
  1253.         else
  1254.         {
  1255.         char    *pStr = lpStr;
  1256.         char    *pCmdLine  = lpszCmdLine;
  1257.         char    *pPortFile = lpszPortFileName;
  1258.         int     i, nCnt;
  1259.  
  1260.         while (*pStr != 0)
  1261.             {
  1262.             /* background switch is set, so prepare parameters and set flag */
  1263.             if ((*pStr == '/' || *pStr == '-') &&
  1264.             (*(pStr+1) == 'b' || *(pStr+1) == 'B'))
  1265.             {
  1266.             *bBkgnd = TRUE;
  1267.  
  1268.             /* copy from beg. of lpStr to *pStr to lpszCmdLine */
  1269.             nCnt = pStr - lpStr;
  1270.             for (i=0; i<nCnt; i++)
  1271.                 lpszCmdLine[i] = lpStr[i];
  1272.             lpszCmdLine[i] = 0;
  1273.             strcat (lpszCmdLine, (pStr+2));
  1274.  
  1275.             /* break from loop */
  1276.             break;
  1277.             }
  1278.             else if ((*pStr == '/' || *pStr == '-') &&
  1279.             (*(pStr+1) == 'i' || *(pStr+1) == 'I'))
  1280.             {
  1281.               pStr = lpStr;
  1282.  
  1283.               while (*pStr != ' ' && *pStr != 0)
  1284.               {
  1285.                 pStr++;
  1286.                 lpStr++;
  1287.               }
  1288.  
  1289.               while (*pStr == ' ' && *pStr != 0)
  1290.               {
  1291.                 pStr++;
  1292.                 lpStr++;
  1293.               }
  1294.  
  1295.               while (*pStr != ' ' && *pStr != 0)
  1296.               {
  1297.                 *pPortFile = *pStr;
  1298.                 pPortFile++;
  1299.                 pStr++;
  1300.                 lpStr++;
  1301.               }
  1302.               *pPortFile = 0;
  1303.             }
  1304.  
  1305.             pStr++;
  1306.             }
  1307.  
  1308.         /* no switch found, can only edit one file, remove extra parameters */
  1309.         if (*pStr == 0)
  1310.             {
  1311.             pStr = lpStr;
  1312.  
  1313.             while (*pStr != ' ' && *pStr != 0)
  1314.             pStr++;
  1315.  
  1316.             if (*pStr == ' ')
  1317.             *pStr = 0;
  1318.  
  1319.             strcpy (lpszCmdLine, lpStr);
  1320.             }
  1321.         }
  1322.         }
  1323.     else
  1324.         return FALSE;
  1325.     }
  1326.     else
  1327.     return FALSE;
  1328.  
  1329.     return TRUE;
  1330. }
  1331.  
  1332.  
  1333.  
  1334. /* display a Save, Yes|No|Cancel message box */
  1335. int WINAPI Save_YNC (
  1336.     HWND    hWnd)
  1337. {
  1338.     char    lpszMsg[MAX_PATH];
  1339.     char    lpszAppName[MAX_PATH];
  1340.  
  1341.     /* load string to prompt user */
  1342.     LoadString ((HANDLE)GetModuleHandle (NULL),
  1343.         IDS_DATACHANGED,
  1344.         lpszMsg,
  1345.         sizeof (lpszMsg));
  1346.     LoadString ((HANDLE)GetModuleHandle (NULL),
  1347.         IDS_APPNAME,
  1348.         lpszAppName,
  1349.         sizeof (lpszAppName));
  1350.  
  1351.     /* return user response */
  1352.     return (MessageBox (hWnd,
  1353.             lpszMsg,
  1354.             lpszAppName,
  1355.             MB_YESNOCANCEL | MB_ICONQUESTION));
  1356. }
  1357.  
  1358.  
  1359.  
  1360. /* error notification routine */
  1361. VOID WINAPI ErrorNotify (
  1362.     HWND    hWnd,
  1363.     int     nErrorString)
  1364. {
  1365.     char    lpszAppName[MAX_PATH];
  1366.     char    lpszErrStr[MAX_PATH];
  1367.     char    szNum[10];
  1368.  
  1369.     LoadString ((HANDLE)GetModuleHandle (NULL),
  1370.         IDS_APPNAME,
  1371.         lpszAppName,
  1372.         sizeof (lpszAppName));
  1373.     if (!LoadString ((HANDLE)GetModuleHandle (NULL),
  1374.              nErrorString,
  1375.              lpszErrStr,
  1376.              sizeof (lpszErrStr)))
  1377.     {
  1378.     LoadString((HANDLE)GetModuleHandle(NULL),
  1379.           IDS_UNKNOWN_ERROR,
  1380.           lpszErrStr,
  1381.           sizeof (lpszErrStr));
  1382.     strcat (lpszErrStr, itoa (nErrorString, szNum, 10));
  1383.     }
  1384.  
  1385.     MessageBox (NULL, lpszErrStr, lpszAppName, MB_OK | MB_ICONINFORMATION | MB_TASKMODAL);
  1386. }
  1387.  
  1388.  
  1389.  
  1390. VOID WINAPI SetWindowTitle (
  1391.     HWND    hWnd,
  1392.     char    *lpszFile)
  1393. {
  1394.     char    lpszAppName[MAX_PATH];
  1395.  
  1396.     if (LOBYTE(LOWORD(dwVersion))>=4) {
  1397.     // On Windows 95, only put up the filename
  1398.     SetWindowText (hWnd, lpszFile);
  1399.     } else {
  1400.     /* load AppName and Window title string into window text */
  1401.     LoadString ((HANDLE)GetModuleHandle (NULL),
  1402.         IDS_PRINTJOB,
  1403.         lpszAppName,
  1404.         sizeof (lpszAppName));
  1405.     strcat (lpszAppName, lpszFile);
  1406.     SetWindowText (hWnd, lpszAppName);
  1407.     }
  1408. }
  1409.  
  1410.  
  1411.  
  1412. /* extract a substring from the edit controls data buffer */
  1413. VOID WINAPI GetEditSubString (
  1414.     HWND    hWndEdit,
  1415.     PUINT   puStart,
  1416.     PUINT   puEnd,
  1417.     char    *lpszString)
  1418. {
  1419.     HANDLE    hEditData;
  1420.     char      *lpEditData;
  1421.     UINT      i;
  1422.  
  1423.     char sz[40]; // temporary string for error reporting
  1424.  
  1425.     /* maximum search string length is MAXSEARCHSTRING characters */
  1426.     if ((*puEnd - *puStart) > MAXSEARCHSTRING)
  1427.     *puEnd = *puStart + MAXSEARCHSTRING;
  1428.  
  1429. #if defined(WIN32)
  1430.  
  1431.     i = GetWindowTextLength(hWndEdit);
  1432.     hEditData = LocalAlloc (LHND, i+1);
  1433.     if (hEditData == NULL) {
  1434.     wsprintf (sz, "Unable to allocate %u bytes", i+1);
  1435.     MessageBox (GetFocus, sz, "PORTTOOL::GetEditSubString", MB_OK);
  1436.     }
  1437.  
  1438.     lpEditData = LocalLock (hEditData);
  1439.     if (lpEditData == NULL) {
  1440.     MessageBox (GetFocus, "Unable to lock memory", "PORTTOOL::GetEditSubString", MB_OK);
  1441.     } else {
  1442.     GetWindowText (hWndEdit, lpEditData, i+1);
  1443.     }
  1444.  
  1445. #else
  1446.  
  1447.     /* get edit data handle and lock */
  1448.     hEditData = (HANDLE)SendMessage (hWndEdit, EM_GETHANDLE, 0, 0);
  1449.     lpEditData = (char *)LocalLock (hEditData);
  1450.  
  1451. #endif
  1452.  
  1453.     if (lpEditData != NULL) {
  1454.     /* copy characters to string and terminate */
  1455.     for (i=*puStart; i<*puEnd; i++)
  1456.         lpszString[i-*puStart] = lpEditData[i];
  1457.     lpszString[i-*puStart] = 0;
  1458.     }
  1459.  
  1460.     /* unlock and return edit handle */
  1461.     LocalUnlock (hEditData);
  1462.  
  1463. #if defined(WIN32)
  1464.  
  1465.     LocalFree (hEditData);
  1466.  
  1467. #endif
  1468.  
  1469. }
  1470.  
  1471.  
  1472. /****************************************************************************
  1473.     My_mbschr:  strchr() DBCS version
  1474. ****************************************************************************/
  1475. unsigned char * _CRTAPI1 My_mbschr(
  1476.     unsigned char *psz, unsigned short uiSep)
  1477. {
  1478.     while (*psz != '\0' && *psz != uiSep) {
  1479.         psz = CharNext(psz);
  1480.     }
  1481.     if (*psz == '\0' && uiSep != '\0') {
  1482.         return NULL;
  1483.     } else {
  1484.         return psz;
  1485.     }
  1486. }
  1487. /****************************************************************************
  1488.     My_mbstok:  strtok() DBCS version
  1489. ****************************************************************************/
  1490. unsigned char * _CRTAPI1 My_mbstok(
  1491.     unsigned char *pszSrc, unsigned char *pszSep)
  1492. {
  1493.     static char *pszSave = NULL;
  1494.     char *pszHead;
  1495.     char *psz;
  1496.  
  1497.     if (pszSrc == NULL) {
  1498.         if (pszSave == NULL) {
  1499.             return NULL;
  1500.         } else {
  1501.             psz = pszSave;
  1502.         }
  1503.     } else {
  1504.         psz = pszSrc;
  1505.     }
  1506.  
  1507.     /*********************************************/
  1508.     /* Skip delimiters to find a head of a token */
  1509.     /*********************************************/
  1510.     while (*psz) {
  1511.         if (IsDBCSLeadByte(*psz)) {
  1512.             break;
  1513.         } else if (NULL == My_mbschr(pszSep, *psz)) {
  1514.             break;
  1515.         }
  1516.         psz++;
  1517.     }
  1518.     if (*psz == '\0') {
  1519.         //No more token
  1520.         return (pszSave = NULL);
  1521.     }
  1522.     pszHead = psz;
  1523.  
  1524.     /******************************/
  1525.     /* Search a Tail of the token */
  1526.     /******************************/
  1527.     while (*psz) {
  1528.         if (IsDBCSLeadByte(*psz)) {
  1529.             psz += 2;
  1530.             continue;
  1531.         } else if (NULL != My_mbschr(pszSep, *psz)) {
  1532.             break;
  1533.         }
  1534.         psz++;
  1535.     }
  1536.     if (*psz == '\0') {
  1537.         pszSave = NULL;
  1538.     } else {
  1539.         //Found next delimiter
  1540.         pszSave = psz + 1;
  1541.         *psz = '\0';
  1542.     }
  1543.     return pszHead;
  1544. }
  1545. /****************************************************************************
  1546.     My_mbsncpy:
  1547. ****************************************************************************/
  1548. unsigned char * _CRTAPI1 My_mbsncpy(
  1549.     unsigned char *psz1, const unsigned char *psz2, size_t nLength)
  1550. {
  1551.     int nLen = (int)nLength;
  1552.     unsigned char *pszSv = psz1;
  1553.  
  1554.     while (0 < nLen) {
  1555.         if (*psz2 == '\0') {
  1556.             *psz1++ = '\0';
  1557.             nLen--;
  1558.         } else if (IsDBCSLeadByte(*psz2)) {
  1559.             if (nLen == 1) {
  1560.                 *psz1 = '\0';
  1561.             } else {
  1562.                 *psz1++ = *psz2++;
  1563.                 *psz1++ = *psz2++;
  1564.             }
  1565.             nLen -= 2;
  1566.         } else {
  1567.             *psz1++ = *psz2++;
  1568.             nLen--;
  1569.         }
  1570.     }
  1571.     return pszSv;
  1572. }
  1573.