wndproc.c
上传用户:jlteech
上传日期:2007-01-06
资源大小:349k
文件大小:67k
源码类别:

压缩解压

开发平台:

Visual C++

  1. /* Windows Info-ZIP Window Procedure, wndproc.c.
  2.  * Author: Robert A. Heath, 157 Chartwell Rd., Columbia, SC 29210
  3.  * I, Robert Heath, place this source code module in the public domain.
  4.  *
  5.  * Modifications: 1995, 1996 M. White
  6.  */
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include <time.h>
  10. #include <string.h>
  11. #include <stdio.h>
  12. #include <ctype.h>
  13. #ifdef __BORLANDC__
  14. #  include <dir.h>
  15. #else
  16. #  include <direct.h>
  17. #endif
  18. #include "wiz.h"
  19. #include "helpids.h"
  20. /* For a some reason I haven't bothered to try to figure out
  21.  * shellapi.h must follow wiz.h
  22.  */
  23. #include <shellapi.h>
  24. FARPROC lpOldEditProc;
  25. extern LRESULT CALLBACK SubClassEditProc(HWND, WORD, WPARAM, LPARAM);
  26. char LongFileTrailer[] =
  27.      "%7lu  %7lu %4s                    %u file%s";
  28. char ShortFileTrailer[] = "%7lu                    %u file%s";
  29. char Far HeadersShort[]  = " Length    Date    Time    Name";
  30. char Far HeadersLong[]  =
  31.   " Length     Size Ratio   Date     Time   Name";
  32. char Far *Headers[] = {HeadersShort, HeadersLong};
  33. char szTotalsLine[80];              /* text for totals of zip archive */
  34. BOOL fUpdateEntries, bSizing = FALSE, bMouseButtonDown = FALSE;
  35. OPENFILENAME ofnTemp; /* Open file name structure for edit box save and open */
  36. /* Forward Refs
  37.  */
  38. void GetDirectory(LPSTR lpDir);
  39. void GetHelpContext(WPARAM wParam);
  40. extern LPUSERFUNCTIONS lpUserFunctions;
  41. HWND hPatternSelectDlg; /* pattern select modeless dialog   */
  42. static UINT uCommDlgHelpMsg;   /* common dialog help message ID */
  43. DWORD dwCommDlgHelpId = HELPID_HELP; /* what to pass to WinHelp() */
  44. char szFormatKeyword[2][6] = { "short", "long" };
  45. static BOOL move_flag = FALSE;
  46. static BOOL rename_flag = FALSE;
  47. DWORD dwHelpContextId;
  48. LPSTR lpchLast;
  49. #ifndef WIN32
  50. /* Trailers are the lines just above the totals */
  51. static char * __based(__segname("STRINGS_TEXT")) szTrailers[2] = {
  52. " ------                    -------",
  53. "-------  -------  ---                    -------"
  54. } ;
  55. #endif
  56. static char __based(__segname("STRINGS_TEXT")) szCantChDir[] =
  57.    "Internal error: Cannot change directory. Common dialog error code is 0x%lX.";
  58. /* size of char in SYSTEM font in pixels */
  59. #ifndef WIN32
  60. short dxChar, dyChar;
  61. #else
  62. long dxChar, dyChar;
  63. #endif
  64. /*       This will allow you to perform a hit test on a line in the
  65.          list box, however, you then tend to lose the concept of being
  66.          able to do ctrl-mouse click and undo selections. It wasn't
  67.          important enough to spend any more time fooling with.
  68. */
  69. #if 0
  70. void MapCursorToListItem(void);
  71. void MapCursorToListItem(void)
  72. {
  73. DWORD          dwpos;
  74. LV_HITTESTINFO lvhti;
  75. UINT           state;
  76. LV_ITEM        lvi;
  77. int            iItemClicked;
  78. if (ListView_GetItemCount(hWndList))
  79.    {
  80.    /* Find out where the cursor was */
  81.    dwpos = GetMessagePos();
  82.    lvhti.pt.x = LOWORD(dwpos);
  83.    lvhti.pt.y = HIWORD(dwpos);
  84.    MapWindowPoints(HWND_DESKTOP, hWndList, &lvhti.pt, 1);
  85.    state = lvhti.pt.x;
  86.    lvhti.pt.x = 0;
  87.    /* Now do a hittest with this point. We keep testing so we can
  88.       find out if the mouse click was anywhere on the row.
  89.     */
  90.    while (((iItemClicked = ListView_HitTest(hWndList, &lvhti)) < 0) &&
  91.          (lvhti.pt.x < (int)state))
  92.          {
  93.          lvhti.pt.x++;
  94.          }
  95.    /* Okay, have we clicked on a live item? */
  96.    if (lvhti.flags & LVHT_ONITEM)
  97.       {
  98.       lvi.mask      = LVIF_STATE;
  99.       lvi.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
  100.       lvi.iItem     = iItemClicked;
  101.       lvi.iSubItem  = 0;
  102.       ListView_GetItem(hWndList, &lvi);
  103.       if (lvi.state & LVIS_SELECTED)
  104.          lvi.state = 0;
  105.       else
  106.          lvi.state = LVIS_SELECTED | LVIS_FOCUSED;
  107.       ListView_SetItem(hWndList, &lvi);
  108.       }
  109.    }
  110. }
  111. #endif
  112. LPSTR lstrrchr(LPSTR lpszSrc, char chFind)
  113. {
  114. LPSTR   lpszFound = (LPSTR)0;
  115. LPSTR   lpszT;
  116. if ( lpszSrc )
  117.    {
  118.    for (lpszT = lpszSrc; *lpszT; ++lpszT)
  119.        {
  120.        if ((*lpszT) == chFind)
  121.           lpszFound = lpszT;
  122.        }
  123.    }
  124. return lpszFound;
  125. }
  126. /* Copy only the path portion of current file name into
  127.  * given buffer, lpszDestDir, translate into ANSI.
  128.  */
  129. void GetArchiveDir(LPSTR lpszDestDir)
  130. {
  131. LPSTR lpchLast;
  132. /* strip off filename to make directory name    */
  133. lstrcpy(lpszDestDir, lpumb->szFileName);
  134. if ((lpchLast = lstrrchr(lpszDestDir, '\'))!=0)
  135.    *lpchLast = '';
  136. else if ((lpchLast = lstrrchr(lpszDestDir, ':'))!=0)
  137.    *(++lpchLast) = ''; /* clobber char AFTER the colon! */
  138. }
  139. void GetDirectory(LPSTR lpDir)
  140. {
  141. LPSTR lpchLast;
  142. /* If no '\' then set directory name to "" */
  143. if ((lpchLast = lstrrchr(lpDir, '\')) == 0)
  144.    {
  145.    lpDir[0] = '';
  146.    return;
  147.    }
  148. /* strip off filename to make directory name    */
  149. if ((lpchLast = lstrrchr(lpDir, '\'))!=0)
  150.    *lpchLast = '';
  151. else if ((lpchLast = lstrrchr(lpDir, ':'))!=0)
  152.    *(++lpchLast) = ''; /* clobber char AFTER the colon! */
  153. }
  154. /*
  155.  * FUNCTION: SetCaption(HWND hWnd)
  156.  * PURPOSE: Set new caption for main window
  157.  */
  158. void
  159. SetCaption(HWND hWnd)
  160. {
  161. #define SIMPLE_NAME_LEN 15
  162. static BOOL FirstTime = TRUE;
  163. WORD wMenuState;
  164. char szSimpleFileName[SIMPLE_NAME_LEN+1];  /* just the 8.3 part in ANSI char set */
  165. LPSTR lpszFileNameT;        /* pointer to simple filename               */
  166. BOOL    fIconic = IsIconic(hWnd);   /* is window iconic ?   */
  167. BOOL fWndEnabled; /* Is button to be enabled? */
  168. /* point to simple filename in OEM char set */
  169. if ((((lpszFileNameT = lstrrchr(lpumb->szFileName, '\'))!=0) ||
  170.    ((lpszFileNameT = lstrrchr(lpumb->szFileName, ':')))!=0))
  171.    lpszFileNameT++;
  172. else
  173.    lpszFileNameT = lpumb->szFileName;
  174. #ifndef WIN32
  175. _fstrncpy(szSimpleFileName, lpszFileNameT, SIMPLE_NAME_LEN);
  176. #else
  177. strncpy(szSimpleFileName, lpszFileNameT, SIMPLE_NAME_LEN);
  178. #endif
  179. szSimpleFileName[SIMPLE_NAME_LEN] = ''; /* force termination */
  180. wMenuState = (WORD)(szSimpleFileName[0] ? MF_ENABLED : MF_GRAYED);
  181. fWndEnabled = (BOOL) (szSimpleFileName[0] ? TRUE : FALSE);
  182. /* Enable/Disable menu items */
  183. EnableMenuItem(hMenu, IDM_SELECT_ALL, wMenuState|MF_BYCOMMAND);
  184. EnableMenuItem(hMenu, IDM_DESELECT_ALL, wMenuState|MF_BYCOMMAND);
  185. EnableMenuItem(hMenu, IDM_SELECT_BY_PATTERN, wMenuState|MF_BYCOMMAND);
  186. /* Enable/Disable buttons */
  187. if (!FirstTime)
  188.    {
  189.    WinAssert(hSelectAll);
  190.    EnableWindow( hSelectAll, fWndEnabled);
  191.    WinAssert(hDeselectAll);
  192.    EnableWindow( hDeselectAll, fWndEnabled);
  193.    WinAssert(hSelectPattern);
  194.    EnableWindow( hSelectPattern, fWndEnabled);
  195.    }
  196. if ((lstrlen(szUnzipToDirName) == 2) && (szUnzipToDirName[1] == ':') &&
  197.    szSimpleFileName[0])
  198.    {
  199.    lstrcpy(szUnzipToDirName, lpumb->szFileName);
  200.    if ((lpszFileNameT = lstrrchr(szUnzipToDirName, '\'))!=0)
  201.       lpszFileNameT[0] = '';
  202.    if (lstrlen(szUnzipToDirName) == 2)
  203.       lstrcat(szUnzipToDirName, "\");
  204.    }
  205. if (!szSimpleFileName[0])
  206.    lstrcpy(szSimpleFileName, "No Zip File");
  207. wsprintf(lpumb->szBuffer, "%s - %s %s %s",
  208.                (LPSTR)szAppName,
  209.                (LPSTR)(szSimpleFileName),
  210.                (LPSTR)(!fIconic && szUnzipToDirName[0] ? " - " : ""),
  211.                (LPSTR)(!fIconic ? szUnzipToDirName : ""));
  212. SetWindowText(hWnd, lpumb->szBuffer);
  213. FirstTime = FALSE;
  214. }
  215. /*
  216.  * FUNCTION: WiZWndMainProc(HWND, unsigned, WORD, LONG)
  217.  *
  218.  * PURPOSE:  Processes messages
  219.  *
  220.  * MESSAGES:
  221.  *
  222.  * WM_DESTROY      - destroy window
  223.  * WM_SIZE         - window size has changed
  224.  * WM_QUERYENDSESSION - willing to end session?
  225.  * WM_ENDSESSION   - end Windows session
  226.  * WM_CLOSE        - close the window
  227.  * WM_SIZE         - window resized
  228.  * WM_PAINT        - windows needs to be painted
  229.  * WM_DROPFILES    - open a dropped file
  230.  * COMMENTS:
  231.  * WM_COMMAND processing:
  232.  *    IDM_OPEN -  open a new file.
  233.  *    IDM_EXIT -  exit.
  234.  *    IDM_ABOUT - display "About" box.
  235.  */
  236. LRESULT WINAPI WiZMainWndProc(HWND hWnd, WORD wMessage, WPARAM wParam, LPARAM lParam)
  237. {
  238. HDC hDC;                /* device context       */
  239. TEXTMETRIC    tm;           /* text metric structure    */
  240. char drive;
  241. #ifndef WIN32
  242. FARPROC lpfnAbout, lpfnSelectDir;
  243. #endif
  244. char *ptr;
  245. switch (wMessage)
  246.     {
  247.     case WM_CREATE: /* create  window       */
  248.       hInst = ((LPCREATESTRUCT)lParam)->hInstance;
  249.       hAccTable = LoadAccelerators(hInst, "WiZAccels");
  250.       hBrush = CreateSolidBrush(GetSysColor(BG_SYS_COLOR)); /* background */
  251.       hMenu = GetMenu(hWnd);
  252.       /* Get an hourglass cursor to use during file transfers */
  253.       hHourGlass = LoadCursor(0, IDC_WAIT);
  254.       hFixedFont = GetStockObject(ANSI_FIXED_FONT);
  255.       hDC = GetDC(hWnd);  /* get device context */
  256.       hOldFont = SelectObject(hDC, hFixedFont);
  257.       GetTextMetrics(hDC, &tm);
  258.       ReleaseDC(hWnd, hDC);
  259.       dxChar = tm.tmAveCharWidth;
  260.       dyChar = tm.tmHeight + tm.tmExternalLeading + tm.tmInternalLeading;
  261.       WinAssert(hWnd);
  262. #ifndef WIN32
  263.       hWndList = CreateWindow("listbox", NULL,
  264.                         WS_CHILD|WS_DLGFRAME|WS_VSCROLL|LBS_NOTIFY|
  265.                         LBS_EXTENDEDSEL|ES_NOHIDESEL,
  266.                         0, 0,
  267.                         0, 0,
  268.                         hWnd, (HMENU)IDM_LISTBOX,
  269.                         GetWindowWord (hWnd, GWW_HINSTANCE), NULL);
  270. #else
  271.       hWndList = CreateWindow(WC_LISTVIEW, NULL,
  272.                         WS_CHILD | WS_DLGFRAME |
  273.                         LVS_REPORT | LVS_SHOWSELALWAYS |
  274.                         LVS_SORTASCENDING,
  275.                         0, 0,
  276.                         0, 0,
  277.                         hWnd, (HMENU)IDM_LISTBOX,
  278.                         (HANDLE)GetWindowLong (hWnd, GWL_HINSTANCE), NULL);
  279. #endif
  280.       WinAssert(hWndList);
  281.       SendMessage(hWndList, WM_SETFONT, (WPARAM)hFixedFont, FALSE);
  282.       WinAssert(hWnd);
  283. #ifdef WIN32
  284.       {
  285.       LV_COLUMN lvc;
  286.       int       iCol;
  287.       char      szText[6][20]= {"Name", "Orig Size", "Comp Size","Ratio","  Date",
  288.                   "Time"};
  289.       /* Initialize the LV_COLUMN structure. */
  290.       lvc.mask    = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  291.       lvc.fmt     = LVCFMT_LEFT;
  292.       lvc.cx      = 95;
  293.       for (iCol = 0; iCol < 6; iCol++)
  294.           {
  295.           lvc.pszText = szText[iCol];
  296.           lvc.iSubItem = iCol;
  297.           if (ListView_InsertColumn(hWndList, iCol, &lvc) == -1)
  298.               return FALSE;
  299.           }
  300.       ListView_SetColumnWidth(hWndList, 0, MAKELPARAM((int)30*dxChar, 0));
  301.       ListView_SetColumnWidth(hWndList, 1, MAKELPARAM((int)11*dxChar, 0));
  302.       ListView_SetColumnWidth(hWndList, 2, MAKELPARAM((int)11*dxChar, 0));
  303.       ListView_SetColumnWidth(hWndList, 3, MAKELPARAM((int)7*dxChar, 0));
  304.       ListView_SetColumnWidth(hWndList, 4, MAKELPARAM((int)10*dxChar, 0));
  305.       ListView_SetColumnWidth(hWndList, 5, MAKELPARAM((int)7*dxChar, 0));
  306.       }
  307. #endif /* WIN32 */
  308. #ifndef WIN32
  309.       hWndStatic = CreateWindow("StaticClass", "WiZ Edit/Status Window",
  310.                             WS_OVERLAPPEDWINDOW|WS_SIZEBOX,
  311.                             0, 0,
  312.                             0, 0,
  313.                             hWnd,
  314.                             (HWND) 0,
  315.                             GetWindowWord (hWnd, GWW_HINSTANCE), NULL);
  316.       hWndEdit = CreateWindow("edit", NULL,
  317.                             WS_CHILD |ES_MULTILINE|ES_NOHIDESEL|
  318.                             ES_AUTOHSCROLL|WS_VSCROLL|WS_HSCROLL,
  319.                             0, 0,
  320.                             0, 0,
  321.                             hWndStatic,
  322.                             NULL,
  323.                             GetWindowWord (hWnd, GWW_HINSTANCE),
  324.                             NULL);
  325. #else
  326.       hWndStatic = CreateWindow("StaticClass", "WiZ Edit/Status Window",
  327.                             WS_OVERLAPPEDWINDOW|WS_SIZEBOX,
  328.                             0, 0,
  329.                             0, 0,
  330.                             hWnd,
  331.                             NULL, /* Use class menu */
  332.                             (HANDLE)GetWindowLong (hWnd, GWL_HINSTANCE), NULL);
  333.       WinAssert(hWndStatic);
  334.       hWndEdit = CreateWindow("RICHEDIT", NULL,
  335.                             WS_CHILD |ES_MULTILINE|ECO_AUTOWORDSELECTION|
  336.                             ECO_AUTOHSCROLL|WS_VSCROLL|WS_HSCROLL|
  337.                             ES_NOHIDESEL|ECO_AUTOVSCROLL,
  338.                             0, 0,
  339.                             0, 0,
  340.                             hWndStatic,
  341.                             NULL,
  342.                             (HANDLE)GetWindowLong (hWnd, GWL_HINSTANCE),
  343.                             NULL);
  344. #endif
  345.       WinAssert(hWndEdit);
  346.       /* Subclass the edit control */
  347.       lpOldEditProc = (FARPROC)GetWindowLong (hWndEdit, GWL_WNDPROC);
  348.       SetWindowLong (hWndEdit, GWL_WNDPROC, (LONG)SubClassEditProc);
  349.       /* Now we set the maximum size the edit control can utilize */
  350. #ifdef WIN32
  351.       SendMessage(hWndEdit, EM_EXLIMITTEXT, (WPARAM)0, (LPARAM)EDIT_BUF_SIZE);
  352. #else
  353.       SendMessage(hWndEdit, EM_LIMITTEXT, (WPARAM) 0, 0L);
  354. #endif
  355.       SendMessage(hWndEdit, WM_SETFONT, (WPARAM)hFixedFont, TRUE);
  356. #ifdef WIN32
  357.       /* Insure rich edit control alignment is set to left */
  358.       {
  359.       PARAFORMAT pf;
  360.       pf.cbSize = sizeof(pf);
  361.       pf.dwMask = PFM_ALIGNMENT;
  362.       pf.wAlignment = PFA_LEFT;
  363.       SendMessage(hWndEdit, EM_SETPARAFORMAT, 0, (LPARAM)&pf);
  364.       }
  365. #endif
  366.       GetWizOptions(); /* Get options from .INI file */
  367.       UpdateListBox();
  368. #ifndef WIN32
  369.       SendMessage(hWndList, LB_SETSEL, 1, 0L);
  370. #else
  371.       ListViewSetSel(0, TRUE);
  372. #endif
  373.       SetCaption(hWnd);
  374.       uCommDlgHelpMsg = RegisterWindowMessage((LPSTR)HELPMSGSTRING); /* register open help message */
  375.       if ( uf.fCanDragDrop )
  376.          DragAcceptFiles( hWnd, TRUE );
  377.       break;
  378.     case WM_SETFOCUS:
  379.         SetFocus(hWndList);
  380.         break;
  381. #ifdef WIN32
  382.     /* This whole section is only for the ListView control which is only
  383.        available with Windows 95/Windows NT - and not for 16 bit Windows
  384.        programs.
  385.      */
  386.     case WM_NOTIFY:
  387.          {
  388.          DWORD          dwpos;
  389.          NM_LISTVIEW *pNm = (NM_LISTVIEW *)lParam;
  390.          /* Are we dealing with a message from the list box? */
  391.          if (pNm->hdr.hwndFrom != hWndList)
  392.             break;
  393.          switch (pNm->hdr.code) {
  394.          case NM_RCLICK: /* Now is it a right mouse button click? */
  395.             {
  396. /*       This will allow you to perform a hit test on a line in the
  397.          list box, however, you then tend to lose the concept of being
  398.          able to do ctrl-mouse click and undo selections. It wasn't
  399.          important enough to spend any more time fooling with.
  400.             MapCursorToListItem();
  401. */
  402.             dwpos = GetMessagePos();
  403.             PostMessage(hWndMain, WM_RBUTTONUP, (WPARAM) 0L, (LPARAM) dwpos); /* Yep */
  404.             break;
  405.             }
  406.          case NM_DBLCLK: /* Double-click in ListView control */
  407.             {
  408. /*       This will allow you to perform a hit test on a line in the
  409.          list box, however, you then tend to lose the concept of being
  410.          able to do ctrl-mouse click and undo selections. It wasn't
  411.          important enough to spend any more time fooling with.
  412.             MapCursorToListItem();
  413. */
  414.             UpdateButtons();
  415.             if ( uf.fCanDragDrop )
  416.                DragAcceptFiles( hWnd, FALSE );
  417.             Action(hWnd, (WPARAM)(wLBSelection - IDM_LB_EXTRACT));
  418.             if ( uf.fCanDragDrop )
  419.                DragAcceptFiles( hWnd, TRUE );
  420.             break;
  421.             }
  422.          /* This is for "sorting" and is a kludge as it requires reading
  423.             from disk each time you do a sort, but I don't know a better
  424.             way other than keeping a list in memory which results in a
  425.             whole bunch of memory being eaten up just for a "fancy". If
  426.             the time delay bothers you - don't do it, just take this out.
  427.           */
  428.          case LVN_COLUMNCLICK: /* Column clicked on - now sort */
  429.             ListViewSortOnColumns(pNm->iSubItem);
  430. #ifndef WIN32
  431.             SendMessage(hWndList, LB_SETSEL, 1, 0L);
  432. #else
  433.             ListViewSetSel(0, TRUE);
  434. #endif
  435.             break;
  436.          case LVN_ITEMCHANGED:
  437.             {
  438.             UpdateButtons();
  439.             break;
  440.             }
  441. /*       This will allow you to perform a hit test on a line in the
  442.          list box, however, you then tend to lose the concept of being
  443.          able to do ctrl-mouse click and undo selections. It wasn't
  444.          important enough to spend any more time fooling with.
  445.          case NM_CLICK:
  446.             MapCursorToListItem();
  447.             break;
  448. */
  449.             }
  450.          break;
  451.          }
  452. #endif /* WIN32 ? */
  453.     case WM_ACTIVATE:
  454.         /* This section is put in to fix a weird problem with the listbox
  455.            not displaying the contents of an archive file if it is either
  456.            dropped on WiZ, or if it is started from the command line.
  457.            I have no idea why this happens.
  458.         */
  459.         {
  460.         extern int ofretval;
  461.         if ((lpumb->szFileName[0]!='') && (ofretval))
  462.            {
  463.            UpdateListBox();
  464.            /* We have to have something selected before we can
  465.               activate the buttons!
  466.             */
  467. #ifndef WIN32
  468.            SendMessage(hWndList, LB_SETSEL, 1, 0L);
  469. #else
  470.            ListViewSetSel(0, TRUE);
  471. #endif
  472.            UpdateButtons();
  473.            }
  474.         ofretval = 0;
  475.         }
  476.         SetCaption(hWnd);
  477.         return DefWindowProc(hWnd, wMessage, wParam, lParam);
  478.     case WM_SIZE:
  479.         SizeWindow();
  480.         break;
  481.     case WM_SYSCOMMAND:
  482.         return DefWindowProc( hWnd, wMessage, wParam, lParam );
  483.     case WM_RBUTTONUP:
  484.          /*
  485.            PURPOSE: Display and track popup menu on button click.
  486.            PARAMETERS:
  487.              hWnd      - Window handle
  488.              lparam    - Coordinates where the mouse was pressed
  489.            Always returns 0 - Message handled
  490.           */
  491.          {
  492.            HMENU hmenu;
  493.            HMENU hmenuTrackPopup;
  494.           RECT  rc;
  495.          BOOL fButtonState;
  496.           POINT pt;
  497.          DWORD dwpos;
  498.           /* Draw the appropriate "floating" popup in the client area
  499.             Check the listbox first
  500.           */
  501.           GetWindowRect(hWndList, &rc);
  502.             dwpos = GetMessagePos();
  503.             pt.x = LOWORD(dwpos);
  504.             pt.y = HIWORD(dwpos);
  505.           if (PtInRect(&rc, pt))
  506.              {
  507.               /* Get the menu for the popup from the resource file. */
  508.               hmenu = LoadMenu(hInst, "PopupListMenu");
  509.               if (!hmenu)
  510.                  return 0;
  511.               /* Get the first menu in it which we will use for the call to
  512.                * TrackPopup(). This could also be created on the fly using
  513.                * CreatePopupMenu and then using InsertMenu() or
  514.                * AppendMenu.
  515.              */
  516.               hmenuTrackPopup = GetSubMenu(hmenu, 0);
  517.             if (lpumb->szFileName[0] &&
  518. #ifndef WIN32
  519.                SendMessage(hWndList, LB_GETSELCOUNT, 0, 0L)) /* anything selected ? */
  520. #else
  521.                ListView_GetSelectedCount(hWndList))
  522. #endif
  523.                   fButtonState = TRUE;
  524.             else
  525.                   fButtonState = FALSE;
  526.             EnableMenuItem(hmenuTrackPopup, IDM_EXTRACT,
  527.                (fButtonState ? MF_ENABLED : MF_DISABLED|MF_GRAYED)|MF_BYCOMMAND);
  528.             EnableMenuItem(hmenuTrackPopup, IDM_DISPLAY,
  529.                (fButtonState ? MF_ENABLED : MF_DISABLED|MF_GRAYED)|MF_BYCOMMAND);
  530.             EnableMenuItem(hmenuTrackPopup, IDM_TEST,
  531.                (fButtonState ? MF_ENABLED : MF_DISABLED|MF_GRAYED)|MF_BYCOMMAND);
  532.             EnableMenuItem(hmenuTrackPopup, IDM_SHOW_COMMENT,
  533.                    (BOOL)(fButtonState && lpUserFunctions->cchComment ? MF_ENABLED : MF_DISABLED|MF_GRAYED)|MF_BYCOMMAND);
  534.             EnableMenuItem(hmenuTrackPopup, IDM_GET_ZIPINFO,
  535.                  (fButtonState ? MF_ENABLED : MF_DISABLED|MF_GRAYED)|MF_BYCOMMAND);
  536.             EnableMenuItem(hmenuTrackPopup, IDM_UPDATE_ZIP,
  537.                  (fButtonState ? MF_ENABLED : MF_DISABLED|MF_GRAYED)|MF_BYCOMMAND);
  538.             EnableMenuItem(hmenuTrackPopup, IDM_ZIP_DELETE_ENTRIES,
  539.                (fButtonState ? MF_ENABLED : MF_DISABLED|MF_GRAYED)|MF_BYCOMMAND);
  540.             if (lpumb->szFileName[0] != '')
  541.                fButtonState = TRUE;
  542.             else
  543.                fButtonState = FALSE;
  544.             EnableMenuItem(hmenuTrackPopup, IDM_COPY_ARCHIVE,
  545.                (fButtonState ? MF_ENABLED : MF_DISABLED|MF_GRAYED)|MF_BYCOMMAND);
  546.             EnableMenuItem(hmenuTrackPopup, IDM_MOVE_ARCHIVE,
  547.                (fButtonState ? MF_ENABLED : MF_DISABLED|MF_GRAYED)|MF_BYCOMMAND);
  548.             EnableMenuItem(hmenuTrackPopup, IDM_DELETE_ARCHIVE,
  549.                (fButtonState ? MF_ENABLED : MF_DISABLED|MF_GRAYED)|MF_BYCOMMAND);
  550.             EnableMenuItem(hmenuTrackPopup, IDM_RENAME_ARCHIVE,
  551.                 (fButtonState ? MF_ENABLED : MF_DISABLED|MF_GRAYED)|MF_BYCOMMAND);
  552.             EnableMenuItem(hmenuTrackPopup, IDM_SELECT_ALL,
  553.                (fButtonState ? MF_ENABLED : MF_DISABLED|MF_GRAYED)|MF_BYCOMMAND);
  554.             EnableMenuItem(hmenuTrackPopup, IDM_DESELECT_ALL,
  555.                (fButtonState ? MF_ENABLED : MF_DISABLED|MF_GRAYED)|MF_BYCOMMAND);
  556.             EnableMenuItem(hmenuTrackPopup, IDM_SELECT_BY_PATTERN,
  557.                (fButtonState ? MF_ENABLED : MF_DISABLED|MF_GRAYED)|MF_BYCOMMAND);
  558.               /* Draw and track the "floating" popup */
  559. #ifdef WIN32
  560.               TrackPopupMenuEx(hmenuTrackPopup,
  561.                          TPM_LEFTALIGN | TPM_TOPALIGN |     /* default values */
  562.                          TPM_LEFTBUTTON | TPM_HORIZONTAL |  /* equivalent to 0 */
  563.                          TPM_RIGHTBUTTON,                   /* Right selection */
  564.                          pt.x, pt.y,
  565.                          hWnd,
  566.                          NULL);
  567. #else
  568.               TrackPopupMenu(hmenuTrackPopup,
  569.                          TPM_LEFTALIGN |   /* default values */
  570.                          TPM_LEFTBUTTON |  /* equivalent to 0 */
  571.                          TPM_RIGHTBUTTON,  /* Right selection */
  572.                          pt.x, pt.y, 0,
  573.                          hWnd,
  574.                          NULL);
  575. #endif
  576.               /* Destroy the menu since we are done with it. */
  577.               DestroyMenu(hmenu);
  578.               return 0;
  579.              }
  580.          /* The mouse was not in the list box, now let's check the edit box */
  581.          GetWindowRect(hWndEdit, &rc);
  582.          if (PtInRect(&rc, pt))
  583.             {
  584.             UINT fEnable;
  585.             UINT ichStart, ichEnd;
  586. #ifndef WIN32
  587.             DWORD dwResult;
  588. #endif
  589.             /* Get the edit control menu which we will use for the call to
  590.              * TrackPopup(). This could also be created on the fly using
  591.              * CreatePopupMenu and then using InsertMenu() or
  592.              * AppendMenu.
  593.              */
  594.             hmenu = LoadMenu(hInst, "EditMenu");
  595.             if (!hmenu)
  596.                return 0;
  597.             /* Get the edit menu from the parent of the edit control */
  598.             hmenuTrackPopup = GetSubMenu(hmenu, 1);
  599.             /* Is an "undo" operation possible? */
  600.                 fEnable = (UINT)SendMessage(hWndEdit, EM_CANUNDO, 0, 0);
  601.             EnableMenuItem(hmenuTrackPopup, IDM_EDIT_UNDO,
  602.                (fEnable ? MF_ENABLED : MF_DISABLED|MF_GRAYED)|MF_BYCOMMAND);
  603.                 /* Can we paste to the edit control? */
  604.                 if (OpenClipboard(hWnd))
  605.                    {
  606.                    /* Only allow text */
  607.                    if (IsClipboardFormatAvailable(CF_TEXT) ||
  608.                        IsClipboardFormatAvailable(CF_OEMTEXT))
  609.                        fEnable = TRUE;
  610.                    else
  611.                        fEnable = FALSE;
  612.                    }
  613.                 CloseClipboard();
  614.                 EnableMenuItem(hmenuTrackPopup, IDM_EDIT_PASTE,
  615.                     (fEnable ? MF_ENABLED : MF_DISABLED|MF_GRAYED)|MF_BYCOMMAND);
  616.                 /* Is anything selected in the edit control */
  617. #ifdef WIN32
  618.                 SendMessage(hWndEdit, EM_GETSEL, (WPARAM)&ichStart, (LPARAM)&ichEnd);
  619.             fEnable = (ichStart != ichEnd);
  620. #else
  621.                 dwResult = SendMessage(hWndEdit, EM_GETSEL, 0, 0);
  622.             ichStart = LOWORD(dwResult);
  623.             ichEnd = HIWORD(dwResult);
  624.             fEnable = (ichStart != ichEnd);
  625. #endif
  626.             EnableMenuItem(hmenuTrackPopup, IDM_EDIT_CUT,
  627.                (fEnable ? MF_ENABLED : MF_DISABLED|MF_GRAYED)|MF_BYCOMMAND);
  628.             EnableMenuItem(hmenuTrackPopup, IDM_EDIT_COPY,
  629.                (fEnable ? MF_ENABLED : MF_DISABLED|MF_GRAYED)|MF_BYCOMMAND);
  630.             EnableMenuItem(hmenuTrackPopup, IDM_EDIT_DELETE,
  631.                (fEnable ? MF_ENABLED : MF_DISABLED|MF_GRAYED)|MF_BYCOMMAND);
  632.             /* Anything in the edit control at all? */
  633.             fEnable = (UINT)SendMessage(hWndEdit, WM_GETTEXTLENGTH, 0, 0);
  634.             EnableMenuItem(hmenuTrackPopup, IDM_EDIT_SELECT_ALL,
  635.                (fEnable ? MF_ENABLED : MF_DISABLED|MF_GRAYED)|MF_BYCOMMAND);
  636.             EnableMenuItem(hmenuTrackPopup, IDM_CLEAR_STATUS,
  637.                (fEnable ? MF_ENABLED : MF_DISABLED|MF_GRAYED)|MF_BYCOMMAND);
  638.             /* Draw and track the "floating" popup */
  639. #ifdef WIN32
  640.             TrackPopupMenuEx(hmenuTrackPopup,
  641.                          TPM_LEFTALIGN | TPM_TOPALIGN |     /* default values */
  642.                          TPM_LEFTBUTTON | TPM_HORIZONTAL |  /* equivalent to 0 */
  643.                          TPM_RIGHTBUTTON,                   /* Right selection */
  644.                          pt.x, pt.y,
  645.                          hWndEdit,
  646.                          NULL);
  647. #else
  648.             TrackPopupMenu(hmenuTrackPopup,
  649.                          TPM_LEFTALIGN |      /* default values */
  650.                          TPM_LEFTBUTTON |
  651.                          TPM_RIGHTBUTTON,     /* Right selection */
  652.                          pt.x, pt.y, 0,
  653.                          hWnd,
  654.                          NULL);
  655. #endif
  656.            }
  657.         return 0;
  658.         }
  659.     /*
  660.      *
  661.      * This section is solely to cause the bubble help to be drawn with
  662.      * different colors than the background window. This is not necessary
  663.      * for 16 bit windows, as this is done for you.
  664.      *
  665.      */
  666. #ifdef WIN32
  667.     case WM_CTLCOLORSTATIC:
  668.            {
  669.            POINT point;
  670.            SetBkColor((HDC)wParam, GetSysColor(COLOR_INFOBK));
  671.            SetBkMode((HDC)wParam, OPAQUE);
  672.            SetTextColor((HDC)wParam, GetSysColor(COLOR_INFOTEXT));
  673.            point.x = point.y = 0;
  674.            ClientToScreen(hWnd, &point);
  675.            SetBrushOrgEx((HDC)wParam, point.x, point.y, NULL);
  676.            hBrush = CreateSolidBrush(GetSysColor(COLOR_INFOBK));
  677.            return ((DWORD)hBrush);
  678.            }
  679. #endif
  680.     case WM_COMMAND:
  681.         /* Was F1 just pressed in a menu, or are we in help mode */
  682.         /* (Shift-F1)? */
  683.         if (uf.fHelp)
  684.            {
  685.            GetHelpContext(wParam);
  686.            if ((!dwHelpContextId) && (uf.fHelp))
  687.               {
  688.               MessageBox( hWnd, "Context Help not available for this item",
  689.                          "Help Example", MB_OK);
  690.               }
  691.            else
  692.               if (uf.fHelp)
  693.                   WinHelp(hWnd,szHelpFileName,HELP_CONTEXT,dwHelpContextId);
  694.            uf.fHelp = FALSE;
  695.         }
  696.         else /* not in help mode */
  697.         {
  698. #ifndef WIN32
  699.         RECT  rClient;
  700. #endif
  701.             switch (LOWORD(wParam))
  702.             {
  703.             case IDM_GREP_ARCHIVE:
  704.                {
  705.                extern char baseDir[PATH_MAX];
  706.                extern char SearchPattern[PATH_MAX];
  707.                char *p, drive[2], szTmp[PATH_MAX];
  708.                OPENFILENAME ofn;
  709. #ifndef WIN32
  710.                FARPROC lpfnGrepArchive;
  711. #endif
  712. //               dwCommDlgHelpId = HELPID_MAKEDIR_HELP; /* if someone hits help */
  713.                if ( uf.fCanDragDrop )
  714.                     DragAcceptFiles( hWnd, FALSE );
  715. #ifndef WIN32
  716.                _fmemset(&ofn, '', sizeof(OPENFILENAME)); /* initialize struct */
  717. #else
  718.                memset(&ofn, '', sizeof(OPENFILENAME)); /* initialize struct */
  719. #endif
  720.                WinAssert(hWnd);
  721.                szTmp[0] = '';
  722.                ofn.lStructSize = sizeof(OPENFILENAME);
  723.                ofn.hwndOwner = hWnd;
  724.                ofn.hInstance = hInst;
  725.                ofn.lpstrFilter = "All Files (*.*)*.*";
  726.                ofn.nFilterIndex = 1;
  727.                ofn.lpstrFile = szTmp;
  728.                ofn.nMaxFile = PATH_MAX;
  729.                ofn.lpstrFileTitle = NULL;
  730.                ofn.nMaxFileTitle = PATH_MAX; /* ignored ! */
  731.                ofn.lpstrTitle = (LPSTR)"Find Files in Archive";
  732.                ofn.lpstrInitialDir = NULL;
  733.                ofn.Flags = OFN_SHOWHELP | OFN_ENABLEHOOK | OFN_CREATEPROMPT |
  734.                   OFN_HIDEREADONLY | OFN_ENABLETEMPLATE | OFN_NOCHANGEDIR;
  735. #ifndef WIN32
  736.                lpfnGrepArchive = MakeProcInstance((FARPROC)GrepArchiveProc, hInst);
  737. #   ifndef MSC
  738.                (UINT CALLBACK *)ofn.lpfnHook = (UINT CALLBACK *)lpfnGrepArchive;
  739. #   else
  740.                ofn.lpfnHook = lpfnGrepArchive;
  741. #   endif
  742. #else
  743.                ofn.lpfnHook = (LPOFNHOOKPROC)GrepArchiveProc;
  744. #endif
  745.                ofn.lpTemplateName = "GREPARCHIVES";   /* see grep.dlg   */
  746.                GetOpenFileName(&ofn);
  747.                if ((lstrlen(SearchPattern) != 0) &&
  748.                   (lstrlen(baseDir) != 0))
  749.                   {
  750.                   drive[0] = baseDir[0];
  751.                   drive[1] = '';
  752.                   p = &baseDir[2];
  753.                   /* Off we go - the control handle is set to null as a flag */
  754.                   FindFile(drive, p, NULL);
  755.                   }
  756.                }
  757.                if (uf.fCanDragDrop)
  758.                    DragAcceptFiles(hWnd, TRUE);
  759.                break;
  760. #ifndef WIN32
  761.             /* Deal with the Edit box menu items */
  762.             case IDM_EDIT_UNDO:
  763.                     SendMessage(hWndEdit, EM_UNDO, 0, 0);
  764.                break;
  765.             case IDM_EDIT_CUT:
  766.                     SendMessage(hWndEdit, WM_CUT, 0, 0);
  767.                break;
  768.             case IDM_EDIT_COPY:
  769.                     SendMessage(hWndEdit, WM_COPY, 0, 0);
  770.                break;
  771.             case IDM_EDIT_PASTE:
  772.                     SendMessage(hWndEdit, WM_PASTE, 0, 0);
  773.                break;
  774.             case IDM_EDIT_DELETE:
  775.                     SendMessage(hWndEdit, WM_CLEAR, 0, 0);
  776.                SetWindowText(hWndStatic, "WiZ Edit/Status Window");
  777.                break;
  778.             case IDM_EDIT_SELECT_ALL:
  779.                     SendMessage(hWndEdit, EM_SETSEL, (WPARAM)0,
  780.                   (LPARAM)MAKELPARAM(0,-1));
  781.                break;
  782. #endif
  783.             case IDM_ZIP_TARGET:
  784.             case IDM_ZIP_PREFERENCES:
  785.             case IDM_UNZIP_PREFERENCES:
  786.                 if ( uf.fCanDragDrop )
  787.                     DragAcceptFiles( hWnd, FALSE );
  788.                 ZipWndProc(hWnd, wMessage, wParam, lParam);
  789.                 WriteZipOptionsProfile();
  790.                 if ( uf.fCanDragDrop )
  791.                     DragAcceptFiles( hWnd, TRUE );
  792.                break;
  793.             case IDM_OPEN:
  794.                 /* If unzipping separately and previous file exists,
  795.                  * go to directory where archive lives.
  796.                  */
  797.                 if ( uf.fCanDragDrop )
  798.                     DragAcceptFiles( hWnd, FALSE );
  799.             /* If not unzipping to same directory as archive and
  800.              * file already open, go to where file lives.
  801.              * If extracting to different directory, return to
  802.              * that directory after selecting archive to open.
  803.              */
  804.             if (lpumb->szUnzipFromDirName[0])
  805.                {
  806.                lstrcpy(lpumb->szDirName, lpumb->szUnzipFromDirName);
  807.                }
  808.             if (lpumb->szFileName[0])
  809.                {
  810.                /* strip off filename to make directory name    */
  811.                GetArchiveDir(lpumb->szDirName);
  812.                }
  813.             else
  814.                {
  815.                if (!lpumb->szUnzipFromDirName[0])
  816.                   lpumb->szDirName[0] = ''; /* assume no dir   */
  817.                }
  818.             lpumb->szBuffer[0] = '';
  819. #ifndef WIN32
  820.             _fmemset(&lpumb->ofn, '', sizeof(OPENFILENAME)); /* initialize struct */
  821. #else
  822.             memset(&lpumb->ofn, '', sizeof(OPENFILENAME)); /* initialize struct */
  823. #endif
  824.             lpumb->ofn.lStructSize = sizeof(OPENFILENAME);
  825.             lpumb->ofn.hwndOwner = hWnd;
  826.             lpumb->ofn.lpstrFilter = "Zip Files (*.zip)*.zipSelf-extracting Files (*.exe)*.exeAll Files (*.*)*.*";
  827.             lpumb->ofn.nFilterIndex = 1;
  828.             lpumb->ofn.lpstrFile = lpumb->szFileName;
  829.             lpumb->szFileName[0] = '';   /* no initial filename   */
  830.             lpumb->ofn.nMaxFile = PATH_MAX;
  831.             lpumb->ofn.lpstrFileTitle = lpumb->szBuffer; /* ignored */
  832.             lpumb->ofn.lpstrInitialDir = (LPSTR)(!lpumb->szDirName[0] ? NULL : lpumb->szDirName);
  833.             lpumb->ofn.nMaxFileTitle = PATH_MAX;
  834.             lpumb->ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST |
  835.                    OFN_HIDEREADONLY|OFN_NOVALIDATE;
  836.             dwCommDlgHelpId = HELPID_OPEN; /* specify correct help for open dlg   */
  837.             if (GetOpenFileName(&lpumb->ofn))   /* if successful file open  */
  838.                {
  839.                /* Yes, you should be able to get the fully qualified path name
  840.                   in lpumb->szFileName when you return from GetOpenFileName(),
  841.                   however, at least Borland 4.52 (others?) does not return a fully
  842.                   qualified path, but simply the file name. This kludge gets
  843.                   around that.
  844.                 */  
  845.                getcwd(lpumb->szDirName, PATH_MAX);
  846.                /* If we get a fully qualified file name, then the second
  847.                   character should be a colon.
  848.                 */
  849.                if (lpumb->szFileName[1] != ':')
  850.                   {
  851.                   lstrcpy(lpumb->szBuffer, lpumb->szDirName);
  852.                   if (lpumb->szBuffer[lstrlen(lpumb->szBuffer)-1] != '\')
  853.                      lstrcat(lpumb->szBuffer, "\");
  854.                   lstrcat(lpumb->szBuffer, lpumb->szFileName);
  855.                   lstrcpy(lpumb->szFileName, lpumb->szBuffer);
  856.                   }
  857.                /*
  858.                Save the last "unzip from" directory
  859.                */
  860.                if (lpumb->szDirName[1] == ':')
  861.                   drive = lpumb->szDirName[0];
  862.                else
  863.                   drive = '';
  864.                if (uf.fSaveUnZipFromDir &&
  865.                   (toupper(drive) != 'A') &&
  866.                   (toupper(drive) != 'B'))
  867.                   {
  868.                   lstrcpy(lpumb->szUnzipFromDirName, lpumb->szDirName);
  869.                   if (lpumb->szUnzipFromDirName[strlen(lpumb->szUnzipFromDirName)-1]
  870.                      == ':')
  871.                      lstrcat(lpumb->szUnzipFromDirName, "\");
  872.                   WritePrivateProfileString(szAppName, szDefaultUnzipFromDir,
  873.                                  lpumb->szUnzipFromDirName, szWiZIniFile);
  874.                   }
  875.                else
  876.                   WritePrivateProfileString(szAppName, szDefaultUnzipFromDir,
  877.                                  "", szWiZIniFile);
  878.                if (uf.fUnzipToZipDir || /* unzipping to same directory as archive */
  879.                   szUnzipToDirName[0] == '') /* or no default */
  880.                   {
  881.                   /* strip off filename to make directory name    */
  882.                   lstrcpy(szUnzipToDirName, lpumb->szDirName);
  883.                   }
  884.                }
  885.                UpdateListBox(); /* fill in list box */
  886. #ifndef WIN32
  887.                SendMessage(hWndList, LB_SETSEL, 1, 0L);
  888. #else
  889.                 ListViewSetSel(0, TRUE);
  890. #endif               
  891.                UpdateButtons(); /* update state of buttons */
  892.                SetCaption(hWnd);
  893. #ifndef WIN32
  894.                /* Update archive totals area */
  895.                WinAssert(hWndList);
  896.                GetClientRect( hWndList, &rClient );
  897.                OffsetRect( &rClient, 0, dyChar );
  898.                rClient.top = rClient.bottom;
  899.                rClient.bottom = rClient.top + (6*dyChar);
  900.                InvalidateRect( hWnd, &rClient, TRUE);
  901. #endif
  902.                if ( uf.fCanDragDrop )
  903.                   DragAcceptFiles( hWnd, TRUE );
  904.                break;
  905.             case IDM_CHDIR:
  906.                 if ( uf.fCanDragDrop )
  907.                     DragAcceptFiles( hWnd, FALSE );
  908. #ifndef WIN32
  909.                 _fmemset(&lpumb->ofn, '', sizeof(OPENFILENAME)); /* initialize struct */
  910. #else
  911.                 memset(&lpumb->ofn, '', sizeof(OPENFILENAME)); /* initialize struct */
  912. #endif
  913.                 lpumb->ofn.lStructSize = sizeof(OPENFILENAME);
  914.                 lpumb->ofn.hwndOwner = hWnd;
  915.                 lpumb->ofn.hInstance = hInst;
  916.                 lpumb->ofn.lpstrFilter = "All Files (*.*)*.*";
  917.                 lpumb->ofn.nFilterIndex = 1;
  918.                 lstrcpy(lpumb->szUnzipToDirNameTmp, szUnzipToDirName); /* initialize */
  919.                 { /* Braces are here to allow the declaration of uDirNameLen */
  920. #ifndef WIN32
  921.                 size_t uDirNameLen = _fstrlen(lpumb->szUnzipToDirNameTmp);
  922. #else
  923.                 size_t uDirNameLen = strlen(lpumb->szUnzipToDirNameTmp);
  924. #endif
  925.                /* If '\' not at end of directory name, add it now.
  926.                 */
  927.                 if (uDirNameLen > 0 && lpumb->szUnzipToDirNameTmp[uDirNameLen-1] != '\')
  928.                    lstrcat(lpumb->szUnzipToDirNameTmp, "\");
  929.                 }
  930.                 lstrcat(lpumb->szUnzipToDirNameTmp,
  931.                     "johnny376376.375374373"); /* fake name */
  932.                 lpumb->ofn.lpstrFile = lpumb->szUnzipToDirNameTmp; /* result goes here! */
  933.                 lpumb->ofn.nMaxFile = PATH_MAX;
  934.                 lpumb->ofn.lpstrFileTitle = NULL;
  935.                 lpumb->ofn.nMaxFileTitle = PATH_MAX; /* ignored ! */
  936.                 lpumb->ofn.lpstrInitialDir = szUnzipToDirName;
  937.                 lpumb->ofn.lpstrTitle = (LPSTR)"Unzip To";
  938.                 lpumb->ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST |
  939.                            OFN_HIDEREADONLY|OFN_NOCHANGEDIR;
  940.                 lpumb->ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST | OFN_ENABLEHOOK |
  941.                            OFN_HIDEREADONLY|OFN_ENABLETEMPLATE|OFN_NOCHANGEDIR;
  942. #ifndef WIN32
  943.                 lpfnSelectDir =
  944.                   MakeProcInstance((FARPROC)SelectDirProc, hInst);
  945. #ifndef MSC
  946.                 (UINT CALLBACK *)lpumb->ofn.lpfnHook = (UINT CALLBACK *)lpfnSelectDir;
  947. #else
  948.                 lpumb->ofn.lpfnHook = lpfnSelectDir;
  949. #endif
  950. #else
  951.                 lpumb->ofn.lpfnHook = (LPOFNHOOKPROC)SelectDirProc;
  952. #endif
  953.                 lpumb->ofn.lpTemplateName = "SELDIR";   /* see seldir.dlg   */
  954.                 dwCommDlgHelpId = HELPID_CHDIR; /* in case user hits "help" button */
  955.                 if (GetSaveFileName(&lpumb->ofn)) /* successfully got dir name ? */
  956.                    {
  957. #ifndef WIN32
  958.                    ptr = _fstrrchr(lpumb->ofn.lpstrFile, '\');
  959. #else
  960.                    ptr = strrchr(lpumb->ofn.lpstrFile, '\');
  961. #endif
  962.                    if (ptr != NULL)
  963.                       lpumb->ofn.lpstrFile[(int)(ptr - lpumb->ofn.lpstrFile)] = '';
  964.                    lstrcpy(szUnzipToDirName, lpumb->ofn.lpstrFile); /* save result */
  965.                    if (szUnzipToDirName[1] == ':')
  966.                       {
  967.                       drive = szUnzipToDirName[0];
  968.                       if (lstrlen(szUnzipToDirName) == 2)
  969.                          { /* We only have a drive letter and a colon */
  970.                          lstrcat(szUnzipToDirName, "\");
  971.                          }
  972.                       }
  973.                    else
  974.                       drive = '';
  975.                    if (uf.fSaveUnZipToDir &&
  976.                       (toupper(drive) != 'A') &&
  977.                       (toupper(drive) != 'B'))
  978.                        {
  979.                   /* Always save last directory written to */
  980.                        WritePrivateProfileString(szAppName, szDefaultUnzipToDir,
  981.                           szUnzipToDirName, szWiZIniFile);
  982.                        }
  983.                    SetCaption(hWnd);
  984.                    }
  985.                 else /* either real error or canceled */
  986.                    {
  987.                    DWORD dwExtdError = CommDlgExtendedError(); /* debugging */
  988.                    if (dwExtdError != 0L) /* if not canceled then real error */
  989.                       {
  990.                       wsprintf (lpumb->szBuffer, szCantChDir, dwExtdError);
  991.                       MessageBox (hWnd, lpumb->szBuffer, szAppName, MB_ICONINFORMATION | MB_OK);
  992.                       }
  993.                    }
  994. #ifndef WIN32
  995.                 FreeProcInstance(lpfnSelectDir);
  996. #endif
  997.                 if ( uf.fCanDragDrop )
  998.                     DragAcceptFiles( hWnd, TRUE );
  999.                 break;
  1000.             case IDM_DELETE_ARCHIVE:
  1001.                 {
  1002.                 char szStr[PATH_MAX];
  1003.                 if ( uf.fCanDragDrop )
  1004.                     DragAcceptFiles( hWnd, FALSE );
  1005.                 sprintf(szStr, "Are you sure you want to deleten%s", lpumb->szFileName);
  1006.                 if (MessageBox(hWnd, szStr, "Deleting File", MB_ICONSTOP | MB_OKCANCEL) == IDOK)
  1007.                    {
  1008.                    remove(lpumb->szFileName);
  1009.                    BufferOut("Deleting %sn", lpumb->szFileName);
  1010. #ifndef WIN32
  1011.                    SendMessage(hWndList, LB_RESETCONTENT, 0, 0);
  1012. #else
  1013.                    ListView_DeleteAllItems(hWndList);
  1014. #endif
  1015.                    lpumb->szFileName[0] = '';
  1016.                    SetCaption(hWnd);
  1017.                    UpdateButtons(); /* update state of buttons */
  1018.                    }
  1019.                 if ( uf.fCanDragDrop )
  1020.                   DragAcceptFiles( hWnd, TRUE );
  1021.                 break;
  1022.                 }
  1023.             case IDM_MOVE_ARCHIVE:
  1024.                 /*
  1025.                  * Yes - this can be done under Win32 differently, but
  1026.                  * you have to go through some hoops, and this just makes
  1027.                  * it easier.
  1028.                  */
  1029.                 move_flag = TRUE;
  1030.                 dwCommDlgHelpId = HELPID_MOVE_ARCHIVE; /* in case user hits "help" button */
  1031.             case IDM_RENAME_ARCHIVE:
  1032.                 if (!move_flag)
  1033.                    {
  1034.                    rename_flag = TRUE;
  1035.                    dwCommDlgHelpId = HELPID_RENAME_ARCHIVE; /* in case user hits "help" button */
  1036.                    }
  1037.             case IDM_COPY_ARCHIVE:
  1038.                 if ( uf.fCanDragDrop )
  1039.                     DragAcceptFiles( hWnd, FALSE );
  1040.                 if ((!move_flag) && (!rename_flag))
  1041.                    dwCommDlgHelpId = HELPID_COPY_ARCHIVE; /* in case user hits "help" button */
  1042.                 CopyArchive(hWnd, move_flag, rename_flag);
  1043.                 if ( uf.fCanDragDrop )
  1044.                     DragAcceptFiles( hWnd, TRUE );
  1045.                 move_flag = FALSE;
  1046.                 rename_flag = FALSE;
  1047.                 break;
  1048.             case IDM_EXIT:
  1049.                 WriteZipOptionsProfile();
  1050.                 SendMessage(hWnd, WM_CLOSE, 0, 0L);
  1051.                 break;
  1052.             case IDM_HELP:  /* Display Help */
  1053. #ifndef WIN32
  1054.                 WinHelp(hWnd,szHelpFileName,HELP_INDEX,0L);
  1055. #else
  1056.                 WinHelp(hWnd,szHelpFileName,HELP_FINDER,0L);
  1057. #endif
  1058.                 break;
  1059.             case IDM_SHIFT_HELP:
  1060.                 uf.fHelp = TRUE;
  1061.                 SetCursor(hHelpCursor);
  1062.                 break;
  1063.             case IDM_ESCAPE:
  1064.                 if (uf.fHelp)
  1065.                     {
  1066.                    uf.fHelp = FALSE;
  1067. #ifndef WIN32
  1068.                    SetCursor((HCURSOR)GetClassWord(hWndMain,GCW_HCURSOR));
  1069. #else
  1070.                    SetCursor((HCURSOR)GetClassLong(hWndMain,GCL_HCURSOR));
  1071. #endif
  1072.                    dwHelpContextId = (DWORD) 0L;
  1073.                    return 0;
  1074.                    }
  1075.                 break;
  1076.             case IDM_HELP_HELP:
  1077.                 WinHelp(hWnd,"WINHELP.HLP",HELP_INDEX,0L);
  1078.                 break;
  1079.             case IDM_ABOUT:
  1080.                 if ( uf.fCanDragDrop )
  1081.                     DragAcceptFiles( hWnd, FALSE );
  1082. #ifndef WIN32
  1083.                 lpfnAbout = MakeProcInstance(AboutProc, hInst);
  1084.                 DialogBox(hInst, "About", hWnd, lpfnAbout);
  1085.                 FreeProcInstance(lpfnAbout);
  1086. #else
  1087.                 DialogBox(hInst, "About", hWnd, AboutProc);
  1088. #endif
  1089.                 if ( uf.fCanDragDrop )
  1090.                     DragAcceptFiles( hWnd, TRUE );
  1091.                 break;
  1092. #ifndef WIN32
  1093.             case IDM_LISTBOX:       /* command from listbox     */
  1094.                 if (cZippedFiles)
  1095.                 {
  1096.                     switch (GET_WM_COMMAND_CMD(wParam, lParam))
  1097.                     {
  1098.                     case LBN_SELCHANGE:
  1099.                         UpdateButtons();
  1100.                         break;
  1101.                     case LBN_DBLCLK:
  1102.                         UpdateButtons();
  1103.                         if ( uf.fCanDragDrop )
  1104.                             DragAcceptFiles( hWnd, FALSE );
  1105.                         Action(hWnd, (WPARAM)(wLBSelection - IDM_LB_EXTRACT));
  1106.                         if ( uf.fCanDragDrop )
  1107.                             DragAcceptFiles( hWnd, TRUE );
  1108.                         break;
  1109.                     }
  1110.                 }
  1111.                 break;
  1112.             case IDM_LONG:
  1113.             case IDM_SHORT:
  1114.                 /* If format change, uncheck old, check new. */
  1115.                 if ((LOWORD(wParam) - IDM_SHORT) != (signed int)uf.fFormatLong)
  1116.                 {
  1117.                     WPARAM wFormatTmp = (WPARAM)(LOWORD(wParam)  - IDM_SHORT);
  1118.                     int __far *pnSelItems; /* pointer to list of selected items */
  1119.                     HANDLE  hnd = 0;
  1120.                     int cSelLBItems ; /* no. selected items in listbox */
  1121.                     RECT    rClient;
  1122.                     cSelLBItems = CLBItemsGet(hWndList, &pnSelItems, &hnd);
  1123.                     CheckMenuItem(hMenu, (IDM_SHORT+uf.fFormatLong), MF_BYCOMMAND|MF_UNCHECKED);
  1124.                     CheckMenuItem(hMenu, (IDM_SHORT+wFormatTmp), MF_BYCOMMAND|MF_CHECKED);
  1125.                     uf.fFormatLong = wFormatTmp;
  1126.                     UpdateListBox();
  1127.                     WriteZipOptionsProfile();
  1128.                     /* anything previously selected ? */
  1129.                     if (cSelLBItems > 0)
  1130.                        {
  1131.                        ReselectLB(hWndList, cSelLBItems, pnSelItems);
  1132.                        GlobalUnlock(hnd);
  1133.                        GlobalFree(hnd);
  1134.                        }
  1135.                     /* make sure labels & Zip archive totals get updated */
  1136.                     WinAssert(hWnd);
  1137.                     GetClientRect( hWnd, &rClient );
  1138.                     /* Drop down two lines for button row */
  1139.                     rClient.top = (2*dyChar);
  1140.                     rClient.bottom = rClient.top + (2*dyChar);
  1141.                     /* Okay, now we selected only the "header" for
  1142.                      * repainting, invalidate it.
  1143.                      */
  1144.                     InvalidateRect( hWnd, &rClient, TRUE);
  1145.                     WinAssert(hWndList);
  1146.                     GetClientRect( hWndList, &rClient );
  1147.                     rClient.top = rClient.bottom;
  1148.                     /* Now allow for two lines for button row,
  1149.                      * two lines for the "header" and two lines
  1150.                      * for the trailer. Then invalidate it.
  1151.                      */
  1152.                     rClient.bottom = rClient.top + (6*dyChar);
  1153.                     InvalidateRect( hWnd, &rClient, TRUE);
  1154.                 }
  1155.                 break;
  1156. #endif
  1157.             case IDM_SAVE_UNZIP_TO_DIR:
  1158.                 /* Toggle value of fSaveUnzipToDir flag. */
  1159.                 uf.fSaveUnZipToDir = !uf.fSaveUnZipToDir;
  1160.                 CheckMenuItem(hMenu,IDM_SAVE_UNZIP_TO_DIR,MF_BYCOMMAND|
  1161.                                 (WORD)(uf.fSaveUnZipToDir ? MF_CHECKED: MF_UNCHECKED));
  1162.                 WriteZipOptionsProfile();
  1163.                 if (uf.fSaveUnZipToDir)
  1164.                    WritePrivateProfileString(szAppName, szDefaultUnzipToDir,
  1165.                          "", szWiZIniFile);
  1166.                 break;
  1167.             case IDM_SAVE_UNZIP_FROM_DIR:
  1168.                 /* Toggle value of fSaveUnzipToDir flag. */
  1169.                 uf.fSaveUnZipFromDir = !uf.fSaveUnZipFromDir;
  1170.                 CheckMenuItem(hMenu,IDM_SAVE_UNZIP_FROM_DIR,MF_BYCOMMAND|
  1171.                                 (WORD)(uf.fSaveUnZipFromDir ? MF_CHECKED: MF_UNCHECKED));
  1172.                 WriteZipOptionsProfile();
  1173.                 if (uf.fSaveUnZipFromDir)
  1174.                    WritePrivateProfileString(szAppName, szDefaultUnzipFromDir,
  1175.                          "", szWiZIniFile);
  1176.                 break;
  1177.             case IDM_UNZIP_TO_ZIP_DIR:
  1178.                 /* toggle value of Unzip to .ZIP  */
  1179.                 uf.fUnzipToZipDir = !uf.fUnzipToZipDir;
  1180.                 CheckMenuItem(hMenu,IDM_UNZIP_TO_ZIP_DIR,MF_BYCOMMAND|
  1181.                                     (WORD)(uf.fUnzipToZipDir ? MF_CHECKED:MF_UNCHECKED));
  1182.                 EnableMenuItem(hMenu,IDM_CHDIR,MF_BYCOMMAND|
  1183.                                     (WORD)(uf.fUnzipToZipDir ? MF_GRAYED:MF_ENABLED));
  1184.                 WriteZipOptionsProfile();
  1185.                 if (uf.fUnzipToZipDir && lpumb->szDirName[0])
  1186.                    {
  1187.                    lstrcpy(szUnzipToDirName, lpumb->szDirName); /* get new dirname */
  1188.                    SetCaption(hWnd);
  1189.                    }
  1190.                 break;
  1191.             case IDM_SAVE_ZIP_TO_DIR:
  1192.                fSaveZipToDir = !fSaveZipToDir;
  1193.                CheckMenuItem(hMenu, IDM_SAVE_ZIP_TO_DIR,
  1194.                   MF_BYCOMMAND | (fSaveZipToDir ? MF_CHECKED : MF_UNCHECKED));
  1195.                if (!fSaveZipToDir)
  1196.                   szTargetZipDir[0] = '';
  1197.                WriteZipOptionsProfile();
  1198.                break;
  1199.             case IDM_MAKE_DIR:
  1200.                {
  1201.                FARPROC lpfnMakeDir;
  1202.                dwCommDlgHelpId = HELPID_MAKEDIR_HELP; /* if someone hits help */
  1203.                lpfnMakeDir = MakeProcInstance(MakeDirProc, hInst);
  1204.                DialogBox(hInst, "MAKEDIR", hWnd, lpfnMakeDir);
  1205. #ifndef WIN32
  1206.                FreeProcInstance(lpfnMakeDir);
  1207. #endif
  1208.                }
  1209.                break;
  1210.             case IDM_SOUND_OPTIONS: /* launch Sound Options dialog box   */
  1211.              {
  1212.             FARPROC lpfnSoundOptions;
  1213.             dwCommDlgHelpId = HELPID_SOUND_OPTIONS; /* if someone hits "help" */
  1214.                 lpfnSoundOptions = MakeProcInstance(SoundProc, hInst);
  1215.                 DialogBox(hInst, "SOUND", hWnd, lpfnSoundOptions);
  1216. #ifndef WIN32
  1217.                 FreeProcInstance(lpfnSoundOptions);
  1218. #endif
  1219.             }
  1220.                 break;
  1221.             case IDM_SHOW_COMMENT:
  1222.                 /* display the archive comment in mesg window */
  1223.                 if ( uf.fCanDragDrop )
  1224.                     DragAcceptFiles( hWnd, FALSE );
  1225.                 DisplayComment(hWnd);
  1226.                 if ( uf.fCanDragDrop )
  1227.                     DragAcceptFiles( hWnd, TRUE );
  1228.                 break;
  1229.             case IDM_SHOW_BUBBLE_HELP:
  1230.                 /* Show toolbar help */
  1231.                 uf.fShowBubbleHelp = !uf.fShowBubbleHelp;
  1232.                 CheckMenuItem(hMenu, IDM_SHOW_BUBBLE_HELP,
  1233.                  MF_BYCOMMAND | (uf.fShowBubbleHelp ? MF_CHECKED : MF_UNCHECKED));
  1234.                 WriteZipOptionsProfile();
  1235.                 break;
  1236.             case IDM_GET_ZIPINFO:
  1237.             case IDM_UPDATE_ZIP:
  1238.             case IDM_DISPLAY:
  1239.             case IDM_TEST:
  1240.             case IDM_EXTRACT:
  1241.             case IDM_ZIP_DELETE_ENTRIES:
  1242.                 if ( uf.fCanDragDrop )
  1243.                     DragAcceptFiles( hWnd, FALSE );
  1244.                 fUpdateEntries = TRUE;
  1245.                 Action(hWnd, (WPARAM)(LOWORD(wParam) - IDM_EXTRACT));
  1246.                 if (ZpOpt.fOffsets)
  1247.                    {
  1248. #ifndef WIN32
  1249.                    DWORD i;
  1250.                    i = SendMessage(hWndList , LB_GETCOUNT, 0, 0);
  1251.                    SendMessage(hWndList , LB_SELITEMRANGE,
  1252.                           (WPARAM) FALSE, MAKELONG(0, i));
  1253. #else
  1254.                    DWORD i, j;
  1255.                    i = ListView_GetItemCount(hWndList);
  1256.                    for (j = 0; j < i; j++)
  1257.                         ListViewSetSel(j, TRUE);
  1258. #endif
  1259.                    }
  1260.                 if ( uf.fCanDragDrop )
  1261.                     DragAcceptFiles( hWnd, TRUE );
  1262.                 break;
  1263.             case IDM_SELECT_ALL:
  1264.             case IDM_DESELECT_ALL:
  1265.                 if (cZippedFiles)
  1266.                    {
  1267. #ifndef WIN32
  1268.                    SendMessage(hWndList , LB_SELITEMRANGE,
  1269.                           (WPARAM)(LOWORD(wParam) == IDM_DESELECT_ALL ? FALSE : TRUE),
  1270.                           MAKELONG(0, (cZippedFiles-1)));
  1271. #else
  1272.                    int i;
  1273.                    int iItems = ListView_GetItemCount(hWndList);
  1274.                    if (LOWORD(wParam) == IDM_DESELECT_ALL)
  1275.                        for (i = 0; i < iItems; i++)
  1276.                            ListViewSetSel(i, FALSE);
  1277.                    else
  1278.                        for (i = 0; i < iItems; i++)
  1279.                            ListViewSetSel(i, TRUE);
  1280. #endif
  1281.                    UpdateButtons();
  1282.                    }
  1283.                 break;
  1284.          case IDM_SELECT_BY_PATTERN:
  1285.             if (!hPatternSelectDlg)
  1286.                {
  1287.                DLGPROC lpfnPatternSelect;
  1288.                dwCommDlgHelpId = HELPID_SELECT_BY_PATTERN;
  1289.                lpfnPatternSelect = (DLGPROC)MakeProcInstance(PatternSelectProc, hInst);
  1290.                WinAssert(lpfnPatternSelect)
  1291.                hPatternSelectDlg =
  1292.                CreateDialog(hInst, "PATTERN", hWnd, lpfnPatternSelect);
  1293.                WinAssert(hPatternSelectDlg);
  1294.                }
  1295.             break;
  1296.          case IDM_CLEAR_STATUS:  /* forward to status window */
  1297.             SendMessage(hWndEdit, WM_COMMAND, IDM_CLEAR_STATUS, 0L);
  1298.             break;
  1299.          case IDM_EDIT_SAVE_AS:
  1300.             {
  1301.             OFSTRUCT ofs;
  1302.             char szFilename[PATH_MAX] = "";
  1303.             char *p;
  1304. #ifdef WIN32
  1305.             DWORD bytes_written;
  1306.             HANDLE hFile;
  1307. #else
  1308.             HFILE hFile;
  1309. #endif
  1310.             memset(&ofnTemp, 0, sizeof (ofnTemp));
  1311.             memset(&ofs, 0, sizeof(ofs));
  1312.             GetWindowText(hWndStatic, szFilename, PATH_MAX);
  1313.             for (p = szFilename; *p; p++)
  1314.                if (*p == '/')
  1315.                   *p = '\';
  1316.             ofnTemp.lStructSize = sizeof (ofnTemp);
  1317.             ofnTemp.hwndOwner = hWndMain;
  1318.             ofnTemp.hInstance = hInst;
  1319.             ofnTemp.lpstrFilter = "All Files (*.*)*.*";
  1320.             ofnTemp.nFilterIndex = 1;
  1321.             ofnTemp.lpstrFile = szFilename;
  1322.             ofnTemp.nMaxFile = PATH_MAX;
  1323.             ofnTemp.lpstrInitialDir = NULL;
  1324.             ofnTemp.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
  1325.              if (GetSaveFileName (&ofnTemp))
  1326.                {
  1327.                unsigned int txtlen;
  1328.                txtlen = (unsigned int)SendMessage(hWndEdit, WM_GETTEXTLENGTH, 0, 0);
  1329.                if (txtlen != 0)
  1330.                   txtlen++;
  1331.                SendMessage(hWndEdit, WM_GETTEXT, txtlen, (LPARAM)pszBuffer);
  1332. #ifndef WIN32
  1333.                hFile = OpenFile(szFilename, &ofs, OF_CREATE);
  1334.                _lwrite (hFile, pszBuffer, lstrlen(pszBuffer));
  1335.                _lclose (hFile);
  1336. #else
  1337.                hFile = CreateFile(szFilename, GENERIC_WRITE, 0, NULL,
  1338.                   CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  1339.                WriteFile(hFile, pszBuffer, lstrlen(pszBuffer), &bytes_written,NULL);
  1340.                CloseHandle(hFile);
  1341. #endif
  1342.                SetWindowText(hWndStatic, szFilename);
  1343.                }
  1344.             }
  1345.             break;
  1346.          case IDM_EDIT_OPEN_FILE:
  1347.             {
  1348.             OFSTRUCT ofs;
  1349.             char szFilename[PATH_MAX] = "";
  1350. #ifdef WIN32
  1351.             DWORD bytes_written, dwSize;
  1352.             HANDLE hFile;
  1353. #else
  1354.             HFILE hFile;
  1355. #endif
  1356.             memset(&ofnTemp, 0, sizeof (ofnTemp));
  1357.             memset(&ofs, 0, sizeof(ofs));
  1358.             ofnTemp.lStructSize = sizeof (ofnTemp);
  1359.             ofnTemp.hwndOwner = hWndMain;
  1360.             ofnTemp.hInstance = hInst;
  1361.             ofnTemp.lpstrFilter = "All Files (*.*)*.*";
  1362.             ofnTemp.nFilterIndex = 1;
  1363.             ofnTemp.lpstrFile = szFilename;
  1364.             ofnTemp.nMaxFile = PATH_MAX;
  1365.             ofnTemp.lpstrInitialDir = NULL;
  1366.             ofnTemp.Flags = OFN_FILEMUSTEXIST;
  1367.             if (GetOpenFileName (&ofnTemp))
  1368.                {
  1369.                extern BOOL MapCRtoCRLF(LPSTR);
  1370.                SendMessage(hWndEdit, WM_COMMAND, IDM_CLEAR_STATUS, 0L);
  1371. #ifndef WIN32
  1372.                hFile = OpenFile(szFilename, &ofs, OF_READ);
  1373.                _lread (hFile, pszBuffer, (UINT)EDIT_BUF_SIZE);
  1374.                _lclose (hFile);
  1375. #else
  1376.                hFile = CreateFile(szFilename, GENERIC_READ, 0, NULL,
  1377.                   OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL);
  1378.                dwSize = GetFileSize(hFile, NULL);
  1379.                if (dwSize >= (dwEditBufSize - 1))
  1380.                   {
  1381.                   HGLOBAL hTemp;
  1382.                   GlobalUnlock(hEditor);
  1383.                   hTemp = GlobalReAlloc(hEditor, dwSize + 0x1000,
  1384.                      GMEM_MOVEABLE|GMEM_ZEROINIT);
  1385.                   if (hTemp)
  1386.                      {
  1387.                      hEditor = hTemp;
  1388.                      dwEditBufSize = dwSize + 0x1000;
  1389.                      }
  1390.                   else
  1391.                      MessageBox(hWndMain,
  1392.                         "Cannot allocate enough memory for file. Truncating file.",
  1393.                         "Insufficient Memory",
  1394.                         MB_ICONINFORMATION|MB_OK);
  1395.                   pszBuffer = GlobalLock(hEditor);
  1396.                   memset(pszBuffer, '', dwEditBufSize);
  1397.                   }
  1398.                ReadFile(hFile, pszBuffer, dwSize, &bytes_written, NULL);
  1399.                CloseHandle(hFile);
  1400. #endif
  1401.                /* Convert CR to CRLF and strip formfeeds */
  1402.                MapCRtoCRLF(pszBuffer);
  1403.                SendMessage(hWndEdit, WM_SETTEXT, 0, (LPARAM)pszBuffer);
  1404.                SetWindowText(hWndStatic, szFilename);
  1405.                UpdateWindow(hWndEdit);
  1406.                }
  1407.             }
  1408.             break;
  1409.          case IDM_MAX_STATUS:
  1410.             {
  1411.             SendMessage(hStatusButton, WM_LBUTTONDOWN,
  1412.                   MK_LBUTTON, MAKELPARAM(5,5) );
  1413.             break;
  1414.             }
  1415.          case IDM_SETFOCUS_ON_STATUS: /* posted from Action() following extract-to-Status */
  1416.             SetFocus(hWndEdit);   /* set focus on Status so user can scroll */
  1417.             break;
  1418.          case IDM_ZIP_STATS:
  1419.             {
  1420.             char szCompFactor[10];
  1421.             char sgn;
  1422.             char CompFactorStr[] = "%c%d%%";
  1423.             char CompFactor100[] = "100%%";
  1424.             if (lpumb->szFileName[0])   /* if file selected */
  1425.                {
  1426.                if (lpUserFunctions->TotalSizeComp > lpUserFunctions->TotalSize)
  1427.                   sgn = '-';
  1428.                else
  1429.                   sgn = ' ';
  1430.                if (lpUserFunctions->CompFactor == 100)
  1431.                    sprintf(szCompFactor, CompFactor100);
  1432.                else
  1433.                    sprintf(szCompFactor, CompFactorStr, sgn,
  1434.                       lpUserFunctions->CompFactor);
  1435.                wsprintf(szTotalsLine,
  1436.                "Total Sizett%7lunCompressed Sizet%7lunRatiott%6snTotal Filest%7u",
  1437.                       lpUserFunctions->TotalSize,
  1438.                       lpUserFunctions->TotalSizeComp,
  1439.                       szCompFactor,
  1440.                       lpUserFunctions->NumMembers);
  1441.                MessageBox(hWndMain, szTotalsLine,
  1442.                   lpumb->szFileName, MB_ICONINFORMATION | MB_OK);
  1443.                }
  1444.             }
  1445.             break;
  1446.          default:
  1447.             return DefWindowProc(hWnd, wMessage, wParam, lParam);
  1448.             }
  1449.         } /* bottom of not in help mode */
  1450.         break;
  1451.     case WM_SETCURSOR:
  1452.         /* In help mode it is necessary to reset the cursor in response */
  1453.         /* to every WM_SETCURSOR message.Otherwise, by default, Windows */
  1454.         /* will reset the cursor to that of the window class. */
  1455.         if (uf.fHelp)
  1456.         {
  1457.             SetCursor(hHelpCursor);
  1458.             break;
  1459.         }
  1460.         return DefWindowProc(hWnd, wMessage, wParam, lParam);
  1461.     case WM_INITMENU:
  1462.         if (uf.fHelp)
  1463.            {
  1464.            SetCursor(hHelpCursor);
  1465.            }
  1466.         return TRUE;
  1467.     case WM_ENTERIDLE:
  1468.         if ((LOWORD(wParam) == MSGF_MENU) && (GetKeyState(VK_F1) & 0x8000))
  1469.            {
  1470.            uf.fHelp = TRUE;
  1471.            PostMessage(hWnd, WM_KEYDOWN, VK_RETURN, 0L);
  1472.            }
  1473.         break;
  1474.     case WM_CLOSE:
  1475.         DestroyWindow(hWnd);
  1476.         break;
  1477.     case WM_DESTROY:
  1478.         if ( uf.fCanDragDrop )
  1479.             DragAcceptFiles( hWnd, FALSE );
  1480.         DeleteObject(hBrush);
  1481.         WinHelp(hWnd, szHelpFileName, HELP_QUIT, 0L);
  1482.         PostQuitMessage(0);
  1483.         break;
  1484.     case WM_DROPFILES:
  1485.         {
  1486.         WORD    cFiles;
  1487.         /* Get the number of files that have been dropped */
  1488.         cFiles = (WORD)DragQueryFile( (HDROP)wParam, (UINT)-1, lpumb->szBuffer, (UINT)256);
  1489.         /* Only handle one dropped file until MDI-ness happens */
  1490.         if (cFiles == 1)
  1491.            {
  1492.            RECT    rClient;
  1493.            DragQueryFile( (HDROP)wParam, 0, lpumb->szFileName, PATH_MAX);
  1494.            GetArchiveDir(lpumb->szDirName); /* get archive dir name */
  1495.            if (uf.fUnzipToZipDir || /* unzipping to same directory as archive */
  1496.                szUnzipToDirName[0] == '') /* or no default */
  1497.               {
  1498.               /* strip off filename to make directory name    */
  1499.               lstrcpy(szUnzipToDirName, lpumb->szDirName);
  1500.               }
  1501.            lstrcpy(lpumb->szBuffer, lpumb->szDirName); /* get scratch copy */
  1502.            DlgDirList (hWnd, lpumb->szBuffer, 0, 0, 0); /* change dir */
  1503.            UpdateListBox(); /* fill in list box */
  1504. #ifndef WIN32
  1505.            SendMessage(hWndList, LB_SETSEL, 1, 0L);
  1506. #else
  1507.            ListViewSetSel(0, TRUE);
  1508. #endif           
  1509.            UpdateButtons(); /* update state of buttons */
  1510.            WinAssert(hWndList);
  1511.            GetClientRect( hWndList, &rClient );
  1512.            OffsetRect( &rClient, 0, dyChar );
  1513.            rClient.top = rClient.bottom;
  1514.            rClient.bottom = rClient.top + (2*dyChar);
  1515.            InvalidateRect( hWnd, &rClient, TRUE);
  1516.            SetCaption(hWnd);
  1517.            }
  1518.         DragFinish( (HDROP)wParam );
  1519.         }
  1520.         break;
  1521. #ifndef WIN32
  1522.     case WM_PAINT:
  1523.            {
  1524.            PAINTSTRUCT ps;
  1525.            RECT    rClient;
  1526.            DWORD   dwBackColor;
  1527.            char szCompFactor[10];
  1528.            char sgn;
  1529.            char CompFactorStr[] = "%c%d%%";
  1530.            char CompFactor100[] = "100%%";
  1531.            hDC = BeginPaint( hWnd, &ps );
  1532.            if ( hDC )
  1533.               {
  1534.               WinAssert(hWndList);
  1535.               UpdateWindow( hWndList );
  1536.               hOldFont = SelectObject ( hDC, hFixedFont);
  1537.               WinAssert(hWnd);
  1538.               GetClientRect( hWnd, &rClient );
  1539.               dwBackColor = SetBkColor(hDC,GetSysColor(COLOR_SCROLLBAR));
  1540.               /* Move "header" down two lines for button room at top */
  1541.               rClient.top = 2 * dyChar;
  1542.               rClient.left += dxChar/2;
  1543.               /* "Draw the header */
  1544.               DrawText( hDC, (LPSTR)Headers[uf.fFormatLong], -1,
  1545.                   &rClient, DT_NOPREFIX | DT_TOP);
  1546.               if (lpumb->szFileName[0])   /* if file selected */
  1547.                  {
  1548.                  WinAssert(hWndList);
  1549.                  GetClientRect( hWndList, &rClient );
  1550.                  /* Drop rectangle down 1 vertical char + 2 */
  1551.                  OffsetRect( &rClient, 0, dyChar+2);
  1552.                  rClient.left += dxChar/2;
  1553.                  /* Move totals "trailer" down two lines for button room */
  1554.                  rClient.top = rClient.bottom + (2 * dyChar) +
  1555.                   (2 * GetSystemMetrics(SM_CYDLGFRAME));
  1556.                  rClient.bottom = rClient.top + dyChar;
  1557.                  DrawText( hDC, (LPSTR)szTrailers[uf.fFormatLong], -1,
  1558.                    &rClient, DT_NOPREFIX | DT_TOP);
  1559.                  /* Display totals line at bottom of listbox */
  1560.                  rClient.top += dyChar;
  1561.                  rClient.bottom += dyChar;
  1562.                  if (lpUserFunctions->TotalSizeComp > lpUserFunctions->TotalSize)
  1563.                     sgn = '-';
  1564.                  else
  1565.                     sgn = ' ';
  1566.                  if (lpUserFunctions->CompFactor == 100)
  1567.                      sprintf(szCompFactor, CompFactor100);
  1568.                  else
  1569.                      sprintf(szCompFactor, CompFactorStr, sgn,
  1570.                         lpUserFunctions->CompFactor);
  1571.                  if (uf.fFormatLong)
  1572.                      wsprintf(szTotalsLine, LongFileTrailer,
  1573.                         lpUserFunctions->TotalSize,
  1574.                         lpUserFunctions->TotalSizeComp,
  1575.                         szCompFactor,
  1576.                         lpUserFunctions->NumMembers,
  1577.                         lpUserFunctions->NumMembers == 1 ? "":"s");
  1578.                  else
  1579.                      wsprintf(szTotalsLine, ShortFileTrailer,
  1580.                         lpUserFunctions->TotalSize,
  1581.                         lpUserFunctions->NumMembers,
  1582.                         lpUserFunctions->NumMembers == 1 ? "" : "s");
  1583.                  DrawText( hDC, szTotalsLine, -1,
  1584.                     &rClient, DT_NOPREFIX | DT_TOP);
  1585.                  }
  1586.               SetBkColor(hDC, dwBackColor);
  1587.               (void)SelectObject ( hDC, hOldFont);
  1588.             }
  1589.            EndPaint(hWnd, &ps);
  1590.            break;
  1591.            }
  1592. #endif
  1593.    default:
  1594.       if (wMessage == uCommDlgHelpMsg)   /* common dialog help message ID */
  1595.          {
  1596.          WinHelp(hWnd, szHelpFileName, HELP_CONTEXT, dwCommDlgHelpId );
  1597.          return 0;
  1598.          }
  1599.       return DefWindowProc(hWnd, wMessage, wParam, lParam);
  1600.     }
  1601.     return 0;
  1602. }
  1603. void GetHelpContext(WPARAM wParam)
  1604. {
  1605. switch (LOWORD(wParam))
  1606.    {
  1607.    case IDM_ESCAPE:
  1608.       if (uf.fHelp)
  1609.          {
  1610.          uf.fHelp = FALSE;
  1611. #ifndef WIN32
  1612.          SetCursor((HCURSOR)GetClassWord(hWndMain,GCW_HCURSOR));
  1613. #else
  1614.          SetCursor((HCURSOR)GetClassLong(hWndMain,GCL_HCURSOR));
  1615. #endif
  1616.          dwHelpContextId = (DWORD) 0L;
  1617.          }
  1618.       break;
  1619.    case IDM_OPEN:
  1620.       dwHelpContextId = (DWORD) HELPID_OPEN;
  1621.       break;
  1622.    case IDM_EXIT:
  1623.       dwHelpContextId = (DWORD) HELPID_EXIT_CMD;
  1624.       break;
  1625.    case IDM_HELP:
  1626.       dwHelpContextId = (DWORD) HELPID_HELP;
  1627.       break;
  1628.    case IDM_HELP_HELP:
  1629.       dwHelpContextId = (DWORD) HELPID_HELP_HELP;
  1630.       break;
  1631.    case IDM_ABOUT:
  1632.       dwHelpContextId = (DWORD) HELPID_ABOUT;
  1633.       break;
  1634.    case IDM_RECR_DIR_STRUCT:
  1635.       dwHelpContextId = (DWORD) HELPID_RECR_DIR_STRUCT;
  1636.       break;
  1637.    case IDM_SHOW_BUBBLE_HELP:
  1638.       dwHelpContextId = (DWORD) HELPID_SHOW_BUBBLE_HELP;
  1639.       break;
  1640.    case IDM_UNZIP_TO_ZIP_DIR:
  1641.       dwHelpContextId = (DWORD) HELPID_UNZIP_TO_ZIP_DIR;
  1642.       break;
  1643.    case IDM_LISTBOX:
  1644.       dwHelpContextId = (DWORD) HELPID_LISTBOX;
  1645.       break;
  1646.    case IDM_EXTRACT:
  1647.       dwHelpContextId = (DWORD) HELPID_EXTRACT;
  1648.       break;
  1649.    case IDM_DISPLAY:
  1650.       dwHelpContextId = (DWORD) HELPID_DISPLAY;
  1651.       break;
  1652.    case IDM_TEST:
  1653.       dwHelpContextId = (DWORD) HELPID_TEST;
  1654.       break;
  1655.    case IDM_DESELECT_ALL:
  1656.       dwHelpContextId = (DWORD) HELPID_DESELECT_ALL;
  1657.       break;
  1658.    case IDM_SELECT_ALL:
  1659.       dwHelpContextId = (DWORD) HELPID_SELECT_ALL;
  1660.       break;
  1661.    case IDM_SELECT_BY_PATTERN:
  1662.       dwHelpContextId = (DWORD) HELPID_SELECT_BY_PATTERN;
  1663.       break;
  1664.    case IDM_CLEAR_STATUS:
  1665.       dwHelpContextId = (DWORD) HELPID_CLEAR_STATUS;
  1666.       break;
  1667.    case IDM_SOUND_OPTIONS:
  1668.       dwHelpContextId = (DWORD) HELPID_SOUND_OPTIONS;
  1669.       break;
  1670.    case IDM_MAX_STATUS:
  1671.       dwHelpContextId = (DWORD) HELPID_MAX_STATUS;
  1672.       break;
  1673.    case IDM_SAVE_UNZIP_FROM_DIR:
  1674.       dwHelpContextId = (DWORD) HELPID_SAVE_UNZIP_FROM_DIR;
  1675.       break;
  1676.    case IDM_SAVE_UNZIP_TO_DIR:
  1677.       dwHelpContextId = (DWORD) HELPID_SAVE_UNZIP_TO_DIR;
  1678.       break;
  1679.    case IDM_CHDIR:
  1680.       dwHelpContextId = (DWORD) HELPID_CHDIR;
  1681.       break;
  1682.    case IDM_COPY_ARCHIVE:
  1683.       dwHelpContextId = (DWORD) HELPID_COPY_ARCHIVE;
  1684.       break;
  1685.    case IDM_MOVE_ARCHIVE:
  1686.       dwHelpContextId = (DWORD) HELPID_MOVE_ARCHIVE;
  1687.       break;
  1688.    case IDM_DELETE_ARCHIVE:
  1689.       dwHelpContextId = (DWORD) HELPID_DELETE_ARCHIVE;
  1690.       break;
  1691.    case IDM_RENAME_ARCHIVE:
  1692.       dwHelpContextId = (DWORD) HELPID_RENAME_ARCHIVE;
  1693.       break;
  1694.    case IDM_MAKE_DIR:
  1695.       dwHelpContextId = (DWORD) HELPID_MAKEDIR_HELP;
  1696.       break;
  1697.    case IDM_MAKEDIR_HELP:
  1698.       dwHelpContextId = (DWORD) HELPID_MAKEDIR_HELP;
  1699.       break;
  1700.    case IDM_EDIT_OPEN_FILE:
  1701.       dwHelpContextId = (DWORD) HELPID_EDIT_OPEN_FILE;
  1702.       break;
  1703.    case IDM_EDIT_SAVE_AS:
  1704.       dwHelpContextId = (DWORD) HELPID_EDIT_SAVE_AS;
  1705.       break;
  1706.    default:
  1707.       dwHelpContextId = (DWORD) HELPID_BUTTONS;
  1708.    }
  1709. }