home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 14 / CDACTUAL.iso / cdactual / demobin / share / program / c / WUNZ13SR.ZIP / WNDPROC.C < prev   
Encoding:
C/C++ Source or Header  |  1992-07-02  |  35.0 KB  |  868 lines

  1. #include <sys\types.h>
  2. #include <sys\stat.h>
  3. #include <time.h>                
  4. #include <string.h>             
  5. #include "wizunzip.h"
  6. #include "helpids.h"
  7. #include <shellapi.h>
  8.  
  9.  
  10. /* Windows Info-ZIP Unzip Window Procedure, wndproc.c.
  11.  * Author: Robert A. Heath, 157 Chartwell Rd., Columbia, SC 29210
  12.  * I, Robert Heath, place this source code module in the public domain.
  13.  */
  14.  
  15. #define MAKE_TABSTOP_TABLE_ENTRY(WNDHANDLE, ID) \
  16.     { \
  17.         TabStopTable[ID - TABSTOP_ID_BASE].lpfnOldFunc = \
  18.             (FARPROC)GetWindowLong(WNDHANDLE, GWL_WNDPROC); \
  19.         SetWindowLong(WNDHANDLE, GWL_WNDPROC, (LONG)lpfnKbd); \
  20.         TabStopTable[ID - TABSTOP_ID_BASE].hWnd = WNDHANDLE; \
  21.     }
  22.  
  23.  
  24. static char szFormatKeyword[2][6] = { "short", "long" };
  25.  
  26. /* Trailers are the lines just above the totals */
  27. static char * __based(__segname("STRINGS_TEXT")) szTrailers[2] = {
  28. " ------                    -------",
  29. " ------          ------  ---                              -------"
  30. } ;
  31.  
  32. /* size of char in SYSTEM font in pixels */
  33. short dxChar, dyChar;
  34.  
  35. /* button control table -- one entry for 
  36.  * each of 4 entries. Indexed by the window ID relative to
  37.  * the first tabstop (TABSTOP_ID_BASE).         
  38.  */
  39. TabStopEntry TabStopTable[TABSTOP_TABLE_ENTRIES]; 
  40.  
  41.  
  42. static LPSTR
  43. lstrrchr(LPSTR lpszSrc, char chFind)
  44. {
  45.     LPSTR   lpszFound = (LPSTR)0;
  46.     LPSTR   lpszT;
  47.     
  48.     if ( lpszSrc )
  49.     {
  50.         for (lpszT = lpszSrc; *lpszT; ++lpszT)
  51.         {
  52.             if ((*lpszT) == chFind)
  53.                 lpszFound = lpszT;
  54.         }
  55.     }
  56.     
  57.     return lpszFound;
  58. }
  59.  
  60. /****************************************************************************
  61.  
  62.     FUNCTION: SetCaption(HWND hWnd,  PSTR szOemFileName)
  63.                 szFileName is OEM char set.
  64.  
  65.     PURPOSE: Set new caption for main window
  66.  
  67. ****************************************************************************/
  68. void 
  69. SetCaption(HWND hWnd)
  70. {
  71.     WORD wMenuState;
  72.     char szSimpleFileName[15];  /* just the 8.3 part in ANSI char set */
  73.     LPSTR lpszFileNameT;        /* pointer to simple filename               */
  74.     BOOL    fIconic = IsIconic(hWnd);   /* is window iconic ?   */
  75.  
  76.     /* point to simple filename in OEM char set                 */
  77.     if ((lpszFileNameT = lstrrchr(lpumb->szFileName, '\\')) ||
  78.         (lpszFileNameT = lstrrchr(lpumb->szFileName, ':')))
  79.         lpszFileNameT++;
  80.     else
  81.         lpszFileNameT = lpumb->szFileName;
  82.  
  83.     OemToAnsi(lpszFileNameT, szSimpleFileName);
  84.     (void)wsprintf(lpumb->szBuffer, "%s - %s %s %s", 
  85.                     (LPSTR)szAppName, 
  86.                     (LPSTR)(szSimpleFileName[0] ? 
  87.                         szSimpleFileName : "(No .ZIP file)"),
  88.                     (LPSTR)(!fIconic && lpumb->szOrigDirName[0] ? " - " : ""),
  89.                     (LPSTR)(!fIconic ? lpumb->szOrigDirName : ""));
  90.     SetWindowText(hWnd, lpumb->szBuffer);
  91.     wMenuState = (WORD)(szSimpleFileName[0] ? MF_ENABLED : MF_GRAYED) ;
  92.     EnableMenuItem(hMenu, IDM_SELECT_ALL, wMenuState|MF_BYCOMMAND); 
  93.     EnableMenuItem(hMenu, IDM_DESELECT_ALL, wMenuState|MF_BYCOMMAND); 
  94. }
  95.  
  96. /****************************************************************************
  97.  
  98.     FUNCTION: WizunzipWndProc(HWND, unsigned, WORD, LONG)
  99.  
  100.     PURPOSE:  Processes messages
  101.  
  102.     MESSAGES:
  103.  
  104.     WM_DESTROY      - destroy window
  105.     WM_SIZE         - window size has changed
  106.     WM_QUERYENDSESSION - willing to end session?
  107.     WM_ENDSESSION   - end Windows session
  108.     WM_CLOSE        - close the window
  109.     WM_SIZE         - window resized
  110.     WM_PAINT        - windows needs to be painted
  111.     WM_DROPFILES    - open a dropped file
  112.     COMMENTS:
  113.  
  114.     WM_COMMAND processing:
  115.  
  116.         IDM_OPEN -  open a new file.
  117.  
  118.  
  119.         IDM_EXIT - query to save current file if there is one and it
  120.                has been changed, then exit.
  121.  
  122.         IDM_ABOUT - display "About" box.
  123.  
  124. ****************************************************************************/
  125.  
  126. long FAR PASCAL WizunzipWndProc(HWND hWnd, WORD wMessage, WORD wParam, LONG lParam)
  127. {
  128.     FARPROC lpfnAbout, lpfnSelectDir;
  129.  
  130.     HDC hDC;                /* device context       */
  131.     TEXTMETRIC    tm;           /* text metric structure    */
  132.     POINT point;
  133.     FARPROC lpfnKbd;
  134.     short   i;
  135.  
  136.  
  137.     switch (wMessage)
  138.     {
  139.     case WM_CREATE: /* create  window       */
  140.         hInst = ((LPCREATESTRUCT)lParam)->hInstance;
  141.         lpfnKbd = MakeProcInstance((FARPROC)KbdProc, hInst);
  142.         hAccTable = LoadAccelerators(hInst, "WizunzipAccels");
  143.         hBrush = CreateSolidBrush(GetSysColor(BG_SYS_COLOR)); /* background */
  144.  
  145.         hMenu = GetMenu(hWnd);
  146.         /* Check Menu items to reflect WIN.INI settings */
  147.         CheckMenuItem(hMenu, IDM_RECR_DIR_STRUCT, MF_BYCOMMAND | 
  148.                             (uf.fRecreateDirs ? MF_CHECKED : MF_UNCHECKED));
  149.         CheckMenuItem(hMenu, (IDM_SHORT+uf.fFormatLong), MF_BYCOMMAND | MF_CHECKED);
  150.         CheckMenuItem(hMenu, IDM_OVERWRITE, MF_BYCOMMAND |
  151.                             (uf.fOverwrite ? MF_CHECKED : MF_UNCHECKED));
  152.         CheckMenuItem(hMenu, IDM_TRANSLATE, MF_BYCOMMAND |
  153.                             (uf.fTranslate ? MF_CHECKED : MF_UNCHECKED));
  154.         CheckMenuItem(hMenu, wLBSelection, MF_BYCOMMAND | MF_CHECKED);
  155.         CheckMenuItem(hMenu, IDM_UNZIP_TO_ZIP_DIR, MF_BYCOMMAND |
  156.                             (uf.fUnzipToZipDir ? MF_CHECKED : MF_UNCHECKED));
  157.         CheckMenuItem(hMenu, IDM_BEEP_ON_FINISH, MF_BYCOMMAND |
  158.                             (uf.fBeepOnFinish ? MF_CHECKED: MF_UNCHECKED));
  159.         EnableMenuItem(hMenu, IDM_CHDIR, MF_BYCOMMAND |
  160.                             (uf.fUnzipToZipDir ? MF_GRAYED : MF_ENABLED));
  161.  
  162.         /* Get an hourglass cursor to use during file transfers */
  163.         hHourGlass = LoadCursor(0, IDC_WAIT);
  164.  
  165.         hFixedFont = GetStockObject(SYSTEM_FIXED_FONT);
  166.         hDC = GetDC(hWnd);  /* get device context */
  167.         hOldFont = SelectObject(hDC, hFixedFont);
  168.         GetTextMetrics(hDC, &tm);
  169.         ReleaseDC(hWnd, hDC);
  170.         dxChar = tm.tmAveCharWidth;
  171.         dyChar = tm.tmHeight + tm.tmExternalLeading; 
  172.  
  173.         hWndList = CreateWindow("listbox", NULL,
  174.                         WS_CHILD | WS_VISIBLE | LBS_NOTIFY | WS_VSCROLL | WS_BORDER| LBS_EXTENDEDSEL,
  175.                         0, 0,
  176.                         0, 0,
  177.                         hWnd, IDM_LISTBOX,
  178.                         GetWindowWord (hWnd, GWW_HINSTANCE), NULL);
  179.  
  180.         MAKE_TABSTOP_TABLE_ENTRY(hWndList, IDM_LISTBOX);
  181.         SendMessage(hWndList, WM_SETFONT, hFixedFont, FALSE);
  182.         ShowWindow(hWndList, SW_SHOW);
  183.         UpdateWindow(hWndList);         /* show it now! */
  184.  
  185.         hWndStatus = CreateWindow(szStatusClass, "Status",
  186.                             WS_CHILD|WS_SYSMENU|WS_VISIBLE|WS_BORDER|WS_HSCROLL|WS_VSCROLL|WS_MAXIMIZEBOX|WS_CAPTION,
  187.                             0, 0,
  188.                             0, 0,
  189.                             hWnd, IDM_STATUS,
  190.                             GetWindowWord (hWnd, GWW_HINSTANCE), NULL);
  191.         SendMessage(hWndStatus, WM_SETFONT, hFixedFont, TRUE);
  192.         MAKE_TABSTOP_TABLE_ENTRY(hWndStatus, IDM_STATUS);
  193.         if (uf.fStatusHidden)
  194.         {
  195.             ShowWindow( hWndStatus, SW_HIDE );
  196.             ModifyMenu(hMenu,IDM_SHOWHIDE_STATUS,
  197.                         MF_BYCOMMAND|MF_STRING|MF_ENABLED,
  198.                         IDM_SHOWHIDE_STATUS,
  199.                         (uf.fStatusHidden) ? "S&how Status Window" : "&Hide Status Window");
  200.         }
  201.  
  202.         hExtract = CreateWindow("button", "E&xtract",  
  203.                             WS_CHILD | BS_PUSHBUTTON,
  204.                             0, 0,
  205.                             0, 0,
  206.                             hWnd, IDM_EXTRACT,
  207.                             hInst,
  208.                             NULL);
  209.         ShowWindow(hExtract, SW_SHOW);
  210.         MAKE_TABSTOP_TABLE_ENTRY(hExtract, IDM_EXTRACT);
  211.  
  212.  
  213.         hDisplay= CreateWindow("button", "&Display",                    
  214.                             WS_CHILD | BS_PUSHBUTTON,
  215.                             0, 0,
  216.                             0, 0,
  217.                             hWnd, IDM_DISPLAY,
  218.                             hInst,
  219.                             NULL);
  220.         ShowWindow(hDisplay, SW_SHOW);
  221.         MAKE_TABSTOP_TABLE_ENTRY(hDisplay, IDM_DISPLAY);
  222.  
  223.         hTest= CreateWindow("button", "&Test",          
  224.                             WS_CHILD | BS_PUSHBUTTON,
  225.                             0, 0,
  226.                             0, 0,
  227.                             hWnd, IDM_TEST,
  228.                             hInst,
  229.                             NULL);
  230.         ShowWindow(hTest, SW_SHOW);
  231.         MAKE_TABSTOP_TABLE_ENTRY(hTest, IDM_TEST);
  232.     
  233.  
  234.         hShowComment= CreateWindow("button", "&Show Comment", 
  235.                                     WS_CHILD | BS_PUSHBUTTON,
  236.                                     0, 0,
  237.                                     0, 0,
  238.                                     hWnd, IDM_SHOW_COMMENT,
  239.                                     hInst,
  240.                                     NULL);
  241.  
  242.         ShowWindow(hShowComment, SW_SHOW);
  243.         MAKE_TABSTOP_TABLE_ENTRY(hShowComment, IDM_SHOW_COMMENT);
  244.  
  245.         /* if file spec'd on entry */
  246.         if (lpumb->szFileName[0])
  247.         {
  248.             LPSTR lpch;
  249.             extern int ofretval; /* return value from initial open if filename given
  250.                                 during WinMain()                 */
  251.  
  252.  
  253.             OemToAnsi(lpumb->szFileName, lpumb->szBuffer);
  254.             /* If valid filename change dir to where it lives */
  255.             if (ofretval >= 0)
  256.             {
  257.                 /* take only path portion */
  258.                 if ((lpch = lstrrchr(lpumb->szBuffer, '\\')) ||
  259.                      (lpch = lstrrchr(lpumb->szBuffer, ':')))
  260.                     *lpch = '\0';
  261.  
  262.                 lstrcpy(lpumb->szOrigDirName, lpumb->szBuffer);
  263.                 DlgDirList(hWnd, lpumb->szBuffer, 0, 0, 0);
  264.             }
  265.             else /* bad file name */
  266.             {
  267.                 if ((lpch = lstrrchr(lpumb->szBuffer, '\\')) ||
  268.                      (lpch = lstrrchr(lpumb->szBuffer, ':')))
  269.                     lpch++; /* point to filename */
  270.                 else
  271.                     lpch = lpumb->szBuffer;
  272.     
  273.                 wsprintf (lpumb->szBuffer, "Cannot open %s", lpch);
  274.                 MessageBox (hWnd, lpumb->szBuffer, szAppName, MB_ICONINFORMATION | MB_OK);
  275.                 lpumb->szFileName[0] = '\0'; /* pretend filename doesn't exist  */
  276.             }
  277.         }
  278.  
  279.         SetCaption(hWnd);
  280.         UpdateListBox(hWnd);
  281.         SendMessage(hWndList, LB_SETSEL, 1, 0L);
  282.         UpdateButtons(hWnd);
  283.         SizeWindow(hWnd, TRUE);
  284.         if ( uf.fCanDragDrop )
  285.             DragAcceptFiles( hWnd, TRUE );
  286.         break;
  287.     
  288.     case WM_SETFOCUS:
  289.         SetFocus( (uf.fStatusMaximized) ? hWndStatus : hWndList);
  290.         break;
  291.  
  292.     case WM_ACTIVATE:
  293.         SetCaption(hWnd);
  294.         return DefWindowProc(hWnd, wMessage, wParam, lParam);
  295.  
  296.     case WM_SIZE:
  297.         SizeWindow(hWnd, FALSE);
  298.         break;
  299.  
  300.     case WM_CTLCOLOR: /* color background of buttons and statics */
  301.         if (HIWORD(lParam) == CTLCOLOR_STATIC)
  302.         {
  303.             SetBkMode(wParam, TRANSPARENT);
  304.             SetBkColor(wParam, GetSysColor(BG_SYS_COLOR)); /* custom b.g. color */
  305.             SetTextColor(wParam, GetSysColor(COLOR_WINDOWTEXT));
  306.             UnrealizeObject(hBrush);
  307.             point.x = point.y = 0;
  308.             ClientToScreen(hWnd, &point);
  309.             SetBrushOrg(wParam, point.x, point.y);
  310.             return ((DWORD)hBrush);
  311.         }
  312.         /* fall thru to WM_SYSCOMMAND */
  313.         
  314.     case WM_SYSCOMMAND:
  315.         return DefWindowProc( hWnd, wMessage, wParam, lParam );
  316.  
  317.     case WM_COMMAND:
  318.         /* Was F1 just pressed in a menu, or are we in help mode */
  319.         /* (Shift-F1)? */
  320.  
  321.         if (uf.fHelp)
  322.         {
  323.             DWORD dwHelpContextId =
  324.                 (wParam == IDM_OPEN)            ? (DWORD) HELPID_OPEN :
  325.                 (wParam == IDM_EXIT)            ? (DWORD) HELPID_EXIT_CMD :
  326.                 (wParam == IDM_CHDIR)           ? (DWORD) HELPID_CHDIR :
  327.                 (wParam == IDM_SHORT)           ? (DWORD) HELPID_SHORT :
  328.                 (wParam == IDM_LONG)            ? (DWORD) HELPID_LONG :
  329.                 (wParam == IDM_HELP)            ? (DWORD) HELPID_HELP :
  330.                 (wParam == IDM_HELP_HELP)       ? (DWORD) HELPID_HELP_HELP :
  331.                 (wParam == IDM_ABOUT)           ? (DWORD) HELPID_ABOUT :
  332.                 (wParam == IDM_RECR_DIR_STRUCT) ? (DWORD) HELPID_RECR_DIR_STRUCT :
  333.                 (wParam == IDM_OVERWRITE)       ? (DWORD) HELPID_OVERWRITE :
  334.                 (wParam == IDM_TRANSLATE)       ? (DWORD) HELPID_TRANSLATE :
  335.                 (wParam == IDM_UNZIP_TO_ZIP_DIR)? (DWORD) HELPID_UNZIP_TO_ZIP_DIR :
  336.                 (wParam == IDM_LISTBOX)         ? (DWORD) HELPID_LISTBOX :
  337.                 (wParam == IDM_EXTRACT)         ? (DWORD) HELPID_EXTRACT :
  338.                 (wParam == IDM_DISPLAY)         ? (DWORD) HELPID_DISPLAY :
  339.                 (wParam == IDM_TEST)            ? (DWORD) HELPID_TEST :
  340.                 (wParam == IDM_SHOW_COMMENT)    ? (DWORD) HELPID_SHOW_COMMENT :
  341.                 (wParam == IDM_LB_EXTRACT)      ? (DWORD) HELPID_LB_EXTRACT :
  342.                 (wParam == IDM_LB_DISPLAY)      ? (DWORD) HELPID_LB_DISPLAY :
  343.                 (wParam == IDM_LB_TEST)         ? (DWORD) HELPID_LB_TEST :
  344.                 (wParam == IDM_DESELECT_ALL)    ? (DWORD) HELPID_DESELECT_ALL :
  345.                 (wParam == IDM_SELECT_ALL)      ? (DWORD) HELPID_SELECT_ALL :
  346.                 (wParam == IDM_CLEAR_STATUS)    ? (DWORD) HELPID_CLEAR_STATUS :
  347.                 (wParam == IDM_BEEP_ON_FINISH)  ? (DWORD) HELPID_BEEP_ON_FINISH :
  348.                 (wParam == IDM_SHOWHIDE_STATUS) ? (DWORD) (uf.fStatusHidden ? HELPID_SHOW_STATUS : HELPID_HIDE_STATUS) :
  349.                                                   (DWORD) 0L;
  350.  
  351.             if (!dwHelpContextId)
  352.             {
  353.                 MessageBox( hWnd, "Help not available for Help Menu item",
  354.                             "Help Example", MB_OK);
  355.                 return DefWindowProc(hWnd, wMessage, wParam, lParam);
  356.             }
  357.  
  358.             uf.fHelp = FALSE;
  359.             WinHelp(hWnd,szHelpFileName,HELP_CONTEXT,dwHelpContextId);
  360.         }
  361.         else /* not in help mode */
  362.         {
  363.             switch (wParam)
  364.             {
  365.             case IDM_OPEN:
  366.                 /* If unzipping separately and previous file exists,
  367.                  * go to directory where archive lives.
  368.                  */
  369.                 if ( uf.fCanDragDrop )
  370.                     DragAcceptFiles( hWnd, FALSE );
  371.                 lpumb->szBuffer[0] = '\0';
  372.                 for (i=0; i<sizeof(OPENFILENAME); ++i)
  373.                 {
  374.                     ((char __far *)&lpumb->ofn)[i] = 0;
  375.                 }
  376.  
  377.                 lpumb->ofn.lStructSize = sizeof(OPENFILENAME);
  378.                 lpumb->ofn.hwndOwner = hWnd;
  379.                 lpumb->ofn.lpstrFilter = "Zip Files (*.zip)\0*.zip\0\0";
  380.                 lpumb->ofn.nFilterIndex = 1;
  381.                 lpumb->ofn.lpstrFile = lpumb->szFileName;
  382.                 lpumb->ofn.nMaxFile = 128;
  383.                 lpumb->ofn.lpstrFileTitle = lpumb->szBuffer;
  384.                 lpumb->ofn.nMaxFileTitle = 256;
  385.                 lpumb->ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
  386.                 if (GetOpenFileName(&lpumb->ofn))   /* if successful file open  */
  387.                 {
  388.                     RECT    rClient;
  389.  
  390.                     if (uf.fUnzipToZipDir)
  391.                     {
  392.                         LPSTR lpchLast;
  393.  
  394.                         /* strip off filename to make directory name    */
  395.                         OemToAnsi(lpumb->szFileName, lpumb->szOrigDirName);
  396.                         if ((lpchLast = lstrrchr(lpumb->szOrigDirName, '\\')) ||
  397.                             (lpchLast = lstrrchr(lpumb->szOrigDirName, ':')))
  398.                             *lpchLast = '\0';
  399.                     }
  400.  
  401.                     UpdateListBox(hWnd); /* fill in list box */
  402.                     SendMessage(hWndList, LB_SETSEL, 1, 0L);
  403.                     UpdateButtons(hWnd); /* update state of buttons */
  404.  
  405.                     GetClientRect( hWndList, &rClient );
  406.                     OffsetRect( &rClient, 0, dyChar );
  407.                     rClient.top = rClient.bottom;
  408.                     rClient.bottom = rClient.top + (2*dyChar);
  409.                     InvalidateRect( hWnd, &rClient, TRUE);
  410.                     UpdateWindow( hWnd );
  411.                 }
  412.  
  413.                 if (lpumb->szOrigDirName[0]) /* if directory name exists, go there  */
  414.                 {
  415.                     lstrcpy(lpumb->szBuffer, lpumb->szOrigDirName); /* get scratch copy */
  416.                     DlgDirList (hWnd, lpumb->szBuffer, 0, 0, 0); /* change dir */
  417.                 }
  418.                 SetCaption(hWnd);
  419.                 if ( uf.fCanDragDrop )
  420.                     DragAcceptFiles( hWnd, TRUE );
  421.                 break;
  422.             case IDM_CHDIR:
  423.                 if ( uf.fCanDragDrop )
  424.                     DragAcceptFiles( hWnd, FALSE );
  425.                 lpumb->szBuffer[0] = '\0';
  426.                 for (i=0; i<sizeof(OPENFILENAME); ++i)
  427.                 {
  428.                     ((char __far *)&lpumb->ofn)[i] = 0;
  429.                 }
  430.  
  431.                 lpumb->ofn.lStructSize = sizeof(OPENFILENAME);
  432.                 lpumb->ofn.hwndOwner = hWnd;
  433.                 lpumb->ofn.lpstrFilter = "All Files (*.*)\0*.*\0\0";
  434.                 lpumb->ofn.nFilterIndex = 1;
  435.                 lpumb->ofn.lpstrFile = lpumb->szDirName;
  436.                 lpumb->ofn.nMaxFile = 128;
  437.                 lpumb->ofn.lpstrFileTitle = lpumb->szBuffer;
  438.                 lpumb->ofn.nMaxFileTitle = 256;
  439.                 lpumb->ofn.lpstrTitle = (LPSTR)"Unzip To";
  440.                 lpumb->ofn.Flags = OFN_SHOWHELP | OFN_PATHMUSTEXIST | OFN_ENABLEHOOK | OFN_HIDEREADONLY;
  441.                 lpumb->ofn.lpfnHook = lpfnSelectDir = MakeProcInstance((FARPROC)SelectDirProc, hInst);
  442.                 if (GetSaveFileName(&lpumb->ofn))
  443.                 {
  444.                     OemToAnsi(lpumb->szDirName, lpumb->szOrigDirName);
  445.                     SetCaption(hWnd);
  446.                 }
  447.                 else
  448.                 {
  449.  
  450.                 }
  451.                 FreeProcInstance(lpfnSelectDir);
  452.                 lpumb->szBuffer[0] = '\0';
  453.                 if ( uf.fCanDragDrop )
  454.                     DragAcceptFiles( hWnd, TRUE );
  455.                 break;
  456.  
  457.             case IDM_EXIT:
  458.                 SendMessage(hWnd, WM_CLOSE, 0, 0L);
  459.                 break;
  460.  
  461.             case IDM_HELP:  /* Display Help */
  462.                 WinHelp(hWnd,szHelpFileName,HELP_INDEX,0L);
  463.                 break;
  464.  
  465.             case IDM_HELP_HELP:
  466.                 WinHelp(hWnd,"WINHELP.HLP",HELP_INDEX,0L);
  467.                 break;
  468.  
  469.             case IDM_ABOUT:
  470.                 if ( uf.fCanDragDrop )
  471.                     DragAcceptFiles( hWnd, FALSE );
  472.                 lpfnAbout = MakeProcInstance(AboutProc, hInst);
  473.                 DialogBox(hInst, "About", hWnd, lpfnAbout);
  474.                 FreeProcInstance(lpfnAbout);
  475.                 if ( uf.fCanDragDrop )
  476.                     DragAcceptFiles( hWnd, TRUE );
  477.                 break;
  478.  
  479.             case IDM_LISTBOX:       /* command from listbox     */
  480.                 if (cZippedFiles)
  481.                 {
  482.                     switch (HIWORD(lParam))
  483.                     {
  484.                     case LBN_SELCHANGE:
  485.                         UpdateButtons(hWnd);
  486.                         break;
  487.                     case LBN_DBLCLK:
  488.                         UpdateButtons(hWnd);
  489.                         if ( uf.fCanDragDrop )
  490.                             DragAcceptFiles( hWnd, FALSE );
  491.                         Action(hWnd, wLBSelection - IDM_LB_EXTRACT);
  492.                         if ( uf.fCanDragDrop )
  493.                             DragAcceptFiles( hWnd, TRUE );
  494.                         break;
  495.                     }
  496.                 }
  497.                 break;
  498.             case IDM_LONG:
  499.             case IDM_SHORT:
  500.                 /* If format change, uncheck old, check new. */
  501.                 if ((wParam - IDM_SHORT) != uf.fFormatLong)
  502.                 {
  503.                     WORD wFormatTmp = wParam - IDM_SHORT;
  504.                     int __far *pnSelItems; /* pointer to list of selected items */
  505.                     HANDLE  hnd = 0;
  506.                     int cSelLBItems ; /* no. selected items in listbox */
  507.                     RECT    rClient;
  508.  
  509.                     cSelLBItems = CLBItemsGet(hWndList, &pnSelItems, &hnd);
  510.                     CheckMenuItem(hMenu, (IDM_SHORT+uf.fFormatLong), MF_BYCOMMAND|MF_UNCHECKED);
  511.                     CheckMenuItem(hMenu, (IDM_SHORT+wFormatTmp), MF_BYCOMMAND|MF_CHECKED);
  512.                     uf.fFormatLong = wFormatTmp;
  513.                     UpdateListBox(hWnd);
  514.  
  515.                     SizeWindow(hWnd, TRUE);
  516.                     WriteProfileString(szAppName, szFormatKey, 
  517.                                         (LPSTR)(szFormatKeyword[uf.fFormatLong]));
  518.  
  519.                     /* anything previously selected ? */
  520.                     if (cSelLBItems > 0)
  521.                     {
  522.                         ReselectLB(hWndList, cSelLBItems, pnSelItems);
  523.                         GlobalUnlock(hnd);
  524.                         GlobalFree(hnd);
  525.                     }
  526.  
  527.                     /* enable or disable buttons */
  528.                     UpdateButtons(hWnd);
  529.  
  530.                     /* make sure labels & Zip archive totals get updated */
  531.                     GetClientRect( hWnd, &rClient );
  532.                     rClient.top = 0;
  533.                     rClient.bottom = rClient.top + dyChar;
  534.                     InvalidateRect( hWnd, &rClient, TRUE);
  535.                     GetClientRect( hWndList, &rClient );
  536.                     OffsetRect( &rClient, 0, dyChar );
  537.                     rClient.top = rClient.bottom;
  538.                     rClient.bottom = rClient.top + (2*dyChar);
  539.                     InvalidateRect( hWnd, &rClient, TRUE);
  540.                     UpdateWindow( hWnd );
  541.                 }
  542.                 break;
  543.  
  544.             case IDM_OVERWRITE:
  545.                 /* Toggle value of overwrite flag. */
  546.                 uf.fOverwrite = !uf.fOverwrite;
  547.                 CheckMenuItem(hMenu,IDM_OVERWRITE,MF_BYCOMMAND|
  548.                                 (WORD)(uf.fOverwrite ? MF_CHECKED: MF_UNCHECKED));
  549.                 WriteProfileString(szAppName, szOverwriteKey, 
  550.                         (LPSTR)(uf.fOverwrite ? szYes : szNo ));
  551.                 break;
  552.  
  553.             case IDM_TRANSLATE:
  554.                 /* Toggle value of translate flag. */
  555.                 uf.fTranslate = !uf.fTranslate;
  556.                 CheckMenuItem(hMenu,IDM_TRANSLATE,MF_BYCOMMAND|
  557.                                 (WORD)(uf.fTranslate ? MF_CHECKED: MF_UNCHECKED));
  558.                 WriteProfileString(szAppName, szTranslateKey, 
  559.                         (LPSTR)(uf.fTranslate ? szYes : szNo ));
  560.                 break;
  561.             
  562.             case IDM_UNZIP_TO_ZIP_DIR:
  563.                 /* toggle value of Unzip to .ZIP  */
  564.                 uf.fUnzipToZipDir = !uf.fUnzipToZipDir;
  565.                 CheckMenuItem(hMenu,IDM_UNZIP_TO_ZIP_DIR,MF_BYCOMMAND|
  566.                                     (WORD)(uf.fUnzipToZipDir ? MF_CHECKED:MF_UNCHECKED));
  567.                 EnableMenuItem(hMenu,IDM_CHDIR,MF_BYCOMMAND|
  568.                                     (WORD)(uf.fUnzipToZipDir ? MF_GRAYED:MF_ENABLED));
  569.                 WriteProfileString(szAppName, szUnzipToZipDirKey, 
  570.                             (LPSTR)(uf.fUnzipToZipDir ? szYes : szNo ));
  571.  
  572.                 if (uf.fUnzipToZipDir && lpumb->szFileName[0])
  573.                 {
  574.                     LPSTR lpchLast;
  575.  
  576.                     /* strip off filename to make directory name    */
  577.                     OemToAnsi(lpumb->szFileName, lpumb->szOrigDirName);
  578.                     if ((lpchLast = lstrrchr(lpumb->szOrigDirName, '\\')) ||
  579.                         (lpchLast = lstrrchr(lpumb->szOrigDirName, ':')))
  580.                         *lpchLast = '\0';
  581.  
  582.                     if (lpumb->szOrigDirName[0]) /* if directory name exists, go there  */
  583.                     {
  584.                         lstrcpy(lpumb->szBuffer, lpumb->szOrigDirName); /* get scratch copy */
  585.                         DlgDirList (hWnd, lpumb->szBuffer, 0, 0, 0); /* change dir */
  586.                     }
  587.                     SetCaption(hWnd);
  588.                 }
  589.                 break;
  590.             case IDM_BEEP_ON_FINISH:
  591.                 /* Toggle value of beep flag. */
  592.                 uf.fBeepOnFinish = !uf.fBeepOnFinish;
  593.                 CheckMenuItem(hMenu,IDM_BEEP_ON_FINISH,MF_BYCOMMAND|
  594.                                 (WORD)(uf.fBeepOnFinish ? MF_CHECKED: MF_UNCHECKED));
  595.                 WriteProfileString(szAppName, szBeepOnFinish, 
  596.                         (LPSTR)(uf.fBeepOnFinish ? szYes : szNo ));
  597.                 break;
  598.  
  599.             case IDM_LB_EXTRACT:
  600.             case IDM_LB_DISPLAY:
  601.             case IDM_LB_TEST:
  602.                 /* If overwrite change, uncheck old, check new. */
  603.                 /* wParam is the new default action */
  604.                 if (wParam != wLBSelection)
  605.                 {
  606.                     CheckMenuItem(hMenu,wLBSelection,MF_BYCOMMAND|MF_UNCHECKED);
  607.                     CheckMenuItem(hMenu,wParam,MF_BYCOMMAND|MF_CHECKED);
  608.  
  609.                     wLBSelection = wParam;
  610.                     WriteProfileString(szAppName, szLBSelectionKey, 
  611.                         (LPSTR)(LBSelectionTable[wParam - IDM_LB_EXTRACT]));
  612.                 }
  613.                 break;
  614.  
  615.             case IDM_SHOW_COMMENT:
  616.                 /* display the archive comment in mesg window */
  617.                 if ( uf.fCanDragDrop )
  618.                     DragAcceptFiles( hWnd, FALSE );
  619.                 DisplayComment(hWnd);
  620.                 if ( uf.fCanDragDrop )
  621.                     DragAcceptFiles( hWnd, TRUE );
  622.                 break;
  623.             case IDM_RECR_DIR_STRUCT:
  624.                 /* re-create directories structure */
  625.                 uf.fRecreateDirs = !uf.fRecreateDirs;
  626.                 CheckMenuItem(hMenu, IDM_RECR_DIR_STRUCT, 
  627.                  MF_BYCOMMAND | (uf.fRecreateDirs ? MF_CHECKED : MF_UNCHECKED));
  628.                 WriteProfileString(szAppName, szRecreateDirsKey,
  629.                                     (LPSTR)(uf.fRecreateDirs ? szYes : szNo));
  630.                 break;
  631.  
  632.             case IDM_DISPLAY:
  633.             case IDM_TEST:
  634.             case IDM_EXTRACT:
  635.                 if ( uf.fCanDragDrop )
  636.                     DragAcceptFiles( hWnd, FALSE );
  637.                 Action(hWnd, wParam - IDM_EXTRACT);
  638.                 if ( uf.fCanDragDrop )
  639.                     DragAcceptFiles( hWnd, TRUE );
  640.                 break;
  641.  
  642.             case IDM_SELECT_ALL:
  643.             case IDM_DESELECT_ALL:
  644.                 if (cZippedFiles)
  645.                 {
  646.                     SendMessage(hWndList , LB_SELITEMRANGE, 
  647.                             (WORD)(wParam == IDM_DESELECT_ALL ? FALSE : TRUE),
  648.                                 MAKELONG(0, (cZippedFiles-1)));
  649.                     UpdateButtons(hWnd);
  650.                 }
  651.                 break;
  652.  
  653.             case IDM_CLEAR_STATUS:  /* forward to status window */
  654.                 PostMessage(hWndStatus, WM_COMMAND, IDM_CLEAR_STATUS, 0L);
  655.                 break;
  656.  
  657.             case IDM_SHOWHIDE_STATUS:   /* status window was shown/hidden */
  658.                 uf.fStatusHidden = !uf.fStatusHidden;
  659.                 ModifyMenu(hMenu,IDM_SHOWHIDE_STATUS,
  660.                             MF_BYCOMMAND|MF_STRING|MF_ENABLED,
  661.                             IDM_SHOWHIDE_STATUS,
  662.                             (uf.fStatusHidden) ? "S&how Status Window" : "&Hide Status Window");
  663.                 WriteProfileString(szAppName, szHideStatus,
  664.                                     (LPSTR)(uf.fStatusHidden ? szYes : szNo));
  665.                 EnableWindow( hWndStatus, !uf.fStatusHidden );
  666.                 if (uf.fStatusHidden)
  667.                     ShowWindow(hWndStatus, SW_HIDE);
  668.                 else
  669.                     ShowWindow(hWndStatus, SW_SHOWNORMAL);
  670.                 SizeWindow(hWnd, FALSE);
  671.                 break;
  672.                 
  673.             case IDM_MAX_STATUS:    /* status window went to the max */
  674.             case IDM_RESTORE_STATUS:    /* status window restored   */
  675.                 /* This logic is used for maximizing the message window.
  676.                  * It will either hide all other windows allowing the
  677.                  * message window to grow, or it will show them,
  678.                  * allowing the message box to resume its normal size.
  679.                  * These two messages come from the Message window proc.
  680.                  */
  681.                 {
  682.                     int nWndState;  /* ShowWindow state     */
  683.                     BOOL fWndEnabled;   /* Enable Window state */
  684.  
  685.                     if (wParam == IDM_RESTORE_STATUS)
  686.                     {
  687.                         ShowWindow(hWndStatus, SW_RESTORE);
  688.                         UpdateWindow(hWndStatus);
  689.                         uf.fStatusMaximized = FALSE;
  690.                         fWndEnabled = TRUE;
  691.                         nWndState = SW_SHOWNORMAL;
  692.                     }
  693.                     else    /* Message window goes to maximum state     */
  694.                     {
  695.                         uf.fStatusMaximized = TRUE;
  696.                         nWndState = SW_HIDE;    /* assume max state     */
  697.                         fWndEnabled = FALSE;
  698.                     }
  699.  
  700.                     EnableWindow( hWndList, fWndEnabled);
  701.                     UpdateWindow( hWndList);
  702.                     ShowWindow( hWndList, nWndState);
  703.  
  704.                     if (wParam == IDM_RESTORE_STATUS) /* uncover buttons    */
  705.                     {
  706.                         UpdateButtons(hWnd);    /* restore to proper state  */
  707.                     }
  708.                     else    /* else Message window occludes buttons         */
  709.                     {
  710.                         EnableWindow( hExtract, fWndEnabled);
  711.                         EnableWindow( hTest, fWndEnabled);
  712.                         EnableWindow( hDisplay, fWndEnabled);
  713.                         EnableWindow( hShowComment, fWndEnabled);
  714.                     }
  715.  
  716.                     UpdateWindow( hExtract);
  717.                     ShowWindow( hExtract, nWndState);
  718.  
  719.                     ShowWindow( hTest, nWndState);
  720.                     UpdateWindow( hTest);
  721.  
  722.                     ShowWindow( hDisplay, nWndState);
  723.                     UpdateWindow( hDisplay);
  724.  
  725.                     ShowWindow( hShowComment, nWndState);
  726.                     UpdateWindow( hShowComment);
  727.  
  728.                     if (wParam == IDM_MAX_STATUS)   /* message box max'd out */
  729.                     {
  730.                         ShowWindow(hWndStatus, SW_SHOWMAXIMIZED);
  731.                     }
  732.                     SetFocus(hWndStatus);
  733.                     SizeWindow(hWnd, FALSE);
  734.                 }
  735.                 break;
  736.  
  737.             default:
  738.                 return DefWindowProc(hWnd, wMessage, wParam, lParam);
  739.             }
  740.         } /* bottom of not in help mode */
  741.         break;
  742.     case WM_SETCURSOR:
  743.         /* In help mode it is necessary to reset the cursor in response */
  744.         /* to every WM_SETCURSOR message.Otherwise, by default, Windows */
  745.         /* will reset the cursor to that of the window class. */
  746.  
  747.         if (uf.fHelp)
  748.         {
  749.             SetCursor(hHelpCursor);
  750.             break;
  751.         }
  752.         return DefWindowProc(hWnd, wMessage, wParam, lParam);
  753.  
  754.  
  755.     case WM_INITMENU:
  756.         if (uf.fHelp)
  757.         {
  758.             SetCursor(hHelpCursor);
  759.         } 
  760.         return TRUE;
  761.  
  762.     case WM_ENTERIDLE:
  763.         if ((wParam == MSGF_MENU) && (GetKeyState(VK_F1) & 0x8000))
  764.         {
  765.             uf.fHelp = TRUE;
  766.             PostMessage(hWnd, WM_KEYDOWN, VK_RETURN, 0L);
  767.         }
  768.         break;
  769.  
  770.     case WM_CLOSE:
  771.         DestroyWindow(hWnd);
  772.         break;
  773.  
  774.     case WM_DESTROY:
  775.         if ( uf.fCanDragDrop )
  776.             DragAcceptFiles( hWnd, FALSE );
  777.         DeleteObject(hBrush);
  778.         WinHelp(hWnd, szHelpFileName, HELP_QUIT, 0L);
  779.         PostQuitMessage(0);
  780.         break;
  781.  
  782.     case WM_DROPFILES:
  783.         {
  784.             WORD    cFiles;
  785.             WORD    cch;
  786.             
  787.             /* Get the number of files that have been dropped */
  788.             cFiles = DragQueryFile( (HDROP)wParam, (UINT)-1, lpumb->szBuffer, 256);
  789.  
  790.             /* Only handle one dropped file until MDI-ness happens */
  791.             if (cFiles == 1)
  792.             {
  793.                 RECT    rClient;
  794.  
  795.                 cch = DragQueryFile( wParam, 0, lpumb->szFileName, 128);
  796.  
  797.                 if (uf.fUnzipToZipDir)
  798.                 {
  799.                     LPSTR lpchLast;
  800.  
  801.                     /* strip off filename to make directory name    */
  802.                     OemToAnsi(lpumb->szFileName, lpumb->szOrigDirName);
  803.                     if ((lpchLast = lstrrchr(lpumb->szOrigDirName, '\\')) ||
  804.                         (lpchLast = lstrrchr(lpumb->szOrigDirName, ':')))
  805.                         *lpchLast = '\0';
  806.                 }
  807.  
  808.                 UpdateListBox(hWnd); /* fill in list box */
  809.                 SendMessage(hWndList, LB_SETSEL, 1, 0L);
  810.                 UpdateButtons(hWnd); /* update state of buttons */
  811.  
  812.                 GetClientRect( hWndList, &rClient );
  813.                 OffsetRect( &rClient, 0, dyChar );
  814.                 rClient.top = rClient.bottom;
  815.                 rClient.bottom = rClient.top + (2*dyChar);
  816.                 InvalidateRect( hWnd, &rClient, TRUE);
  817.                 UpdateWindow( hWnd );
  818.                 SetCaption(hWnd);
  819.             }
  820.             DragFinish( (HDROP)wParam );
  821.         }
  822.         break;
  823.  
  824.     case WM_PAINT:
  825.         if ( !uf.fStatusMaximized )
  826.         {
  827.             PAINTSTRUCT ps;
  828.             RECT    rClient;
  829.             DWORD   dwBackColor;
  830.             
  831.             hDC = BeginPaint( hWnd, &ps );
  832.             if ( hDC )
  833.             {
  834.                 GetClientRect( hWndList, &rClient );
  835.                 if (RectVisible( hDC, &rClient ))
  836.                     UpdateWindow( hWndList );
  837.                 hOldFont = SelectObject ( hDC, hFixedFont);
  838.                 GetClientRect( hWnd, &rClient );
  839.                 dwBackColor = SetBkColor(hDC,GetSysColor(BG_SYS_COLOR));
  840.  
  841.                 rClient.top = 0;
  842.                 rClient.left += dxChar/2;
  843.                 DrawText( hDC, (LPSTR)Headers[uf.fFormatLong][0], -1, &rClient, DT_NOPREFIX | DT_TOP);
  844.  
  845.                 GetClientRect( hWndList, &rClient );
  846.                 OffsetRect( &rClient, 0, dyChar+2);
  847.                 rClient.left += dxChar/2;
  848.                 rClient.top = rClient.bottom;
  849.                 rClient.bottom = rClient.top + dyChar;
  850.                 DrawText( hDC, (LPSTR)szTrailers[uf.fFormatLong], -1, &rClient, DT_NOPREFIX | DT_TOP);
  851.  
  852.                 rClient.top += dyChar;
  853.                 rClient.bottom += dyChar;
  854.                 DrawText( hDC, lpumb->szTotalsLine, -1, &rClient, DT_NOPREFIX | DT_TOP);
  855.  
  856.                 SetBkColor(hDC, dwBackColor);
  857.                 (void)SelectObject ( hDC, hOldFont);
  858.             }
  859.             EndPaint(hWnd, &ps);
  860.             break;
  861.         }
  862.         /* else fall thru */
  863.     default:
  864.         return DefWindowProc(hWnd, wMessage, wParam, lParam);
  865.     }
  866.     return 0;
  867. }
  868.