PTDLGS.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:35k
源码类别:

Windows编程

开发平台:

Visual C++

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