winmain.cpp
资源名称:unzip540.zip [点击查看]
上传用户:andy_li
上传日期:2007-01-06
资源大小:1019k
文件大小:131k
源码类别:
压缩解压
开发平台:
MultiPlatform
- //******************************************************************************
- LPTSTR BuildAttributesString(LPTSTR szBuffer, DWORD dwAttributes) {
- // Build the attribute string according to the flags specified for this file.
- _stprintf(szBuffer, TEXT("%s%s%s%s%s%s%s%s"),
- (dwAttributes & FILE_ATTRIBUTE_VOLUME) ? TEXT("V") : TEXT(""),
- (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) ? TEXT("D") : TEXT(""),
- (dwAttributes & FILE_ATTRIBUTE_READONLY) ? TEXT("R") : TEXT(""),
- (dwAttributes & FILE_ATTRIBUTE_ARCHIVE) ? TEXT("A") : TEXT(""),
- (dwAttributes & FILE_ATTRIBUTE_HIDDEN) ? TEXT("H") : TEXT(""),
- (dwAttributes & FILE_ATTRIBUTE_SYSTEM) ? TEXT("S") : TEXT(""),
- (dwAttributes & FILE_ATTRIBUTE_ENCRYPTED) ? TEXT("E") : TEXT(""),
- (dwAttributes & FILE_ATTRIBUTE_COMMENT) ? TEXT("C") : TEXT(""));
- return szBuffer;
- }
- //******************************************************************************
- LPCSTR BuildTypeString(FILE_NODE *pFile, LPSTR szType) {
- // First check to see if we have a known description.
- if (pFile->szType) {
- return pFile->szType;
- }
- // Locate the file portion of our path.
- LPCSTR pszFile = GetFileFromPath(pFile->szPathAndMethod);
- // Get the extension portion of the file.
- LPCSTR pszExt = strrchr(pszFile, '.');
- // If we have an extension create a type name for this file.
- if (pszExt && *(pszExt + 1)) {
- strcpy(szType, pszExt + 1);
- _strupr(szType);
- strcat(szType, " File");
- return szType;
- }
- // If no extension, then use the default "File".
- return "File";
- }
- //******************************************************************************
- LPCSTR GetFileFromPath(LPCSTR szPath) {
- LPCSTR p1 = strrchr(szPath, '/'), p2 = strrchr(szPath, '\');
- if (p1 && (p1 > p2)) {
- return p1 + 1;
- } else if (p2) {
- return p2 + 1;
- }
- return szPath;
- }
- //******************************************************************************
- void ForwardSlashesToBackSlashesA(LPSTR szBuffer) {
- while (*szBuffer) {
- if (*szBuffer == '/') {
- *szBuffer = '\';
- }
- szBuffer++;
- }
- }
- //******************************************************************************
- void ForwardSlashesToBackSlashesW(LPWSTR szBuffer) {
- while (*szBuffer) {
- if (*szBuffer == L'/') {
- *szBuffer = L'\';
- }
- szBuffer++;
- }
- }
- //******************************************************************************
- void DeleteDirectory(LPTSTR szPath) {
- // Make note to where the end of our path is.
- LPTSTR szEnd = szPath + _tcslen(szPath);
- // Add our search spec to the path.
- _tcscpy(szEnd, TEXT("\*.*"));
- // Start a directory search.
- WIN32_FIND_DATA w32fd;
- HANDLE hFind = FindFirstFile(szPath, &w32fd);
- // Loop through all entries in this directory.
- if (hFind != INVALID_HANDLE_VALUE) {
- do {
- // Append the file/directory name to the path.
- _tcscpy(szEnd + 1, w32fd.cFileName);
- // Check to see if this entry is a subdirectory.
- if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- // Ignore current directory (.) and previous directory (..)
- if (_tcscmp(w32fd.cFileName, TEXT(".")) &&
- _tcscmp(w32fd.cFileName, TEXT("..")))
- {
- // Recurse into DeleteDirectory() to delete subdirectory.
- DeleteDirectory(szPath);
- }
- // Otherwise, it must be a file.
- } else {
- // If the file is marked as read-only, then change to read/write.
- if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
- SetFileAttributes(szPath, FILE_ATTRIBUTE_NORMAL);
- }
- // Attempt to delete the file. If we fail and the file used to be
- // read-only, then set the read-only bit back on it.
- if (!DeleteFile(szPath) &&
- (w32fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
- {
- SetFileAttributes(szPath, FILE_ATTRIBUTE_READONLY);
- }
- }
- // Get the next directory entry.
- } while (FindNextFile(hFind, &w32fd));
- // Close the directory search.
- FindClose(hFind);
- }
- // Remove the directory.
- *szEnd = TEXT(' ');
- RemoveDirectory(szPath);
- }
- //******************************************************************************
- //***** Registry Functions
- //******************************************************************************
- void RegWriteKey(HKEY hKeyRoot, LPCTSTR szSubKey, LPCTSTR szValue) {
- HKEY hKey = NULL;
- DWORD dwDisposition;
- if (RegCreateKeyEx(hKeyRoot, szSubKey, 0, NULL, 0, KEY_SET_VALUE, NULL, &hKey, &dwDisposition) == ERROR_SUCCESS) {
- if (szValue) {
- RegSetValueEx(hKey, NULL, 0, REG_SZ, (LPBYTE)szValue,
- sizeof(TCHAR) * (_tcslen(szValue) + 1));
- }
- RegCloseKey(hKey);
- }
- }
- //******************************************************************************
- BOOL RegReadKey(HKEY hKeyRoot, LPCTSTR szSubKey, LPTSTR szValue, DWORD cBytes) {
- *szValue = TEXT(' ');
- HKEY hKey = NULL;
- LRESULT lResult = -1;
- if (RegOpenKeyEx(hKeyRoot, szSubKey, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) {
- lResult = RegQueryValueEx(hKey, NULL, NULL, NULL, (LPBYTE)szValue, &cBytes);
- RegCloseKey(hKey);
- }
- return ((lResult == ERROR_SUCCESS) && *szValue);
- }
- //******************************************************************************
- void WriteOptionString(LPCTSTR szOption, LPCTSTR szValue) {
- HKEY hKey = NULL;
- if (RegOpenKeyEx(HKEY_CURRENT_USER, g_szRegKey, 0, KEY_SET_VALUE, &hKey) == ERROR_SUCCESS) {
- RegSetValueEx(hKey, szOption, 0, REG_SZ, (LPBYTE)szValue,
- sizeof(TCHAR) * (_tcslen(szValue) + 1));
- RegCloseKey(hKey);
- }
- }
- //******************************************************************************
- void WriteOptionInt(LPCTSTR szOption, DWORD dwValue) {
- HKEY hKey = NULL;
- if (RegOpenKeyEx(HKEY_CURRENT_USER, g_szRegKey, 0, KEY_SET_VALUE, &hKey) == ERROR_SUCCESS) {
- RegSetValueEx(hKey, szOption, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
- RegCloseKey(hKey);
- }
- }
- //******************************************************************************
- LPTSTR GetOptionString(LPCTSTR szOption, LPCTSTR szDefault, LPTSTR szValue, DWORD nSize) {
- HKEY hKey = NULL;
- LONG lResult = -1;
- if (RegOpenKeyEx(HKEY_CURRENT_USER, g_szRegKey, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) {
- lResult = RegQueryValueEx(hKey, szOption, NULL, NULL, (LPBYTE)szValue, &nSize);
- RegCloseKey(hKey);
- }
- if (lResult != ERROR_SUCCESS) {
- _tcscpy(szValue, szDefault);
- }
- return szValue;
- }
- //******************************************************************************
- DWORD GetOptionInt(LPCTSTR szOption, DWORD dwDefault) {
- HKEY hKey = NULL;
- LONG lResult = -1;
- DWORD dwValue;
- DWORD nSize = sizeof(dwValue);
- if (RegOpenKeyEx(HKEY_CURRENT_USER, g_szRegKey, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) {
- lResult = RegQueryValueEx(hKey, szOption, NULL, NULL, (LPBYTE)&dwValue, &nSize);
- RegCloseKey(hKey);
- }
- return (lResult == ERROR_SUCCESS) ? dwValue : dwDefault;
- }
- //******************************************************************************
- //***** EDIT Control Subclass Functions
- //******************************************************************************
- void DisableEditing(HWND hWndEdit) {
- // Make sure the control does not have ES_READONLY or ES_WANTRETURN styles.
- DWORD dwStyle = (DWORD)GetWindowLong(hWndEdit, GWL_STYLE);
- if (dwStyle & (ES_READONLY | ES_WANTRETURN)) {
- SetWindowLong(hWndEdit, GWL_STYLE, dwStyle & ~(ES_READONLY | ES_WANTRETURN));
- }
- // Subclass the control so we can intercept certain keys.
- g_wpEdit = (WNDPROC)GetWindowLong(hWndEdit, GWL_WNDPROC);
- SetWindowLong(hWndEdit, GWL_WNDPROC, (LONG)EditSubclassProc);
- }
- //******************************************************************************
- LRESULT CALLBACK EditSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- BOOL fCtrl, fShift;
- switch (uMsg) {
- // For cut, paste, delete, and undo, the control post itself a message.
- // we throw away that message. This works as a fail-safe in case we miss
- // some keystroke that causes one of these operations. This also disables
- // the context menu on NT from causing one of these actions to occur.
- case WM_CUT:
- case WM_PASTE:
- case WM_CLEAR:
- case WM_UNDO:
- MessageBeep(0);
- return 0;
- // WM_CHAR is used for normal characters. A-Z, numbers, symbols, enter,
- // backspace, esc, and tab. In does not include del or movement keys.
- case WM_CHAR:
- fCtrl = (GetKeyState(VK_CONTROL) & 0x8000) ? TRUE : FALSE;
- // We only allow CTRL-C (copy), plain ESC, plain TAB, plain ENTER.
- if (( fCtrl && (wParam == 3)) ||
- (!fCtrl && (wParam == VK_ESCAPE)) ||
- (!fCtrl && (wParam == VK_RETURN)) ||
- (!fCtrl && (wParam == VK_TAB)))
- {
- break;
- }
- MessageBeep(0);
- return 0;
- // WM_KEYDOWN handles del, insert, arrows, pg up/down, home/end.
- case WM_KEYDOWN:
- fCtrl = (GetKeyState(VK_CONTROL) & 0x8000) ? TRUE : FALSE;
- fShift = (GetKeyState(VK_SHIFT) & 0x8000) ? TRUE : FALSE;
- // Skip all forms of DELETE, SHIFT-INSERT (paste),
- // CTRL-RETURN (hard-return), and CTRL-TAB (hard-tab).
- if (( (wParam == VK_DELETE)) ||
- (fShift && (wParam == VK_INSERT)) ||
- (fCtrl && (wParam == VK_RETURN)) ||
- (fCtrl && (wParam == VK_TAB)))
- {
- MessageBeep(0);
- return 0;
- }
- break;
- }
- return CallWindowProc(g_wpEdit, hWnd, uMsg, wParam, lParam);
- }
- //******************************************************************************
- //***** MRU Functions
- //******************************************************************************
- #ifdef _WIN32_WCE
- int GetMenuString(HMENU hMenu, UINT uIDItem, LPTSTR lpString, int nMaxCount,
- UINT uFlag) {
- MENUITEMINFO mii;
- ZeroMemory(&mii, sizeof(mii));
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_TYPE;
- mii.dwTypeData = lpString;
- mii.cch = nMaxCount;
- return (GetMenuItemInfo(hMenu, uIDItem, uFlag == MF_BYPOSITION, &mii) ?
- mii.cch : 0);
- }
- #endif
- //******************************************************************************
- void InitializeMRU() {
- TCHAR szMRU[MRU_MAX_FILE][_MAX_PATH + 4], szOption[8];
- int i, j;
- // Get our menu handle.
- #ifdef _WIN32_WCE
- HMENU hMenu = GetSubMenu(CommandBar_GetMenu(g_hWndCmdBar, 0), 0);
- #else
- HMENU hMenu = GetSubMenu(GetMenu(g_hWndMain), 0);
- #endif
- // Read all our current MRUs from the registry.
- for (i = 0, j = 0; i < MRU_MAX_FILE; i++) {
- // Build option name for current MRU and read from registry.
- _stprintf(szOption, TEXT("MRU%d"), i+1);
- GetOptionString(szOption, TEXT(""), &szMRU[i][3], sizeof(TCHAR) * _MAX_PATH);
- // If this MRU exists, then add it.
- if (szMRU[i][3]) {
- // Build the accelerator prefix for this menu item.
- szMRU[i][0] = TEXT('&');
- szMRU[i][1] = TEXT('1') + j;
- szMRU[i][2] = TEXT(' ');
- // Add the item to our menu.
- InsertMenu(hMenu, 4 + j, MF_BYPOSITION | MF_STRING, MRU_START_ID + j,
- szMRU[i]);
- // Increment our actual MRU count.
- j++;
- }
- }
- }
- //******************************************************************************
- void AddFileToMRU(LPCSTR szFile) {
- TCHAR szMRU[MRU_MAX_FILE + 1][_MAX_PATH + 4], szOption[8];
- int i, j;
- // Store the new file in our first MRU index.
- mbstowcs(&szMRU[0][3], szFile, _MAX_PATH);
- //---------------------------------------------------------------------------
- // We first read the current MRU list from the registry, merge in our new
- // file at the top, and then write back to the registry. The registry merge
- // is done to allow multiple instances of Pocket UnZip to maintain a global
- // MRU list independent to this current instance's MRU list.
- //---------------------------------------------------------------------------
- // Read all our current MRUs from the registry.
- for (i = 1; i <= MRU_MAX_FILE; i++) {
- // Build option name for current MRU and read from registry.
- _stprintf(szOption, TEXT("MRU%d"), i);
- GetOptionString(szOption, TEXT(""), &szMRU[i][3], sizeof(TCHAR) * _MAX_PATH);
- }
- // Write our new merged MRU list back to the registry.
- for (i = 0, j = 0; (i <= MRU_MAX_FILE) && (j < MRU_MAX_FILE); i++) {
- // If this MRU exists and is different then our new file, then add it.
- if ((i == 0) || (szMRU[i][3] && _tcsicmp(&szMRU[0][3], &szMRU[i][3]))) {
- // Build option name for current MRU and write to registry.
- _stprintf(szOption, TEXT("MRU%d"), ++j);
- WriteOptionString(szOption, &szMRU[i][3]);
- }
- }
- //---------------------------------------------------------------------------
- // The next thing we need to do is read our local MRU from our File menu,
- // merge in our new file, and store the new list back to our File menu.
- //---------------------------------------------------------------------------
- // Get our menu handle.
- #ifdef _WIN32_WCE
- HMENU hMenu = GetSubMenu(CommandBar_GetMenu(g_hWndCmdBar, 0), 0);
- #else
- HMENU hMenu = GetSubMenu(GetMenu(g_hWndMain), 0);
- #endif
- // Read all our current MRUs from our File Menu.
- for (i = 1; i <= MRU_MAX_FILE; i++) {
- // Query our file Menu for a MRU file.
- if (GetMenuString(hMenu, MRU_START_ID + i - 1, szMRU[i],
- countof(szMRU[0]), MF_BYCOMMAND))
- {
- // Delete this item from the menu for now.
- DeleteMenu(hMenu, MRU_START_ID + i - 1, MF_BYCOMMAND);
- } else {
- szMRU[i][3] = TEXT(' ');
- }
- }
- // Write our new merged MRU list back to the File menu.
- for (i = 0, j = 0; (i <= MRU_MAX_FILE) && (j < MRU_MAX_FILE); i++) {
- // If this MRU exists and is different then our new file, then add it.
- if ((i == 0) || (szMRU[i][3] && _tcsicmp(&szMRU[0][3], &szMRU[i][3]))) {
- // Build the accelerator prefix for this menu item.
- szMRU[i][0] = TEXT('&');
- szMRU[i][1] = TEXT('1') + j;
- szMRU[i][2] = TEXT(' ');
- // Add the item to our menu.
- InsertMenu(hMenu, 4 + j, MF_BYPOSITION | MF_STRING, MRU_START_ID + j,
- szMRU[i]);
- // Increment our actual MRU count.
- j++;
- }
- }
- }
- //******************************************************************************
- void RemoveFileFromMRU(LPCTSTR szFile) {
- TCHAR szMRU[MRU_MAX_FILE][_MAX_PATH + 4], szOption[8];
- int i, j;
- BOOL fFound;
- //---------------------------------------------------------------------------
- // We first look for this file in our global MRU stored in the registry. We
- // read the current MRU list from the registry, and then write it back while
- // removing all occurrances of the file specified.
- //---------------------------------------------------------------------------
- // Read all our current MRUs from the registry.
- for (i = 0, fFound = FALSE; i < MRU_MAX_FILE; i++) {
- // Build option name for current MRU and read from registry.
- _stprintf(szOption, TEXT("MRU%d"), i+1);
- GetOptionString(szOption, TEXT(""), &szMRU[i][3], sizeof(TCHAR) * _MAX_PATH);
- // Check for a match.
- if (!_tcsicmp(szFile, &szMRU[i][3])) {
- szMRU[i][3] = TEXT(' ');
- fFound = TRUE;
- }
- }
- // Only write the MRU back to the registry if we found a file to remove.
- if (fFound) {
- // Write the updated MRU list back to the registry.
- for (i = 0, j = 0; i < MRU_MAX_FILE; i++) {
- // If this MRU still exists, then add it.
- if (szMRU[i][3]) {
- // Build option name for current MRU and write to registry.
- _stprintf(szOption, TEXT("MRU%d"), ++j);
- WriteOptionString(szOption, &szMRU[i][3]);
- }
- }
- // If our list got smaller, clear the unused items in the registry.
- while (j++ < MRU_MAX_FILE) {
- _stprintf(szOption, TEXT("MRU%d"), j);
- WriteOptionString(szOption, TEXT(""));
- }
- }
- //---------------------------------------------------------------------------
- // We next thing we do is look for this file in our local MRU stored in our
- // File menu. We read the current MRU list from the menu, and then write it
- // back while removing all occurrances of the file specified.
- //---------------------------------------------------------------------------
- // Get our menu handle.
- #ifdef _WIN32_WCE
- HMENU hMenu = GetSubMenu(CommandBar_GetMenu(g_hWndCmdBar, 0), 0);
- #else
- HMENU hMenu = GetSubMenu(GetMenu(g_hWndMain), 0);
- #endif
- // Read all our current MRUs from our File Menu.
- for (i = 0, fFound = FALSE; i < MRU_MAX_FILE; i++) {
- // Query our file Menu for a MRU file.
- if (!GetMenuString(hMenu, MRU_START_ID + i, szMRU[i], countof(szMRU[0]),
- MF_BYCOMMAND))
- {
- szMRU[i][3] = TEXT(' ');
- }
- // Check for a match.
- if (!_tcsicmp(szFile, &szMRU[i][3])) {
- szMRU[i][3] = TEXT(' ');
- fFound = TRUE;
- }
- }
- // Only update menu if we found a file to remove.
- if (fFound) {
- // Clear out our menu's MRU list.
- for (i = MRU_START_ID; i < (MRU_START_ID + MRU_MAX_FILE); i++) {
- DeleteMenu(hMenu, i, MF_BYCOMMAND);
- }
- // Write the rest of our MRU list back to the menu.
- for (i = 0, j = 0; i < MRU_MAX_FILE; i++) {
- // If this MRU still exists, then add it.
- if (szMRU[i][3]) {
- // Build the accelerator prefix for this menu item.
- szMRU[i][0] = TEXT('&');
- szMRU[i][1] = TEXT('1') + j;
- szMRU[i][2] = TEXT(' ');
- // Add the item to our menu.
- InsertMenu(hMenu, 4 + j, MF_BYPOSITION | MF_STRING, MRU_START_ID + j,
- szMRU[i]);
- // Increment our actual MRU count.
- j++;
- }
- }
- }
- }
- //******************************************************************************
- void ActivateMRU(UINT uIDItem) {
- TCHAR szFile[_MAX_PATH + 4];
- // Get our menu handle.
- #ifdef _WIN32_WCE
- HMENU hMenu = GetSubMenu(CommandBar_GetMenu(g_hWndCmdBar, 0), 0);
- #else
- HMENU hMenu = GetSubMenu(GetMenu(g_hWndMain), 0);
- #endif
- // Query our menu for the selected MRU.
- if (GetMenuString(hMenu, uIDItem, szFile, countof(szFile), MF_BYCOMMAND)) {
- // Move past 3 character accelerator prefix and open the file.
- ReadZipFileList(&szFile[3]);
- }
- }
- //******************************************************************************
- //***** Open Zip File Functions
- //******************************************************************************
- void ReadZipFileList(LPCWSTR wszPath) {
- // Show wait cursor.
- HCURSOR hCur = SetCursor(LoadCursor(NULL, IDC_WAIT));
- wcstombs(g_szZipFile, wszPath, countof(g_szZipFile));
- // Update our banner to show that we are loading.
- g_fLoading = TRUE;
- DrawBanner(NULL);
- // Update our caption to show that we are loading.
- SetCaptionText(TEXT("Loading"));
- // Clear our list view.
- ListView_DeleteAllItems(g_hWndList);
- // Ghost all our Unzip related menu items.
- EnableAllMenuItems(IDM_FILE_PROPERTIES, FALSE);
- EnableAllMenuItems(IDM_ACTION_EXTRACT, FALSE);
- EnableAllMenuItems(IDM_ACTION_EXTRACT_ALL, FALSE);
- EnableAllMenuItems(IDM_ACTION_TEST, FALSE);
- EnableAllMenuItems(IDM_ACTION_TEST_ALL, FALSE);
- EnableAllMenuItems(IDM_ACTION_VIEW, FALSE);
- EnableAllMenuItems(IDM_ACTION_SELECT_ALL, FALSE);
- EnableAllMenuItems(IDM_VIEW_COMMENT, FALSE);
- // Let Info-ZIP and our callbacks do the work.
- SendMessage(g_hWndList, WM_SETREDRAW, FALSE, 0);
- int result = DoListFiles(g_szZipFile);
- SendMessage(g_hWndList, WM_SETREDRAW, TRUE, 0);
- // Restore/remove cursor.
- SetCursor(hCur);
- // Update our column widths
- ResizeColumns();
- if ((result == PK_OK) || (result == PK_WARN)) {
- // Sort the items by name.
- Sort(0, TRUE);
- // Update this file to our MRU list and menu.
- AddFileToMRU(g_szZipFile);
- // Enabled the comment button if the zip file has a comment.
- if (lpUserFunctions->cchComment) {
- EnableAllMenuItems(IDM_VIEW_COMMENT, TRUE);
- }
- // Update other items that are related to having a Zip file loaded.
- EnableAllMenuItems(IDM_ACTION_EXTRACT_ALL, TRUE);
- EnableAllMenuItems(IDM_ACTION_TEST_ALL, TRUE);
- EnableAllMenuItems(IDM_ACTION_SELECT_ALL, TRUE);
- } else {
- // Make sure we didn't partially load and added a few files.
- ListView_DeleteAllItems(g_hWndList);
- // If the file itself is bad or missing, then remove it from our MRU.
- if ((result == PK_ERR) || (result == PK_BADERR) || (result == PK_NOZIP) ||
- (result == PK_FIND) || (result == PK_EOF))
- {
- RemoveFileFromMRU(wszPath);
- }
- // Display an error.
- TCHAR szError[_MAX_PATH + 128];
- _stprintf(szError, TEXT("Failure loading "%s".nn"), wszPath);
- _tcscat(szError, GetZipErrorString(result));
- MessageBox(g_hWndMain, szError, g_szAppName, MB_OK | MB_ICONERROR);
- // Clear our file status.
- *g_szZipFile = ' ';
- }
- // Update our caption to show that we are done loading.
- SetCaptionText(NULL);
- // Update our banner to show that we are done loading.
- g_fLoading = FALSE;
- DrawBanner(NULL);
- }
- //******************************************************************************
- //***** Zip File Properties Dialog Functions
- //******************************************************************************
- BOOL CALLBACK DlgProcProperties(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- switch (uMsg) {
- case WM_INITDIALOG: {
- // Add "General" and "Comments" tabs to tab control. We are using a
- // poor man's version of a property sheet. We display our 2 pages
- // by showing and hiding controls as necessary. For our purposes,
- // this is much easier than dealing with separate property pages.
- TC_ITEM tci;
- tci.mask = TCIF_TEXT;
- tci.pszText = TEXT("General");
- TabCtrl_InsertItem(GetDlgItem(hDlg, IDC_TAB), 0, &tci);
- tci.pszText = TEXT("Comment");
- TabCtrl_InsertItem(GetDlgItem(hDlg, IDC_TAB), 1, &tci);
- #ifdef _WIN32_WCE
- // Add "Ok" button to caption bar.
- SetWindowLong(hDlg, GWL_EXSTYLE, WS_EX_CAPTIONOKBTN |
- GetWindowLong(hDlg, GWL_EXSTYLE));
- #endif
- // Center us over our parent.
- CenterWindow(hDlg);
- int directory = -1, readOnly = -1, archive = -1, hidden = -1;
- int system = -1, encrypted = -1;
- int year = -1, month = -1, day = -1, hour = -1, minute = -1, pm = -1;
- DWORD dwSize = 0, dwCompressedSize = 0;
- LPCSTR szPath = NULL, szMethod = NULL, szComment = NULL;
- DWORD dwCRC = 0, dwCount = 0, dwCommentCount = 0;
- TCHAR szBuffer[MAX_PATH];
- // Loop through all selected items.
- LV_ITEM lvi;
- ZeroMemory(&lvi, sizeof(lvi));
- lvi.mask = LVIF_PARAM;
- lvi.iItem = -1;
- while ((lvi.iItem = ListView_GetNextItem(g_hWndList, lvi.iItem, LVNI_SELECTED)) != -1) {
- // Get the FILE_NODE for the selected item.
- ListView_GetItem(g_hWndList, &lvi);
- FILE_NODE *pFile = (FILE_NODE*)lvi.lParam;
- // Merge this file's attributes into our accumulative attributes.
- MergeValues(&directory, (pFile->dwAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
- MergeValues(&readOnly, (pFile->dwAttributes & FILE_ATTRIBUTE_READONLY) != 0);
- MergeValues(&archive, (pFile->dwAttributes & FILE_ATTRIBUTE_ARCHIVE) != 0);
- MergeValues(&hidden, (pFile->dwAttributes & FILE_ATTRIBUTE_HIDDEN) != 0);
- MergeValues(&system, (pFile->dwAttributes & FILE_ATTRIBUTE_SYSTEM) != 0);
- MergeValues(&encrypted, (pFile->dwAttributes & FILE_ATTRIBUTE_ENCRYPTED) != 0);
- // Merge this file's date/time into our accumulative date/time.
- int curHour = (pFile->dwModified >> 6) & 0x001F;
- MergeValues(&year, (pFile->dwModified >> 20) & 0x0FFF);
- MergeValues(&month, (pFile->dwModified >> 16) & 0x000F);
- MergeValues(&day, (pFile->dwModified >> 11) & 0x001F);
- MergeValues(&hour, (curHour % 12) ? (curHour % 12) : 12);
- MergeValues(&minute, pFile->dwModified & 0x003F);
- MergeValues(&pm, curHour >= 12);
- // Store this file's name.
- szPath = pFile->szPathAndMethod;
- // Store this file's CRC.
- dwCRC = pFile->dwCRC;
- // Add the size and compressed size to our accumulative sizes.
- dwSize += pFile->dwSize;
- dwCompressedSize += pFile->dwCompressedSize;
- // Merge in our compression method.
- LPCSTR szCurMethod = pFile->szPathAndMethod + strlen(pFile->szPathAndMethod) + 1;
- if ((szMethod == NULL) || !strcmp(szMethod, szCurMethod)) {
- szMethod = szCurMethod;
- } else {
- szMethod = "Multiple Methods";
- }
- // Increment our file count.
- dwCount++;
- // Increment our comment count if this file has a comment.
- if (pFile->szComment) {
- szComment = pFile->szComment;
- dwCommentCount++;
- }
- };
- if (dwCount > 1) {
- // If multiple items selected, then display a selected count string
- // in place of the file name.
- _stprintf(szBuffer, TEXT("%u items selected."), dwCount);
- SetDlgItemText(hDlg, IDC_FILE, szBuffer);
- // Display "Multiple" for CRC if multiple items selected.
- SetDlgItemText(hDlg, IDC_CRC, TEXT("Multiple CRCs"));
- } else {
- // Set the file name text for the single item selected.
- mbstowcs(szBuffer, szPath, countof(szBuffer));
- ForwardSlashesToBackSlashesW(szBuffer);
- SetDlgItemText(hDlg, IDC_FILE, szBuffer);
- // Set the CRC text for the single item selected.
- _stprintf(szBuffer, TEXT("0x%08X"), dwCRC);
- SetDlgItemText(hDlg, IDC_CRC, szBuffer);
- }
- // Set the Size tally text.
- FormatValue(szBuffer, dwSize);
- _tcscat(szBuffer, (dwCount > 1) ? TEXT(" bytes total") : TEXT(" bytes"));
- SetDlgItemText(hDlg, IDC_FILE_SIZE, szBuffer);
- // Set the Compressed Size tally text.
- FormatValue(szBuffer, dwCompressedSize);
- _tcscat(szBuffer, (dwCount > 1) ? TEXT(" bytes total") : TEXT(" bytes"));
- SetDlgItemText(hDlg, IDC_COMPRESSED_SIZE, szBuffer);
- // Set the Compression Factor text.
- int factor = ratio(dwSize, dwCompressedSize);
- _stprintf(szBuffer, TEXT("%d.%d%%"), factor / 10,
- ((factor < 0) ? -factor : factor) % 10);
- SetDlgItemText(hDlg, IDC_COMPRESSON_FACTOR, szBuffer);
- // Set the Compression Method text.
- mbstowcs(szBuffer, szMethod, countof(szBuffer));
- SetDlgItemText(hDlg, IDC_COMPRESSION_METHOD, szBuffer);
- // Set the Attribute check boxes.
- CheckThreeStateBox(hDlg, IDC_DIRECTORY, directory);
- CheckThreeStateBox(hDlg, IDC_READONLY, readOnly);
- CheckThreeStateBox(hDlg, IDC_ARCHIVE, archive);
- CheckThreeStateBox(hDlg, IDC_HIDDEN, hidden);
- CheckThreeStateBox(hDlg, IDC_SYSTEM, system);
- CheckThreeStateBox(hDlg, IDC_ENCRYPTED, encrypted);
- // Build and set the Modified Date text. The MS compiler does not
- // consider "??/" to be a valid string. "??/" is a trigraph that is
- // turned into "" by the preprocessor and causes grief for the compiler.
- LPTSTR psz = szBuffer;
- psz += ((month < 0) ? _stprintf(psz, TEXT("??/")) :
- _stprintf(psz, TEXT("%u/"), month));
- psz += ((day < 0) ? _stprintf(psz, TEXT("??/")) :
- _stprintf(psz, TEXT("%u/"), day));
- psz += ((year < 0) ? _stprintf(psz, TEXT("?? ")) :
- _stprintf(psz, TEXT("%u "), year % 100));
- psz += ((hour < 0) ? _stprintf(psz, TEXT("??:")) :
- _stprintf(psz, TEXT("%u:"), hour));
- psz += ((minute < 0) ? _stprintf(psz, TEXT("?? ")) :
- _stprintf(psz, TEXT("%02u "), minute));
- psz += ((pm < 0) ? _stprintf(psz, TEXT("?M")) :
- _stprintf(psz, TEXT("%cM"), pm ? TEXT('P') : TEXT('A')));
- SetDlgItemText(hDlg, IDC_MODIFIED, szBuffer);
- // Store a global handle to our edit control.
- g_hWndEdit = GetDlgItem(hDlg, IDC_COMMENT);
- // Disable our edit box from being edited.
- DisableEditing(g_hWndEdit);
- // Stuff the appropriate message into the Comment edit control.
- if (dwCommentCount == 0) {
- if (dwCount == 1) {
- AddTextToEdit("This file does not have a comment.");
- } else {
- AddTextToEdit("None of the selected files have a comment.");
- }
- } else if (dwCount == 1) {
- AddTextToEdit(szComment);
- } else {
- CHAR szTemp[64];
- _stprintf(szBuffer, TEXT("%u of the selected files %s a comment."),
- dwCommentCount, (dwCommentCount == 1)? TEXT("has") : TEXT("have"));
- wcstombs(szTemp, szBuffer, countof(szTemp));
- AddTextToEdit(szTemp);
- }
- g_hWndEdit = NULL;
- // Whooh, done with WM_INITDIALOG
- return TRUE;
- }
- case WM_NOTIFY:
- // Check to see if tab control was changed to new tab.
- if (((NMHDR*)lParam)->code == TCN_SELCHANGE) {
- HWND hWndTab = ((NMHDR*)lParam)->hwndFrom;
- HWND hWndComment = GetDlgItem(hDlg, IDC_COMMENT);
- HWND hWnd = GetWindow(hDlg, GW_CHILD);
- // If General tab selected, hide comment edit box and show all other controls.
- if (TabCtrl_GetCurSel(hWndTab) == 0) {
- while (hWnd) {
- ShowWindow(hWnd, ((hWnd == hWndTab) || (hWnd != hWndComment)) ?
- SW_SHOW : SW_HIDE);
- hWnd = GetWindow(hWnd, GW_HWNDNEXT);
- }
- // If Comment tab selected, hide all controls except comment edit box.
- } else {
- while (hWnd) {
- ShowWindow(hWnd, ((hWnd == hWndTab) || (hWnd == hWndComment)) ?
- SW_SHOW : SW_HIDE);
- hWnd = GetWindow(hWnd, GW_HWNDNEXT);
- }
- }
- }
- return FALSE;
- case WM_COMMAND:
- // Exit the dialog on OK (Enter) or CANCEL (Esc).
- if ((LOWORD(wParam) == IDOK) || (LOWORD(wParam) == IDCANCEL)) {
- EndDialog(hDlg, LOWORD(wParam));
- }
- return FALSE;
- }
- return FALSE;
- }
- //******************************************************************************
- void MergeValues(int *p1, int p2) {
- if ((*p1 == -1) || (*p1 == p2)) {
- *p1 = p2;
- } else {
- *p1 = -2;
- }
- }
- //******************************************************************************
- void CheckThreeStateBox(HWND hDlg, int nIDButton, int state) {
- CheckDlgButton(hDlg, nIDButton, (state == 0) ? BST_UNCHECKED :
- (state == 1) ? BST_CHECKED :
- BST_INDETERMINATE);
- }
- //******************************************************************************
- //***** Extract/Test Dialog Functions
- //******************************************************************************
- void ExtractOrTestFiles(BOOL fExtract) {
- EXTRACT_INFO ei;
- ZeroMemory(&ei, sizeof(ei));
- // Set our Extract or Test flag.
- ei.fExtract = fExtract;
- // Get the number of selected items and make sure we have at least one item.
- if ((ei.dwFileCount = ListView_GetSelectedCount(g_hWndList)) <= 0) {
- return;
- }
- // If we are not extracting/testing all, then create and buffer large enough to
- // hold the file list for all the selected files.
- if ((int)ei.dwFileCount != ListView_GetItemCount(g_hWndList)) {
- ei.szFileList = new LPSTR[ei.dwFileCount + 1];
- if (!ei.szFileList) {
- MessageBox(g_hWndMain, GetZipErrorString(PK_MEM), g_szAppName,
- MB_ICONERROR | MB_OK);
- return;
- }
- }
- ei.dwFileCount = 0;
- ei.dwByteCount = 0;
- LV_ITEM lvi;
- ZeroMemory(&lvi, sizeof(lvi));
- lvi.mask = LVIF_PARAM;
- lvi.iItem = -1;
- // Walk through all the selected files to build our counts and set our file
- // list pointers into our FILE_NODE paths for each selected item.
- while ((lvi.iItem = ListView_GetNextItem(g_hWndList, lvi.iItem, LVNI_SELECTED)) >= 0) {
- ListView_GetItem(g_hWndList, &lvi);
- if (ei.szFileList) {
- ei.szFileList[ei.dwFileCount] = ((FILE_NODE*)lvi.lParam)->szPathAndMethod;
- }
- ei.dwFileCount++;
- ei.dwByteCount += ((FILE_NODE*)lvi.lParam)->dwSize;
- }
- if (ei.szFileList) {
- ei.szFileList[ei.dwFileCount] = NULL;
- }
- // If we are extracting, display the extract dialog to query for parameters.
- if (!fExtract || (DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_EXTRACT), g_hWndMain,
- (DLGPROC)DlgProcExtractOrTest, (LPARAM)&ei) == IDOK))
- {
- // Display our progress dialog and do the extraction/test.
- DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_EXTRACT_PROGRESS), g_hWndMain,
- (DLGPROC)DlgProcExtractProgress, (LPARAM)&ei);
- }
- // Free our file list buffer if we created one.
- if (ei.szFileList) {
- delete[] ei.szFileList;
- }
- }
- //******************************************************************************
- BOOL CALLBACK DlgProcExtractOrTest(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- static EXTRACT_INFO *pei;
- TCHAR szPath[_MAX_PATH];
- switch (uMsg) {
- case WM_INITDIALOG:
- // Store our extract information structure.
- pei = (EXTRACT_INFO*)lParam;
- // Load our settings.
- pei->fRestorePaths = GetOptionInt(TEXT("RestorePaths"), TRUE);
- pei->overwriteMode = (OVERWRITE_MODE)GetOptionInt(TEXT("OverwriteMode"), OM_PROMPT);
- // Load and set our path string.
- GetOptionString(TEXT("ExtractToDirectory"), TEXT("\"), szPath, sizeof(szPath));
- SetDlgItemText(hDlg, IDC_EXTRACT_TO, szPath);
- // Set the state of all the controls.
- SetDlgItemText(hDlg, IDC_FILE_COUNT, FormatValue(szPath, pei->dwFileCount));
- SetDlgItemText(hDlg, IDC_BYTE_COUNT, FormatValue(szPath, pei->dwByteCount));
- CheckDlgButton(hDlg, IDC_RESTORE_PATHS, pei->fRestorePaths);
- CheckDlgButton(hDlg, IDC_OVERWRITE_PROMPT, pei->overwriteMode == OM_PROMPT);
- CheckDlgButton(hDlg, IDC_OVERWRITE_NEWER, pei->overwriteMode == OM_NEWER);
- CheckDlgButton(hDlg, IDC_OVERWRITE_ALWAYS, pei->overwriteMode == OM_ALWAYS);
- CheckDlgButton(hDlg, IDC_OVERWRITE_NEVER, pei->overwriteMode == OM_NEVER);
- // Limit our edit control to max path.
- SendDlgItemMessage(hDlg, IDC_EXTRACT_TO, EM_LIMITTEXT, sizeof(szPath) - 1, 0);
- // Center our dialog.
- CenterWindow(hDlg);
- return TRUE;
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDOK:
- // Force us to read and validate the extract to directory.
- SendMessage(hDlg, WM_COMMAND, MAKELONG(IDC_EXTRACT_TO, EN_KILLFOCUS), 0);
- // Get our current path string.
- GetDlgItemText(hDlg, IDC_EXTRACT_TO, szPath, countof(szPath));
- // Verify our "extract to" path is valid.
- if (!SetExtractToDirectory(szPath)) {
- MessageBox(hDlg, TEXT("The directory you entered is invalid or does not exist."),
- g_szAppName, MB_ICONERROR | MB_OK);
- SetFocus(GetDlgItem(hDlg, IDC_EXTRACT_TO));
- return FALSE;
- }
- // Query other control values.
- pei->fRestorePaths = IsDlgButtonChecked(hDlg, IDC_RESTORE_PATHS);
- pei->overwriteMode =
- IsDlgButtonChecked(hDlg, IDC_OVERWRITE_NEWER) ? OM_NEWER :
- IsDlgButtonChecked(hDlg, IDC_OVERWRITE_ALWAYS) ? OM_ALWAYS :
- IsDlgButtonChecked(hDlg, IDC_OVERWRITE_NEVER) ? OM_NEVER : OM_PROMPT;
- // Write our settings.
- WriteOptionInt(TEXT("RestorePaths"), pei->fRestorePaths);
- WriteOptionInt(TEXT("OverwriteMode"), pei->overwriteMode);
- WriteOptionString(TEXT("ExtractToDirectory"), szPath);
- // Fall through to IDCANCEL
- case IDCANCEL:
- EndDialog(hDlg, LOWORD(wParam));
- return FALSE;
- case IDC_EXTRACT_TO:
- // Make sure the path ends in a wack ().
- if (HIWORD(wParam) == EN_KILLFOCUS) {
- GetDlgItemText(hDlg, IDC_EXTRACT_TO, szPath, countof(szPath));
- int length = _tcslen(szPath);
- if ((length == 0) || szPath[length - 1] != TEXT('\')) {
- szPath[length ] = TEXT('\');
- szPath[length + 1] = TEXT(' ');
- SetDlgItemText(hDlg, IDC_EXTRACT_TO, szPath);
- }
- }
- return FALSE;
- case IDC_BROWSE:
- GetDlgItemText(hDlg, IDC_EXTRACT_TO, szPath, countof(szPath));
- if (FolderBrowser(szPath, countof(szPath))) {
- SetDlgItemText(hDlg, IDC_EXTRACT_TO, szPath);
- }
- return FALSE;
- }
- return FALSE;
- }
- return FALSE;
- }
- //******************************************************************************
- //***** Folder Browsing Dialog Functions
- //******************************************************************************
- BOOL FolderBrowser(LPTSTR szPath, DWORD dwLength) {
- #ifdef _WIN32_WCE
- // On Windows CE, we use a common save-as dialog to query the diretory. We
- // display the dialog in this function, and then we sublass it. Our subclass
- // functions tweaks the dialog a bit and and returns the path.
- ForwardSlashesToBackSlashesW(szPath);
- TCHAR szInitialDir[_MAX_PATH];
- _tcscpy(szInitialDir, szPath);
- // Remove trailing wacks from path - The common dialog doesn't like them.
- int length = _tcslen(szInitialDir);
- while ((length > 0) && (szInitialDir[length - 1] == TEXT('\'))) {
- szInitialDir[--length] = TEXT(' ');
- }
- // Set up the parameters for our save-as dialog.
- OPENFILENAME ofn;
- ZeroMemory(&ofn, sizeof(ofn));
- ofn.lStructSize = sizeof(ofn);
- ofn.hwndOwner = g_hWndMain;
- ofn.hInstance = g_hInst;
- ofn.lpstrFilter = TEXT("