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 / ptdlgs.c < prev    next >
C/C++ Source or Header  |  1995-10-28  |  36KB  |  1,344 lines

  1. #include "porttool.h"
  2. #include "port.h"
  3.  
  4. int DLGOFFSET = 100;
  5.  
  6. RESULT    rIssue;
  7.  
  8. HANDLE    hBkFileHeap;
  9. extern HWND    hDlgPort;
  10. extern HWND    hDlgPortStatus;
  11.  
  12.  
  13. /* function prototypes for helper functions */
  14. void WINAPI GrowDialog (HWND, BOOL);
  15. BOOL WINAPI GetHelpFileName (char *);
  16. BOOL WINAPI BuildFileList (char *, LPBKFILELIST *);
  17. BOOL WINAPI AddFile (char *, char *, BKFILELIST *);
  18. BOOL WINAPI RemoveFile (char *, LPBKFILELIST *);
  19. BOOL WINAPI FreeFileList (BKFILELIST *);
  20.  
  21. BOOL MySetEvent (HWND hWnd, HANDLE hEvent);
  22. BOOL MyResetEvent (HWND hWnd, HANDLE hEvent);
  23.  
  24. /* port options dialog */
  25. BOOL WINAPI OptionsDlgProc (
  26.     HWND    hDlg,
  27.     UINT    uMsg,
  28.     UINT    uParam,
  29.     LONG    lParam)
  30. {
  31.     BOOL       bRet = TRUE;
  32. static  DWORD      *dwPTFlags;
  33. static  HFONT      hStrikeoutFont;
  34. static  HFONT      hSystemFont;
  35.     LOGFONT    lf;
  36.  
  37.     switch (uMsg)
  38.     {
  39.     case WM_INITDIALOG:
  40.         /* create strikeout font for ignored tokens */
  41.         hSystemFont = GetStockObject (SYSTEM_FONT);
  42.         GetObject (hSystemFont, sizeof (LOGFONT), &lf);
  43.         lf.lfStrikeOut = TRUE;
  44.         hStrikeoutFont = CreateFontIndirect (&lf);
  45.  
  46.         /* initialize token control with stock system font */
  47.         SendMessage (GetDlgItem (hDlg, IDC_CURTOKEN),
  48.              WM_SETFONT,
  49.              (UINT)hSystemFont,
  50.              FALSE);
  51.  
  52.         /* save dwPTFlags from lParam */
  53.         dwPTFlags = (DWORD *)lParam;
  54.  
  55.         /* initialize current token if any */
  56.         if (*(WORD *)rIssue.lpszToken != MAXTOKENLEN)
  57.         SetDlgItemText (hDlg, IDC_CURTOKEN, rIssue.lpszToken);
  58.         else
  59.         EnableWindow (GetDlgItem (hDlg, IDC_IGNORETOKEN), FALSE);
  60.  
  61.         /* initialize search flag check boxes */
  62.         CheckDlgButton (hDlg, IDC_NOAPIS, (*dwPTFlags & PT_NOAPIS));
  63.         CheckDlgButton (hDlg, IDC_NOMESSAGES, (*dwPTFlags & PT_NOMESSAGES));
  64.         CheckDlgButton (hDlg, IDC_NOSTRUCTURES, (*dwPTFlags & PT_NOSTRUCTURES));
  65.         CheckDlgButton (hDlg, IDC_NOMACROS, (*dwPTFlags & PT_NOMACROS));
  66.         CheckDlgButton (hDlg, IDC_NOCONSTANTS, (*dwPTFlags & PT_NOCONSTANTS));
  67.         CheckDlgButton (hDlg, IDC_NOTYPES, (*dwPTFlags & PT_NOTYPES));
  68.         CheckDlgButton (hDlg, IDC_NOCUSTOM, (*dwPTFlags & PT_NOCUSTOM));
  69.         CheckDlgButton (hDlg, IDC_IGNORECASE, (*dwPTFlags & PT_IGNORECASE));
  70.  
  71.         /* set focus to first check box, return FALSE */
  72.         SetFocus (GetDlgItem (hDlg, IDC_NOAPIS));
  73.         bRet = FALSE;
  74.         break;
  75.  
  76.     case WM_COMMAND:
  77.         switch (LOWORD (uParam))
  78.         {
  79.         case IDOK:
  80.             /* get check box states and return as FLAGS in UM_PORT message */
  81.             *dwPTFlags = (*dwPTFlags & ~PT_IGNORECASE) ^
  82.             (IsDlgButtonChecked (hDlg, IDC_IGNORECASE) ? PT_IGNORECASE : 0);
  83.             *dwPTFlags = (*dwPTFlags & ~PT_NOAPIS) ^
  84.             (IsDlgButtonChecked (hDlg, IDC_NOAPIS) ? PT_NOAPIS : 0);
  85.             *dwPTFlags = (*dwPTFlags & ~PT_NOMESSAGES) ^
  86.             (IsDlgButtonChecked (hDlg, IDC_NOMESSAGES) ? PT_NOMESSAGES : 0);
  87.             *dwPTFlags = (*dwPTFlags & ~PT_NOSTRUCTURES) ^
  88.             (IsDlgButtonChecked (hDlg, IDC_NOSTRUCTURES) ? PT_NOSTRUCTURES : 0);
  89.             *dwPTFlags = (*dwPTFlags & ~PT_NOMACROS) ^
  90.             (IsDlgButtonChecked (hDlg, IDC_NOMACROS) ? PT_NOMACROS : 0);
  91.             *dwPTFlags = (*dwPTFlags & ~PT_NOCONSTANTS) ^
  92.             (IsDlgButtonChecked (hDlg, IDC_NOCONSTANTS) ? PT_NOCONSTANTS : 0);
  93.             *dwPTFlags = (*dwPTFlags & ~PT_NOTYPES) ^
  94.             (IsDlgButtonChecked (hDlg, IDC_NOTYPES) ? PT_NOTYPES : 0);
  95.             *dwPTFlags = (*dwPTFlags & ~PT_NOCUSTOM) ^
  96.             (IsDlgButtonChecked (hDlg, IDC_NOCUSTOM) ? PT_NOCUSTOM : 0);
  97.  
  98.         case IDCANCEL:
  99.             SendMessage (GetDlgItem (hDlg, IDC_CURTOKEN), WM_SETFONT, 0, FALSE);
  100.             DeleteObject (hStrikeoutFont);
  101.             EndDialog (hDlg, LOWORD (uParam) == IDOK);
  102.             break;
  103.  
  104.         case IDC_IGNORETOKEN:
  105.             /* toggle ignore bit */
  106.             *dwPTFlags ^= PT_IGNORETOKEN;
  107.  
  108.             /* have control draw in strikeout if ignored */
  109.             if (*dwPTFlags & PT_IGNORETOKEN)
  110.             SendMessage (GetDlgItem (hDlg, IDC_CURTOKEN),
  111.                      WM_SETFONT,
  112.                      (UINT)hStrikeoutFont,
  113.                      TRUE);
  114.             /* else draw in system font */
  115.             else
  116.             SendMessage (GetDlgItem (hDlg, IDC_CURTOKEN),
  117.                      WM_SETFONT,
  118.                      (UINT)hSystemFont,
  119.                      TRUE);
  120.             break;
  121.         }
  122.         break;
  123.  
  124.     default:
  125.         bRet = FALSE;
  126.         break;
  127.     }
  128.  
  129.     /* return (message was processed); */
  130.     return bRet;
  131. }
  132.  
  133.  
  134.  
  135. /* port options dialog */
  136. BOOL WINAPI PortDlgProc (
  137.     HWND    hDlg,
  138.     UINT    uMsg,
  139.     UINT    uParam,
  140.     LONG    lParam)
  141. {
  142.     BOOL    bRet = TRUE;
  143. static  DWORD   dwPTFlags;
  144. static  BOOL    bSearching = TRUE;
  145. static  BOOL    bHelpActive = FALSE, bIsHelpFile = FALSE;
  146. static  HBRUSH  hBkBrush;
  147. static  HWND    hWndEdit;
  148. static  HANDLE  hEditData = NULL;
  149. static  int     nIssues = 0;
  150. static  int     iLineNo, iStartPos;
  151. static  HLOCAL  hToken, hHelp, hIssue, hSuggest;
  152. static  HLOCAL  hEditLine;
  153.  
  154. static  UINT    uLen = 0;
  155.  
  156.  
  157.     switch (uMsg)
  158.     {
  159.     case WM_INITDIALOG:
  160.         {
  161.         char    lpszTitle[MAX_PATH];
  162.         char    lpszFilename[MAX_PATH];
  163.         RECT    rc;
  164.  
  165.         HDC     hDC;
  166.         HFONT   hFont;
  167.         TEXTMETRIC tm;
  168.  
  169.         hFont = GetStockObject(SYSTEM_FONT);
  170.         hDC = GetDC(NULL);
  171.         hFont = SelectObject(hDC, hFont);
  172.         GetTextMetrics(hDC, &tm);
  173.         SelectObject(hDC, hFont);
  174.         ReleaseDC(NULL, hDC);
  175.         DLGOFFSET = tm.tmHeight * 5;
  176.  
  177.         /* reposition self on bottom of screen */
  178.         GetWindowRect (hDlg, &rc);
  179.         SetWindowPos (hDlg,
  180.               NULL,
  181.               rc.left,
  182.               GetSystemMetrics (SM_CYSCREEN) -
  183.                (rc.bottom - rc.top + DLGOFFSET),
  184.               rc.right-rc.left,
  185.               rc.bottom-rc.top,
  186.               SWP_NOZORDER | SWP_NOSIZE);
  187.  
  188.         /* set help available flag */
  189.         if (GetHelpFileName (lpszTitle))
  190.         {
  191.         EnableWindow (GetDlgItem (hDlg, IDC_HELPM), TRUE);
  192.         bIsHelpFile = TRUE;
  193.         }
  194.  
  195.         /* allocate strings for Issue struct from local heap to reduce stack overhead */
  196.         if (!(rIssue.lpszToken = LocalLock (hToken = LocalAlloc (LHND, MAXTOKENLEN))) ||
  197.         !(rIssue.lpszHelpStr = LocalLock (hHelp = LocalAlloc (LHND, MAXHELPLEN))) ||
  198.         !(rIssue.lpszIssue = LocalLock (hIssue = LocalAlloc (LHND, MAXISSUELEN))) ||
  199.         !(rIssue.lpszSuggest = LocalLock (hSuggest = LocalAlloc (LHND, MAXSUGGESTLEN))))
  200.         {
  201.         ErrorNotify (hDlg, IDS_MEMORYFAILED);
  202.         PostMessage (hDlg, WM_COMMAND, IDC_DONE, 0);
  203.         break;
  204.         }
  205.         /* initialize line and token offset position stuff */
  206.         iLineNo = 0;
  207.         iStartPos = 0;
  208.         rIssue.nPosToken = 0;
  209.  
  210.         /* initialize background brush for use in WM_CTLCOLOR message */
  211.         hBkBrush = (HBRUSH)GetClassLong (hDlg, GCL_HBRBACKGROUND);
  212.  
  213.         /* set initial search flags to default */
  214.         dwPTFlags = 0;
  215.  
  216.         /* initialize filename in caption */
  217.         LoadString (GetModuleHandle (NULL), IDS_PORTFILE, lpszTitle, MAX_PATH);
  218.         GetFileFromPath (lpszFilePath, lpszFilename);
  219.         strcat (lpszTitle, lpszFilename);
  220.         SetWindowText (hDlg, lpszTitle);
  221.  
  222.         /* IDC_SUGGESTION to SW_HIDE */
  223.         ShowWindow (GetDlgItem (hDlg, IDC_SUGGESTION), SW_HIDE);
  224.         ShowWindow (GetDlgItem (hDlg, IDC_SUGGESTLABEL), SW_HIDE);
  225.  
  226.         /* get edit window and data handle */
  227.         hWndEdit = (HWND)GetWindowLong (GetParent (hDlg), WL_HWNDEDIT);
  228.  
  229. #if !defined (WIN32)
  230.  
  231.         hEditData = (HANDLE)SendMessage (hWndEdit, EM_GETHANDLE, 0, 0);
  232.  
  233. #else
  234.         {
  235.         char    *lpEditData;
  236.         char    sz[80];
  237.         MEMORYSTATUS memstat;
  238.  
  239.         uLen = GetWindowTextLength (hWndEdit);
  240.         hEditData = LocalAlloc (LHND, uLen+1);
  241.         if (hEditData == NULL) {
  242.             memstat.dwLength = sizeof(MEMORYSTATUS);
  243.             GlobalMemoryStatus (&memstat);
  244.             wsprintf (sz, "Failed Allocation: %u | %u (%u%%)", (UINT)uLen+1, (UINT)memstat.dwAvailPhys, memstat.dwMemoryLoad);
  245.             //MessageBox (GetFocus(), sz, "PortTool", MB_OK);
  246.             uLen = 500000;
  247.             while (hEditData == NULL && uLen > 1000) {
  248.             uLen -= 1000;
  249.             hEditData = LocalAlloc (LHND, uLen+1);
  250.             }
  251.             wsprintf (sz, "hEditData = %u : uLen = %u", (UINT)hEditData, (UINT)uLen);
  252.             //MessageBox (GetFocus(), sz, "PortTool", MB_OK);
  253.         }
  254.         lpEditData = LocalLock (hEditData);
  255.         if (lpEditData == NULL) {
  256.             MessageBox (GetFocus(), "Unalble To Lock Memory!", "PortTool", MB_OK);
  257.         } else {
  258.             UINT i;
  259.             i = GetWindowText (hWndEdit, lpEditData, uLen+1);
  260.             wsprintf (sz, "length: %u", i);
  261.             //MessageBox (GetFocus(), sz, "PortTool", MB_OK);
  262.         }
  263.         LocalUnlock (hEditData);
  264.         }
  265. #endif
  266.  
  267.         /* allocate here, reallocate later when needed */
  268.         hEditLine = LocalAlloc (LHND, 1);
  269.  
  270.         /* post message to start ball rolling */
  271.         PostMessage (hDlg, WM_COMMAND, (UINT)IDC_CONTINUE, 0);
  272.  
  273.         /* don't worry about focus here since were going to drive the search anyway */
  274.         bRet = TRUE;
  275.         }
  276.         //MessageBox (GetFocus(), "End Of Init", "PortTool", MB_OK);
  277.         break;
  278.  
  279.     case WM_COMMAND:
  280.         switch (LOWORD (uParam))
  281.         {
  282.         case IDC_CONTINUE:
  283.             {
  284.             int     iLastLine, nCharOffset, nLineLen;
  285.             MSG     msg;
  286.             char    lpszBuff[MAXTOKENLEN];
  287.             char    *lpszLine;
  288.             char    *lpLine;
  289.             char    *lpEditData;
  290.  
  291.             /* disable continue button */
  292.             EnableWindow (GetDlgItem (hDlg, IDC_CONTINUE), FALSE);
  293.             EnableWindow (GetDlgItem (hDlg, IDC_OPTIONS), FALSE);
  294.             EnableWindow (GetDlgItem (hDlg, IDCANCEL), TRUE);
  295.  
  296.             /* set IDC_SEARCHFOUND to green searching */
  297.             LoadString (GetModuleHandle (NULL), IDS_SEARCHING,
  298.                 lpszBuff,
  299.                 sizeof (lpszBuff));
  300.             SetWindowText (GetDlgItem (hDlg, IDC_SEARCHFOUND), lpszBuff);
  301.             bSearching = TRUE;
  302.  
  303.             /* set last line */
  304.             iLastLine = (int)SendMessage (hWndEdit, EM_GETLINECOUNT, 0, 0);
  305.  
  306.             /* find next port issue */
  307.             while (TRUE)
  308.             {
  309.             if (iLineNo >= iLastLine)
  310.                 {
  311.                 /* no more issues found, so clean up and go away */
  312.                 ErrorNotify (hDlg, IDS_NOMOREPORTISSUES);
  313.  
  314.                 /* nullify any selection in line edit control */
  315.                 SendMessage (GetDlgItem (hDlg, IDC_LINE), EM_SETSEL, 0, 0);
  316.                 break;
  317.                 }
  318.  
  319.             /* increment line no */
  320.             SetWindowText (GetDlgItem (hDlg, IDC_LINENO),
  321.                        itoa (iLineNo, lpszBuff, 10));
  322.  
  323.             /* get length and number of edit line */
  324.             nCharOffset = SendMessage (hWndEdit, EM_LINEINDEX, iLineNo, 0);
  325.             if ((nLineLen = SendMessage (hWndEdit, EM_LINELENGTH, nCharOffset, 0)) <= 2)
  326.                 goto NEXT_LINE;
  327.  
  328.             /* allocate enough memory for edit line */
  329.             if (!(hEditLine = LocalReAlloc (hEditLine,
  330.                             nLineLen+1,
  331.                             LHND)))
  332.                 {
  333.                 /* no more issues found, so clean up and go away */
  334.                 ErrorNotify (hDlg, IDS_MEMORYFAILED);
  335.                 PostMessage (hDlg, WM_COMMAND, IDC_DONE, 0);
  336.                 break;
  337.                 }
  338.  
  339.             /* get line from edit control, and null terminate */
  340.  
  341.             /* get edit window and data handle */
  342.  
  343.             lpEditData = LocalLock (hEditData);
  344.  
  345.             lpLine = lpszLine = LocalLock (hEditLine);
  346.  
  347.             strncpy (lpszLine, lpEditData+nCharOffset, nLineLen);
  348.             lpszLine[nLineLen] = 0;
  349.  
  350.             /* increment the token position for multiple errors in a line */
  351.             lpLine += iStartPos;
  352.             LocalUnlock (hEditData);
  353.  
  354.             /* initialize line and hilight token */
  355.             SetWindowText (GetDlgItem (hDlg, IDC_LINE), lpszLine);
  356.  
  357.             /* reinitialize rIssue strings lengths */
  358.             *(WORD *)rIssue.lpszToken = MAXTOKENLEN;
  359.             *(WORD *)rIssue.lpszHelpStr = MAXHELPLEN;
  360.             *(WORD *)rIssue.lpszIssue = MAXISSUELEN;
  361.             *(WORD *)rIssue.lpszSuggest = MAXSUGGESTLEN;
  362.  
  363.             /* search next line */
  364.             if (CheckString (lpLine, dwPTFlags, &rIssue))
  365.                 {
  366.                 /* set SEARCHFOUND string to found */
  367.                 LoadString (GetModuleHandle (NULL),
  368.                     IDS_FOUND,
  369.                     lpszBuff,
  370.                     sizeof (lpszBuff));
  371.                 strcat (lpszBuff, rIssue.lpszToken);
  372.                 SetWindowText (GetDlgItem (hDlg, IDC_SEARCHFOUND), lpszBuff);
  373.  
  374.                 /* reenable options button */
  375.                 EnableWindow (GetDlgItem (hDlg, IDC_OPTIONS), TRUE);
  376.  
  377.                 /* set searching flag off */
  378.                 bSearching = FALSE;
  379.  
  380.                 /* increment issue cnt */
  381.                 SetWindowText (GetDlgItem (hDlg, IDC_ISSUECNT),
  382.                        itoa (++nIssues, lpszBuff, 10));
  383.  
  384.                 /* initialize Issue */
  385.                 SetWindowText (GetDlgItem (hDlg, IDC_ISSUE), rIssue.lpszIssue);
  386.  
  387.                 /* if help, enble button */
  388.                 EnableWindow (GetDlgItem (hDlg, IDC_HELPM),
  389.                       ((*(rIssue.lpszSuggest) != 0) && bIsHelpFile));
  390.  
  391.                 /* if suggest, show suggestion */
  392.                 if (*(rIssue.lpszSuggest))
  393.                 {
  394.                 SetWindowText (GetDlgItem (hDlg, IDC_SUGGESTION),
  395.                            rIssue.lpszSuggest);
  396.                 if (!IsWindowVisible (GetDlgItem (hDlg, IDC_SUGGESTION)))
  397.                     GrowDialog (hDlg, TRUE);
  398.                 }
  399.  
  400.                 else if (IsWindowVisible (GetDlgItem (hDlg, IDC_SUGGESTION)))
  401.                 GrowDialog (hDlg, FALSE);
  402.  
  403.                 /* scroll parent edit control and select offending text */
  404.                 SendMessage (hWndEdit, EM_LINESCROLL, 0, iLineNo -
  405.                 SendMessage (hWndEdit, EM_GETFIRSTVISIBLELINE, 0, 0));
  406.                 SendMessage (hWndEdit,
  407.                      EM_SETSEL,
  408.                      iStartPos + nCharOffset + rIssue.nPosToken,
  409.                      iStartPos + nCharOffset + rIssue.nPosToken +
  410.                          strlen (rIssue.lpszToken));
  411.  
  412.                 /* select text in line edit control */
  413.                 SendMessage (GetDlgItem (hDlg, IDC_LINE),
  414.                      EM_SETSEL,
  415.                      iStartPos + rIssue.nPosToken,
  416.                      iStartPos + rIssue.nPosToken +
  417.                          strlen (rIssue.lpszToken));
  418.  
  419.                 /* reset nPosToken to check rest of line */
  420.                 iStartPos += (rIssue.nPosToken + strlen (rIssue.lpszToken));
  421.                 LocalUnlock (hEditLine);
  422.                 break;
  423.                 }
  424.  
  425.             /* call peek message to let user cancel if they choose */
  426.             if (PeekMessage (&msg,
  427.                      GetDlgItem (hDlg, IDCANCEL),
  428.                      WM_LBUTTONDOWN,
  429.                      WM_LBUTTONDOWN,
  430.                      PM_REMOVE))
  431.                 {
  432.                 /* reset appropriate buttons */
  433.                 EnableWindow (GetDlgItem (hDlg, IDCANCEL), FALSE);
  434.                 EnableWindow (GetDlgItem (hDlg, IDC_HELPM), FALSE);
  435.                 EnableWindow (GetDlgItem (hDlg, IDC_OPTIONS), TRUE);
  436.  
  437.                 /* break to let message get delivered */
  438.                 break;
  439.                 }
  440.  
  441.             /* also let the user exit from searching */
  442.             if (PeekMessage (&msg,
  443.                      GetDlgItem (hDlg, IDC_DONE),
  444.                      WM_LBUTTONDOWN,
  445.                      WM_LBUTTONDOWN,
  446.                      PM_REMOVE))
  447.                 {
  448.                 PostMessage (hDlg, WM_COMMAND, IDC_DONE, 0);
  449.                 break;
  450.                 }
  451.  
  452.             /* unlock local edit line */
  453.             LocalUnlock (hEditLine);
  454.  
  455.             /* reset token position */
  456.             rIssue.nPosToken = 0;
  457.             iStartPos = 0;
  458. NEXT_LINE:
  459.             /* increment line and continue */
  460.             iLineNo++;
  461.             }
  462.  
  463.             /* enable continue button unless at end of file */
  464.             if (iLineNo < iLastLine)
  465.             {
  466.             EnableWindow (GetDlgItem (hDlg, IDC_CONTINUE), TRUE);
  467.             SetFocus (GetDlgItem (hDlg, IDC_CONTINUE));
  468.             }
  469.             else
  470.             {
  471.             EnableWindow (GetDlgItem (hDlg, IDC_CONTINUE), FALSE);
  472.             EnableWindow (GetDlgItem (hDlg, IDCANCEL), FALSE);
  473.             SetFocus (GetDlgItem (hDlg, IDC_DONE));
  474.             }
  475.             }
  476.             break;
  477.  
  478.         case WM_CLOSE:
  479.         case IDC_DONE:
  480.             {
  481.             char    lpszFile[MAX_PATH];
  482.  
  483.             if (bHelpActive &&
  484.             GetHelpFileName (lpszFile))
  485.             WinHelp (hDlg, lpszFile, HELP_QUIT, 0);
  486.  
  487.             /* clean up and go away */
  488.             LocalUnlock (hToken); LocalFree (hToken);
  489.             LocalUnlock (hHelp); LocalFree (hHelp);
  490.             LocalUnlock (hIssue); LocalFree (hIssue);
  491.             LocalUnlock (hSuggest); LocalFree (hSuggest);
  492.             LocalFree (hEditLine);
  493.             DestroyWindow (hDlg);
  494.             hDlgPort = NULL;
  495.  
  496.             }
  497.             break;
  498.  
  499.         case IDC_OPTIONS:
  500.             {
  501.             DWORD    dwOptions = dwPTFlags;
  502.  
  503.             /* call dialog to start port process */
  504.             if (DialogBoxParam (GetModuleHandle (NULL),
  505.                     IDD_OPTIONSDLG,
  506.                     hDlg,
  507.                     OptionsDlgProc,
  508.                     (LPARAM)&dwOptions))
  509.             {
  510.             dwPTFlags = dwOptions;
  511.  
  512.             /* if PT_IGNORETOKEN, call CheckString */
  513.             if (dwOptions & PT_IGNORETOKEN)
  514.                 {
  515.                 CheckString (rIssue.lpszToken, dwPTFlags, NULL);
  516.                 dwPTFlags ^= PT_IGNORETOKEN;
  517.                 }
  518.             }
  519.  
  520.             }
  521.             break;
  522.  
  523.         case IDC_HELPM:
  524.             {
  525.             char    lpszFile[MAX_PATH];
  526.  
  527.             if (bIsHelpFile && GetHelpFileName (lpszFile))
  528.             {
  529.             WinHelp (hDlg, lpszFile, HELP_KEY, (DWORD)rIssue.lpszHelpStr);
  530.             bHelpActive = TRUE;
  531.             }
  532.             }
  533.             break;
  534.  
  535.         case IDC_RESTART:
  536.             iLineNo = 0;
  537.             rIssue.nPosToken = 0;
  538.             iStartPos = 0;
  539.             PostMessage (hDlg, WM_COMMAND, IDC_CONTINUE, 0);
  540.             break;
  541.         }
  542.         break;
  543.  
  544.     default:
  545.         bRet = FALSE;
  546.         break;
  547.     }
  548.  
  549.     /* return (message was processed); */
  550.     return bRet;
  551. }
  552.  
  553.  
  554.  
  555.  
  556. /* background porting status dialog */
  557. BOOL WINAPI BkPortDlgProc (
  558.     HWND    hDlg,
  559.     UINT    uMsg,
  560.     UINT    uParam,
  561.     LONG    lParam)
  562. {
  563.       BOOL          bRet = TRUE;
  564.       char          szFileName[MAX_PATH];
  565.       char          szFilePath[MAX_PATH];
  566. static    BKFILELIST    *lpbkFiles;
  567. static    int           iCurThread;
  568. static    BOOL          bStarted = FALSE;
  569.       BKFILELIST    *lpNode;
  570.  
  571.     //    char szDebug[80];
  572.  
  573.     // wsprintf (szDebug, "%i : [0x%X - 0x%X]", uMsg, uParam, lParam);
  574.     // OutputDebugString (szDebug);
  575.  
  576.     switch (uMsg)
  577.     {
  578.     case WM_INITDIALOG:
  579.         {
  580.         HWND          hIssues = GetDlgItem (hDlg, IDC_ISSUES);
  581.         HWND          hLines = GetDlgItem (hDlg, IDC_LINES);
  582.         HWND          hComplete = GetDlgItem (hDlg, IDC_COMPLETE);
  583.  
  584.         /* set background icon to porttool background icon and start minimized */
  585.         SetClassLong (hDlg,
  586.               GCL_HICON,
  587.               (LONG)LoadIcon (GetModuleHandle (NULL), IDBkPort));
  588.  
  589.         lpbkFiles = NULL;
  590.         iCurThread = -1;
  591.  
  592.         /* build list of files to port from lParam */
  593.         if (lParam)
  594.         {
  595.         if (!BuildFileList ((char *)lParam, &lpbkFiles))
  596.             {
  597.             lpbkFiles = NULL;
  598.             break;
  599.             }
  600.         }
  601.  
  602.         else
  603.         {
  604.         /* get file from user first */
  605.         *szFileName = 0;
  606.         *szFilePath = 0;
  607.  
  608.         GetFileName (hDlg, szFileName, szFilePath);
  609.         if (!BuildFileList (szFilePath, &lpbkFiles))
  610.             {
  611.             lpbkFiles = NULL;
  612.             break;
  613.             }
  614.         }
  615.  
  616.         lpNode = lpbkFiles;
  617.         /* initialize each file in list */
  618.         while (lpNode)
  619.         {
  620.         /* add filename to listbox */
  621.         SendMessage (GetDlgItem (hDlg, IDC_FILELIST),
  622.                  LB_ADDSTRING,
  623.                  0,
  624.                  (LPARAM)lpNode->bkFile.szFile);
  625.  
  626.         /* initialize some stuff */
  627.         lpNode->bkFile.hDlg = hDlg;
  628.         lpNode->bkFile.dwPTFlags = PT_DEFAULT;
  629.  
  630.         /* start background thread on each file */
  631.         if (!StartBkPortThread (&lpNode->bkFile)) {
  632.             MessageBox(GetFocus(), "Failed to spawn background porting thread", "PortTool", MB_OK);
  633.         }
  634.  
  635.         /* traverse list */
  636.         lpNode = lpNode->Next;
  637.         }
  638.  
  639.         /* select first thread in listbox */
  640.         SendMessage (GetDlgItem (hDlg, IDC_FILELIST), LB_SETCURSEL, 0, 0);
  641.         SetDlgItemText (hDlg, IDC_FILEPATH, lpbkFiles->bkFile.szFilePath);
  642.  
  643.         /* if started with /b switch */
  644.         if (!GetParent (hDlg))
  645.         ShowWindow (hDlg, SW_SHOWMINIMIZED);
  646.         else
  647.         MySetEvent (hDlg, lpbkFiles->hEvents[BKPORT_STATUS]);
  648.  
  649.         iCurThread = 0;
  650.         bStarted = TRUE;
  651.         }
  652.         break;
  653.  
  654.     case WM_SHOWWINDOW:
  655.         if (bStarted)
  656.         {
  657.         int    i = 0;
  658.  
  659.         lpNode = lpbkFiles;
  660.         while (i++ < iCurThread)
  661.             lpNode = lpNode->Next;
  662.  
  663.         if (!uParam && lpNode)
  664.             MyResetEvent (hDlg, lpNode->hEvents[BKPORT_STATUS]);
  665.         else if(lpNode)
  666.             MySetEvent (hDlg, lpNode->hEvents[BKPORT_STATUS]);
  667.         }
  668.         break;
  669.  
  670.     case WM_SIZE:
  671.         if (bStarted) {
  672.             int    i = 0;
  673.  
  674.             lpNode = lpbkFiles;
  675.     
  676.             while (i++ < iCurThread) {
  677.                 lpNode = lpNode->Next;
  678.             }
  679.  
  680.             if (uParam == SIZEICONIC && lpNode) {
  681.                 MyResetEvent (hDlg, lpNode->hEvents[BKPORT_STATUS]);
  682.             } else if(lpNode) {
  683.                 MySetEvent (hDlg, lpNode->hEvents[BKPORT_STATUS]);
  684.             }
  685.         }
  686.         break;
  687.  
  688.     case UM_STATUSUPDATE:
  689.         {
  690.         char    Buff[10];
  691.  
  692.         /* update status info controls */
  693.         SetDlgItemText (hDlg, IDC_ISSUES, itoa (LOWORD (uParam), Buff, 10));
  694.         SetDlgItemText (hDlg, IDC_COMPLETE, itoa (HIWORD (uParam), Buff, 10));
  695.         SetDlgItemText (hDlg, IDC_LINES, itoa (lParam, Buff, 10));
  696.         }
  697.         break;
  698.  
  699.     case UM_THREADCOMPLETE:
  700.         {
  701.         int    iThread = 0;
  702.  
  703.         /* find handle in list */
  704.         lpNode = lpbkFiles;
  705.         while (lpNode)
  706.         {
  707.         if ((HANDLE)uParam == lpNode->bkFile.hThread)
  708.             break;
  709.         lpNode = lpNode->Next;
  710.         iThread++;
  711.         }
  712.  
  713.         if (lpNode)
  714.         {
  715.         /* remove file list item */
  716.         RemoveFile (lpNode->bkFile.szFilePath, &lpbkFiles);
  717.  
  718.         /* remove item from list box */
  719.         SendMessage (GetDlgItem (hDlg, IDC_FILELIST),
  720.                  LB_DELETESTRING,
  721.                  iThread,
  722.                  0);
  723.  
  724.         /* if current thread ended and more threads exist */
  725.         if (iThread == iCurThread &&
  726.             lpbkFiles             &&
  727.             SendMessage (GetDlgItem (hDlg, IDC_FILELIST), LB_GETCOUNT, 0, 0))
  728.             {
  729.             SendMessage (GetDlgItem (hDlg, IDC_FILELIST), LB_SETCURSEL, 0, 0);
  730.             MySetEvent (hDlg, lpbkFiles->hEvents[BKPORT_STATUS]);
  731.             iCurThread = 0;
  732.             }
  733.  
  734.         else if (iThread == iCurThread)
  735.             {
  736.             iCurThread = -1;
  737.             PostMessage (hDlg, WM_COMMAND, IDC_BKDONE, 0);
  738.             }
  739.  
  740.         /* clean up controls */
  741.         SetDlgItemText (hDlg, IDC_FILEPATH, "");
  742.         PostMessage (hDlg, UM_STATUSUPDATE, 0, 0);
  743.         }
  744.  
  745.         else
  746.         {
  747.                 CHAR szBuf[MAX_PATH];
  748.                 LoadString((HANDLE)GetModuleHandle(NULL),
  749.                     IDS_ERR_INVALID_THREADHND,
  750.                     szBuf,sizeof(szBuf));
  751.         MessageBox (hDlg, szBuf, NULL, MB_ICONSTOP | MB_OK);
  752.         ExitProcess (FALSE);
  753.         }
  754.  
  755.         }
  756.         break;
  757.  
  758.     case WM_COMMAND:
  759.         switch (LOWORD (uParam))
  760.         {
  761.         case IDC_FILELIST:
  762.             /* if new file selected change update signal to active thread */
  763.             if (HIWORD (uParam) == LBN_SELCHANGE)
  764.             {
  765.             int    i = 0;
  766.             int    iNewThread = SendMessage (GetDlgItem (hDlg, IDC_FILELIST),
  767.                              LB_GETCURSEL,
  768.                              0,
  769.                              0);
  770.  
  771.             /* reset current thread */
  772.             lpNode = lpbkFiles;
  773.             while (lpNode)
  774.                 {
  775.                 if (i == iCurThread)
  776.                 MyResetEvent (hDlg, lpNode->hEvents[BKPORT_STATUS]);
  777.  
  778.                 if (i == iNewThread)
  779.                 {
  780.                 MySetEvent (hDlg, lpNode->hEvents[BKPORT_STATUS]);
  781.                 SetDlgItemText (hDlg,
  782.                         IDC_FILEPATH,
  783.                         lpNode->bkFile.szFilePath);
  784.                 }
  785.  
  786.                 lpNode = lpNode->Next;
  787.                 i++;
  788.                 }
  789.  
  790.             iCurThread = iNewThread;
  791.             }
  792.             break;
  793.  
  794.         case IDC_ABORTFILE:
  795.             {
  796.             int        i = 0;
  797.             HCURSOR    hOldCursor;
  798.  
  799.             /* reset current thread */
  800.             lpNode = lpbkFiles;
  801.             while (lpNode)
  802.             {
  803.             if (i == iCurThread)
  804.                 {
  805.                 /* put hourglass cursor up */
  806.                 hOldCursor = (HCURSOR)SetClassLong (hDlg, GCL_HCURSOR, 0);
  807.                 SetCursor (LoadCursor (NULL, IDC_WAIT));
  808.  
  809.                 /* abort porting file where it is */
  810.                 MySetEvent (hDlg, lpNode->hEvents[BKPORT_ABORT]);
  811.  
  812.                 /* remove file from list when thread is dead */
  813.                 WaitForSingleObject (lpNode->bkFile.hThread, INFINITE);
  814.                 RemoveFile (lpNode->bkFile.szFilePath, &lpbkFiles);
  815.  
  816.                 /* replace original cursor */
  817.                 SetClassLong (hDlg, GCL_HCURSOR, (LONG)hOldCursor);
  818.                 SetCursor (hOldCursor);
  819.  
  820.                 /* update listbox */
  821.                 SendMessage (GetDlgItem (hDlg, IDC_FILELIST),
  822.                      LB_DELETESTRING,
  823.                      iCurThread,
  824.                      0);
  825.  
  826.                 /* select new event if any in listbox */
  827.                 if (SendMessage (GetDlgItem (hDlg, IDC_FILELIST),
  828.                          LB_GETCOUNT,
  829.                          0,
  830.                          0))
  831.                 {
  832.                 SendMessage (GetDlgItem (hDlg, IDC_FILELIST),
  833.                          LB_SETCURSEL,
  834.                          0,
  835.                          0);
  836.                 MySetEvent (hDlg, lpbkFiles->hEvents[BKPORT_STATUS]);
  837.                 iCurThread = 0;
  838.                 }
  839.  
  840.                 else
  841.                 {
  842.                 iCurThread = -1;
  843.                 PostMessage (hDlg, WM_COMMAND, IDC_DONE, 0);
  844.                 }
  845.  
  846.                 /* clean up controls */
  847.                 SetDlgItemText (hDlg, IDC_FILEPATH, "");
  848.                 PostMessage (hDlg, UM_STATUSUPDATE, 0, 0);
  849.                 break;
  850.                 }
  851.  
  852.             lpNode = lpNode->Next;
  853.             i++;
  854.             }
  855.             }
  856.             break;
  857.  
  858.         case IDC_ADDFILE:
  859.             {
  860.             /* get file from user first */
  861.             *szFileName = 0;
  862.             *szFilePath = 0;
  863.  
  864.             /* add a file to the list */
  865.             if (GetFileName (hDlg, szFileName, szFilePath))
  866.             {
  867.             /* if new list */
  868.             if (!lpbkFiles)
  869.             {
  870.                 if (!BuildFileList (szFilePath, &lpbkFiles))
  871.                 {
  872.                     lpbkFiles = NULL;
  873.                     break;
  874.                 }
  875.             }
  876.             else if (!AddFile (szFilePath, szFileName, lpbkFiles))
  877.                 break;
  878.  
  879.             /* find node in list */
  880.             lpNode = lpbkFiles;
  881.             while (lpNode)
  882.                 {
  883.                 if (!strcmp (lpNode->bkFile.szFilePath, szFilePath))
  884.                 break;
  885.                 lpNode = lpNode->Next;
  886.                 }
  887.  
  888.             if (lpNode)
  889.                 {
  890.                 /* add filename to listbox */
  891.                 SendMessage (GetDlgItem (hDlg, IDC_FILELIST),
  892.                      LB_ADDSTRING,
  893.                      0,
  894.                      (LPARAM)lpNode->bkFile.szFile);
  895.  
  896.                 /* initialize some stuff */
  897.                 lpNode->bkFile.hDlg = hDlg;
  898.                 lpNode->bkFile.dwPTFlags = PT_DEFAULT;
  899.  
  900.                 /* start background thread on this file */
  901.                 StartBkPortThread (&lpNode->bkFile);
  902.  
  903.                 /* if first thread */
  904.                 if (iCurThread == -1 ||
  905.                 SendMessage (GetDlgItem (hDlg, IDC_FILELIST),
  906.                          LB_GETCOUNT, 0, 0) == 1)
  907.                 {
  908.                 iCurThread = 0;
  909.                 SendMessage (GetDlgItem (hDlg, IDC_FILELIST),
  910.                          LB_SETCURSEL,
  911.                          0,
  912.                          0);
  913.                 SendMessage (hDlg,
  914.                          WM_COMMAND,
  915.                          MAKELONG (IDC_FILELIST, LBN_SELCHANGE),
  916.                          0);
  917.                 }
  918.                 }
  919.             }
  920.             }
  921.             break;
  922.  
  923.         case IDC_CHANGEOPTIONS:
  924.             {
  925.             DWORD    dwFlags;
  926.  
  927.             dwFlags = 0L;
  928.             dwFlags = (dwFlags & ~PT_IGNORECASE) ^
  929.             (IsDlgButtonChecked (hDlg, IDC_BKIGNORECASE) ? PT_IGNORECASE : 0);
  930.             dwFlags = (dwFlags & ~PT_NOAPIS) ^
  931.             (IsDlgButtonChecked (hDlg, IDC_BKNOAPIS) ? PT_NOAPIS : 0);
  932.             dwFlags = (dwFlags & ~PT_NOMESSAGES) ^
  933.             (IsDlgButtonChecked (hDlg, IDC_BKNOMESSAGES) ? PT_NOMESSAGES : 0);
  934.             dwFlags = (dwFlags & ~PT_NOSTRUCTURES) ^
  935.             (IsDlgButtonChecked (hDlg, IDC_BKNOSTRUCTURES) ? PT_NOSTRUCTURES : 0);
  936.             dwFlags = (dwFlags & ~PT_NOMACROS) ^
  937.             (IsDlgButtonChecked (hDlg, IDC_BKNOMACROS) ? PT_NOMACROS : 0);
  938.             dwFlags = (dwFlags & ~PT_NOCONSTANTS) ^
  939.             (IsDlgButtonChecked (hDlg, IDC_BKNOCONSTANTS) ? PT_NOCONSTANTS : 0);
  940.             dwFlags = (dwFlags & ~PT_NOTYPES) ^
  941.             (IsDlgButtonChecked (hDlg, IDC_BKNOTYPES) ? PT_NOTYPES : 0);
  942.             dwFlags = (dwFlags & ~PT_NOCUSTOM) ^
  943.             (IsDlgButtonChecked (hDlg, IDC_BKNOCUSTOM) ? PT_NOCUSTOM : 0);
  944.  
  945.             /* change the options for the file being ported */
  946.             lpbkFiles->bkFile.dwPTFlags = dwFlags;
  947.             }
  948.             break;
  949.  
  950.         case IDCANCEL:
  951.             {
  952.             HCURSOR    hOldCursor;
  953.             HANDLE     hThreads[MAXBKTHREADS];
  954.             int        i = 0;
  955.                     CHAR       szText[MAX_PATH]; // for LoadString()
  956.                     CHAR       szTitle[MAX_PATH]; // for LoadString()
  957.                     HMODULE    hModule = GetModuleHandle(NULL);
  958.  
  959.             /* put up confirm message */
  960.                     LoadString((HANDLE)hModule,
  961.                         IDS_CANCEL_BKGND_PROCESS,
  962.                         szText,sizeof(szText));
  963.                     LoadString((HANDLE)hModule,
  964.                         IDS_ABORT_TITLE,
  965.                         szTitle,sizeof(szTitle));
  966.             if (MessageBox (hDlg,
  967.                     szText, szTitle,
  968.                     MB_ICONQUESTION | MB_OKCANCEL) == IDOK)
  969.             {
  970.             /* put hourglass cursor up */
  971.             hOldCursor = (HCURSOR)SetClassLong (hDlg, GCL_HCURSOR, 0);
  972.             SetCursor (LoadCursor (NULL, IDC_WAIT));
  973.  
  974.             /* if any files in list */
  975.             if (lpbkFiles)
  976.                 {
  977.                 /* abort all background threads and build thread handle array */
  978.                 lpNode = lpbkFiles;
  979.                 while (lpNode)
  980.                 {
  981.                 MySetEvent (hDlg, lpNode->hEvents[BKPORT_ABORT]);
  982.                 hThreads[i++] = lpNode->bkFile.hThread;
  983.                 lpNode = lpNode->Next;
  984.                 }
  985.  
  986.                 /* wait on completion of background threads */
  987.                 WaitForMultipleObjects (i, hThreads, TRUE, INFINITE);
  988.  
  989.                 /* free background port resources */
  990.                 FreeFileList (lpbkFiles);
  991.                 }
  992.  
  993.             SetClassLong (hDlg, GCL_HCURSOR, (LONG)hOldCursor);
  994.             SetCursor (hOldCursor);
  995.             DestroyWindow (hDlg);
  996.             hDlgPortStatus = NULL;
  997.  
  998.             }
  999.             }
  1000.             break;
  1001.  
  1002.         case IDC_BKDONE:
  1003.             /* if file list post message to cancel */
  1004.             if (lpbkFiles)
  1005.             PostMessage (hDlg, WM_COMMAND, IDCANCEL, 0);
  1006.             else
  1007.             DestroyWindow (hDlg);
  1008.             hDlgPortStatus = NULL;
  1009.             break;
  1010.  
  1011.         default:
  1012.             bRet = FALSE;
  1013.             break;
  1014.         }
  1015.         break;
  1016.  
  1017.     case WM_DESTROY:
  1018.         /* if no parent, post quit message */
  1019.         if (GetParent (hDlg) == NULL)
  1020.         PostQuitMessage (1);
  1021.         break;
  1022.  
  1023.     default:
  1024.         bRet = FALSE;
  1025.         break;
  1026.     }
  1027.  
  1028.     return bRet;
  1029. }
  1030.  
  1031.  
  1032.  
  1033. /* funtion retrieves the help filename from the ini file */
  1034. BOOL WINAPI GetHelpFileName (
  1035.     char    *lpszFile)
  1036. {
  1037.     char        szAppName[30];
  1038.     char        szWinHelp[30];
  1039.     char        szDefault[] = "Default";
  1040.     OFSTRUCT    of;
  1041.  
  1042.     /* get help filename from ini file */
  1043.     LoadString (GetModuleHandle (NULL), IDS_APPNAME, szAppName, 30);
  1044.     LoadString (GetModuleHandle (NULL), IDS_WINHELP, szWinHelp, 30);
  1045.     GetPrivateProfileString (szAppName,
  1046.                  szWinHelp,
  1047.                  szDefault,
  1048.                  lpszFile,
  1049.                  MAX_PATH,
  1050.                  lpszPortIniFilePath);
  1051.  
  1052.     /* test to see if help file exists */
  1053.     return (OpenFile (lpszFile, &of, OF_EXIST) != -1);
  1054. }
  1055.  
  1056.  
  1057.  
  1058.  
  1059. /* rearrange dialog and controls */
  1060. void WINAPI GrowDialog (
  1061.     HWND    hDlg,
  1062.     BOOL    bBigger)
  1063. {
  1064.     RECT    rc;
  1065.     int     nChange = (bBigger ? DLGOFFSET : -DLGOFFSET);
  1066.  
  1067.     /* grow main dialog */
  1068.     GetWindowRect (hDlg, &rc);
  1069.     SetWindowPos (hDlg,
  1070.           NULL,
  1071.           rc.left,
  1072.           rc.top,
  1073.           rc.right-rc.left,
  1074.           rc.bottom-rc.top + nChange,
  1075.           SWP_NOMOVE | SWP_NOZORDER);
  1076.  
  1077.     /* move stop button down */
  1078.     GetWindowRect (GetDlgItem (hDlg, IDCANCEL), &rc);
  1079.     ScreenToClient (hDlg, (LPPOINT)&rc);
  1080.     ScreenToClient (hDlg, (LPPOINT)&rc.right);
  1081.     SetWindowPos (GetDlgItem (hDlg, IDCANCEL),
  1082.           NULL,
  1083.           rc.left,
  1084.           rc.top + nChange,
  1085.           rc.right-rc.left,
  1086.           rc.bottom-rc.top,
  1087.           SWP_NOSIZE | SWP_NOZORDER);
  1088.  
  1089.     /* move CONTINUE button down */
  1090.     GetWindowRect (GetDlgItem (hDlg, IDC_CONTINUE), &rc);
  1091.     ScreenToClient (hDlg, (LPPOINT)&rc);
  1092.     ScreenToClient (hDlg, (LPPOINT)&rc.right);
  1093.     SetWindowPos (GetDlgItem (hDlg, IDC_CONTINUE),
  1094.           NULL,
  1095.           rc.left,
  1096.           rc.top + nChange,
  1097.           rc.right-rc.left,
  1098.           rc.bottom-rc.top,
  1099.           SWP_NOSIZE | SWP_NOZORDER);
  1100.  
  1101.     /* move restart button down */
  1102.     GetWindowRect (GetDlgItem (hDlg, IDC_RESTART), &rc);
  1103.     ScreenToClient (hDlg, (LPPOINT)&rc);
  1104.     ScreenToClient (hDlg, (LPPOINT)&rc.right);
  1105.     SetWindowPos (GetDlgItem (hDlg, IDC_RESTART),
  1106.           NULL,
  1107.           rc.left,
  1108.           rc.top + nChange,
  1109.           rc.right-rc.left,
  1110.           rc.bottom-rc.top,
  1111.           SWP_NOSIZE | SWP_NOZORDER);
  1112.  
  1113.     /* move options button down */
  1114.     GetWindowRect (GetDlgItem (hDlg, IDC_OPTIONS), &rc);
  1115.     ScreenToClient (hDlg, (LPPOINT)&rc);
  1116.     ScreenToClient (hDlg, (LPPOINT)&rc.right);
  1117.     SetWindowPos (GetDlgItem (hDlg, IDC_OPTIONS),
  1118.           NULL,
  1119.           rc.left,
  1120.           rc.top + nChange,
  1121.           rc.right-rc.left,
  1122.           rc.bottom-rc.top,
  1123.           SWP_NOSIZE | SWP_NOZORDER);
  1124.  
  1125.     /* move help button down */
  1126.     GetWindowRect (GetDlgItem (hDlg, IDC_HELPM), &rc);
  1127.     ScreenToClient (hDlg, (LPPOINT)&rc);
  1128.     ScreenToClient (hDlg, (LPPOINT)&rc.right);
  1129.     SetWindowPos (GetDlgItem (hDlg, IDC_HELPM),
  1130.           NULL,
  1131.           rc.left,
  1132.           rc.top + nChange,
  1133.           rc.right-rc.left,
  1134.           rc.bottom-rc.top,
  1135.           SWP_NOSIZE | SWP_NOZORDER);
  1136.  
  1137.     /* move done button down */
  1138.     GetWindowRect (GetDlgItem (hDlg, IDC_DONE), &rc);
  1139.     ScreenToClient (hDlg, (LPPOINT)&rc);
  1140.     ScreenToClient (hDlg, (LPPOINT)&rc.right);
  1141.     SetWindowPos (GetDlgItem (hDlg, IDC_DONE),
  1142.           NULL,
  1143.           rc.left,
  1144.           rc.top + nChange,
  1145.           rc.right-rc.left,
  1146.           rc.bottom-rc.top,
  1147.           SWP_NOSIZE | SWP_NOZORDER);
  1148.  
  1149.     /* show suggestion edit control and label when appropriate */
  1150.     ShowWindow (GetDlgItem (hDlg, IDC_SUGGESTION), (bBigger ? SW_SHOW : SW_HIDE));
  1151.     ShowWindow (GetDlgItem (hDlg, IDC_SUGGESTLABEL), (bBigger ? SW_SHOW : SW_HIDE));
  1152. }
  1153.  
  1154.  
  1155.  
  1156.  
  1157. BOOL WINAPI BuildFileList (
  1158.     char          *lpFileList,
  1159.     LPBKFILELIST  *lpList)
  1160. {
  1161.     char        *lpFile;
  1162.     char        szFilePath[MAX_PATH];
  1163.     char        szFile[MAX_PATH];
  1164.     HFILE       hFile;
  1165.     OFSTRUCT    of;
  1166.     BOOL        bList = FALSE;
  1167.  
  1168.     /* create heap for up to 50 files at a time */
  1169.     if (!(hBkFileHeap = HeapCreate (HEAP_NO_SERIALIZE,
  1170.                     sizeof (BKFILELIST),
  1171.                     MAXBKTHREADS * sizeof (BKFILELIST))))
  1172.     return FALSE;
  1173.  
  1174.     /* allocate first node in list */
  1175.     *lpList = (BKFILELIST *)HeapAlloc (hBkFileHeap, 0, sizeof (BKFILELIST));
  1176.     (*lpList)->hEvents[BKPORT_ABORT] = NULL;
  1177.  
  1178.     /* parse first file in list */
  1179.     lpFile = strtok (lpFileList, " ");
  1180.  
  1181.     /* loop through all files in list */
  1182.     while (lpFile)
  1183.     {
  1184.     strcpy (szFilePath, lpFile);
  1185.  
  1186.     /* if no path, add current directory as path */
  1187.     if (!GetFileFromPath (szFilePath, szFile))
  1188.         {
  1189.         strcpy (szFile, szFilePath);
  1190.         GetCurrentDirectory (MAX_PATH, szFilePath);
  1191.         strcat (szFilePath, "\\");
  1192.         strcat (szFilePath, szFile);
  1193.         }
  1194.  
  1195.     /* verify file is available */
  1196.     hFile = OpenFile (szFilePath, &of, OF_READWRITE);
  1197.     if (hFile != -1)
  1198.         {
  1199.         /* added at least one file */
  1200.         bList = TRUE;
  1201.  
  1202.         /* close file */
  1203.         CloseHandle ((HANDLE)hFile);
  1204.  
  1205.         /* add file to list */
  1206.         AddFile (szFilePath, szFile, *lpList);
  1207.         }
  1208.  
  1209.     /* get next file in list */
  1210.     lpFile = strtok (NULL, " ");
  1211.     }
  1212.  
  1213.     /* if no valid files, cleanup */
  1214.     if (!bList)
  1215.     {
  1216.     HeapDestroy (hBkFileHeap);
  1217.     return FALSE;
  1218.     }
  1219.  
  1220.     return TRUE;
  1221. }
  1222.  
  1223.  
  1224.  
  1225.  
  1226. BOOL WINAPI AddFile (
  1227.     char        *lpFilePath,
  1228.     char        *lpFile,
  1229.     BKFILELIST  *lpbkFiles)
  1230. {
  1231.     BKFILELIST    *lpNode;
  1232.  
  1233.  
  1234.     /* if first item in list don't need to allocate */
  1235.     if (!lpbkFiles->hEvents[BKPORT_ABORT])
  1236.     lpNode = lpbkFiles;
  1237.     else
  1238.     {
  1239.     lpNode = (BKFILELIST *)HeapAlloc (hBkFileHeap, 0, sizeof (BKFILELIST));
  1240.     if (!lpNode)
  1241.         return FALSE;
  1242.  
  1243.     /* find end of list then add new node */
  1244.     while (lpbkFiles->Next)
  1245.         lpbkFiles = lpbkFiles->Next;
  1246.     lpbkFiles->Next = lpNode;
  1247.     }
  1248.  
  1249.     /* initialize node structure */
  1250.     strcpy (lpNode->bkFile.szFile, lpFile);
  1251.     strcpy (lpNode->bkFile.szFilePath, lpFilePath);
  1252.     CreateEvents (lpNode->hEvents, &lpNode->bkFile);
  1253.     lpNode->Next = NULL;
  1254.  
  1255.     return TRUE;
  1256. }
  1257.  
  1258.  
  1259.  
  1260.  
  1261. BOOL WINAPI RemoveFile (
  1262.     char          *lpFilePath,
  1263.     LPBKFILELIST  *lpbkFiles)
  1264. {
  1265.     BKFILELIST    *pHead = *lpbkFiles;
  1266.     BKFILELIST    *pTail = *lpbkFiles;
  1267.  
  1268.     /* loop thru list until file name matches */
  1269.     while (pHead)
  1270.     {
  1271.     if (!strcmp (lpFilePath, pHead->bkFile.szFilePath))
  1272.         {
  1273.         /* special case remove first node */
  1274.         if (pTail == pHead)
  1275.         {
  1276.         *lpbkFiles = pHead->Next;
  1277.         DestroyEvents (pHead->hEvents);
  1278.         HeapFree (hBkFileHeap, 0, (char *)(pHead));
  1279.  
  1280.         /* if no more nodes, destroy heap */
  1281.         if (!*lpbkFiles)
  1282.             HeapDestroy (hBkFileHeap);
  1283.         }
  1284.  
  1285.         else
  1286.         {
  1287.         pTail->Next = pHead->Next;
  1288.         DestroyEvents (pHead->hEvents);
  1289.         HeapFree (hBkFileHeap, 0, (char *)pHead);
  1290.         }
  1291.  
  1292.         return TRUE;
  1293.         }
  1294.  
  1295.     pTail = pHead;
  1296.     pHead = pHead->Next;
  1297.     }
  1298.  
  1299.     return FALSE;
  1300. }
  1301.  
  1302.  
  1303.  
  1304.  
  1305. BOOL WINAPI FreeFileList (
  1306.     BKFILELIST  *lpbkFiles)
  1307. {
  1308.     /* loop thru each list item */
  1309.     while (lpbkFiles)
  1310.     {
  1311.     /* destroy event handles */
  1312.     DestroyEvents (lpbkFiles->hEvents);
  1313.  
  1314.     lpbkFiles = lpbkFiles->Next;
  1315.     }
  1316.  
  1317.     /* release entire heap */
  1318.     HeapDestroy (hBkFileHeap);
  1319.  
  1320.     return TRUE;
  1321. }
  1322.  
  1323.  
  1324. BOOL MySetEvent (HWND hWnd, HANDLE hEvent)
  1325. {
  1326.     if (SetEvent(hEvent)) {
  1327.     return TRUE;
  1328.     } else {
  1329.     return PostMessage (hWnd, (UINT)hEvent, 0, 0L);
  1330.     }
  1331. }
  1332.  
  1333. BOOL MyResetEvent (HWND hWnd, HANDLE hEvent)
  1334. {
  1335.     MSG msg;
  1336.  
  1337.     if (ResetEvent(hEvent)) {
  1338.     return TRUE;
  1339.     } else {
  1340.     PeekMessage (&msg, hWnd, (UINT)hEvent, (UINT)hEvent, TRUE);
  1341.     return TRUE;
  1342.     }
  1343. }
  1344.