📄 winmain.cpp
字号:
TCHAR szPath[_MAX_PATH + 256]; // Set our extraction directory to our temporary directory. if (!SetExtractToDirectory((LPTSTR)g_szTempDir)) { // Create error message. Use szPath buffer because it is handy. _stprintf(szPath, TEXT("Could not create \"%s\"\n\n") TEXT("Most likely cause is that your drive is full."), g_szTempDir); // Display error message. MessageBox(g_hWndMain, szPath, g_szAppName, MB_ICONERROR | MB_OK); return; } // Create our single item file array. CHAR *argv[2] = { pfn->szPathAndMethod, NULL }; // Create a buffer to store the mapped name of the file. If the has to be // renamed to be compatible with our file system, then we need to know that // new name in order to open it correctly. CHAR szMappedPath[_MAX_PATH]; *szMappedPath = '\0'; // Configure our extract structure. EXTRACT_INFO ei; ZeroMemory(&ei, sizeof(ei)); ei.fExtract = TRUE; ei.dwFileCount = 1; ei.dwByteCount = pfn->dwSize; ei.szFileList = argv; ei.fRestorePaths = FALSE; ei.overwriteMode = OM_PROMPT; ei.szMappedPath = szMappedPath; // Clear our skipped flag and set our viewing flag. g_fSkipped = FALSE; g_fViewing = TRUE; // Display our progress dialog and do the extraction. DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_VIEW_PROGRESS), g_hWndMain, (DLGPROC)DlgProcViewProgress, (LPARAM)&ei); // Clear our viewing flag. g_fViewing = FALSE; // Check to see if the user skipped the file by aborting the decryption or // overwrite prompts. The only other case that causes us to skip a file // is when the user enters the incorrect password too many times. In this // case, IZ_BADPWD will be returned. if (g_fSkipped) { return; } if (ei.result == IZ_BADPWD) { MessageBox(g_hWndMain, TEXT("Password was incorrect. The file has been skipped."), g_szAppName, MB_ICONWARNING | MB_OK); return; } // Check to see if the extraction failed. if (ei.result != PK_OK) { if (ei.result == PK_ABORTED) { _tcscpy(szPath, GetZipErrorString(ei.result)); } else { // Create error message. Use szPath buffer because it is handy. _stprintf(szPath,#ifdef UNICODE TEXT("Could not extract \"%S\".\n\n%s\n\nTry using the Test or ")#else TEXT("Could not extract \"%s\".\n\n%s\n\nTry using the Test or ")#endif TEXT("Extract action on the file for more details."), *szMappedPath ? szMappedPath : pfn->szPathAndMethod, GetZipErrorString(ei.result)); } // Display error message. MessageBox(g_hWndMain, szPath, g_szAppName, MB_ICONERROR | MB_OK); // If we managed to create a bad file, then delete it. if (*szMappedPath) { MBSTOTSTR(szPath, szMappedPath, countof(szPath)); SetFileAttributes(szPath, FILE_ATTRIBUTE_NORMAL); if (!DeleteFile(szPath)) { SetFileAttributes(szPath, FILE_ATTRIBUTE_READONLY); } } return; } // Convert the file name to UNICODE. MBSTOTSTR(szPath, szMappedPath, countof(szPath)); // Prepare to launch the file. SHELLEXECUTEINFO sei; ZeroMemory(&sei, sizeof(sei)); sei.cbSize = sizeof(sei); sei.hwnd = g_hWndMain; sei.lpDirectory = g_szTempDir; sei.nShow = SW_SHOWNORMAL;#ifdef _WIN32_WCE TCHAR szApp[_MAX_PATH]; // On Windows CE, there is no default file association dialog that appears // when ShellExecuteEx() is given an unknown file type. We check to see if // file is unknown, and display our own file association prompt. // Check our file image to see if this file has no associated viewer. if (lvi.iImage == IMAGE_GENERIC) { // Display our file association prompt dialog. if (IDOK != DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_VIEW_ASSOCIATION), g_hWndMain, (DLGPROC)DlgProcViewAssociation, (LPARAM)szApp)) { // If the user aborted the association prompt, then delete file and exit. SetFileAttributes(szPath, FILE_ATTRIBUTE_NORMAL); if (!DeleteFile(szPath)) { SetFileAttributes(szPath, FILE_ATTRIBUTE_READONLY); } return; } // Set the file to be the viewer app and the parameters to be the file. // Note: Some applications require that arguments with spaces be quoted, // while other applications choked when quotes we part of the filename. // In the end, it seems safer to leave the quotes off. sei.lpFile = szApp; sei.lpParameters = szPath; } else { sei.lpFile = szPath; }#else // On NT, ShellExecuteEx() will prompt user for association if needed. sei.lpFile = szPath;#endif // Launch the file. All errors will be displayed by ShellExecuteEx(). ShellExecuteEx(&sei);}//******************************************************************************void OnActionSelectAll() { for (int i = ListView_GetItemCount(g_hWndList) - 1; i >= 0; i--) { ListView_SetItemState(g_hWndList, i, LVIS_SELECTED, LVIS_SELECTED); }}//******************************************************************************void OnViewExpandedView() { // Toggle our expanded view option. g_fExpandedView = !g_fExpandedView; // Show or remove menu check and toolbar button press. CheckAllMenuItems(IDM_VIEW_EXPANDED_VIEW, g_fExpandedView); // Display the new columns. AddDeleteColumns(); // Re-sort if we just did away with out sort column. if (!g_fExpandedView && (g_sortColumn > 3)) { Sort(0, TRUE); } // Write our expanded view option to the registry. WriteOptionInt(TEXT("ExpandedView"), g_fExpandedView);}//******************************************************************************void OnHelp() { // Prepare to launch the help file. SHELLEXECUTEINFO sei; ZeroMemory(&sei, sizeof(sei)); sei.cbSize = sizeof(sei); sei.hwnd = g_hWndMain; sei.lpFile = g_szHelpFile; // Launch the file. ShellExecuteEx(&sei);}//******************************************************************************//***** Event Handlers for our List View//******************************************************************************void OnGetDispInfo(LV_DISPINFO *plvdi) { // Make sure we have the minimum amount of data to process this event. if ((plvdi->item.iItem < 0) || !plvdi->item.lParam || !plvdi->item.pszText) { return; } // Get a pointer to the file node for this item. FILE_NODE *pFile = (FILE_NODE*)plvdi->item.lParam; CHAR szBuffer[_MAX_PATH * 2]; switch (plvdi->item.iSubItem) { case 0: // Name // Copy the string to a new string while removing all non-printables. fnfilter(pFile->szPathAndMethod, (uch*)szBuffer); // Change all forward slashes to back slashes in the buffer ForwardSlashesToBackSlashesA(szBuffer); // Convert the string to UNICODE and store it in our list control. MBSTOTSTR(plvdi->item.pszText, szBuffer, plvdi->item.cchTextMax); return; case 1: // Size FormatValue(plvdi->item.pszText, pFile->dwSize); return; case 2: // Type MBSTOTSTR(plvdi->item.pszText, BuildTypeString(pFile, szBuffer), plvdi->item.cchTextMax); return; case 3: // Modified int hour; hour = (pFile->dwModified >> 6) & 0x001F; _stprintf(plvdi->item.pszText, TEXT("%u/%u/%u %u:%02u %cM"), (pFile->dwModified >> 16) & 0x000F, (pFile->dwModified >> 11) & 0x001F, ((pFile->dwModified >> 20) & 0x0FFF) % 100, (hour % 12) ? (hour % 12) : 12, pFile->dwModified & 0x003F, hour >= 12 ? 'P' : 'A'); return; case 4: // Attributes BuildAttributesString(plvdi->item.pszText, pFile->dwAttributes); return; case 5: // Compressed FormatValue(plvdi->item.pszText, pFile->dwCompressedSize); return; case 6: // Ratio int factor; factor = ratio(pFile->dwSize, pFile->dwCompressedSize); _stprintf(plvdi->item.pszText, TEXT("%d.%d%%"), factor / 10, ((factor < 0) ? -factor : factor) % 10); return; case 7: // Method MBSTOTSTR(plvdi->item.pszText, pFile->szPathAndMethod + strlen(pFile->szPathAndMethod) + 1, plvdi->item.cchTextMax); return; case 8: // CRC _stprintf(plvdi->item.pszText, TEXT("%08X"), pFile->dwCRC); return; case 9: // Comment MBSTOTSTR(plvdi->item.pszText, pFile->szComment ? pFile->szComment : "", plvdi->item.cchTextMax); return; }}//******************************************************************************void OnDeleteItem(NM_LISTVIEW *pnmlv) { if (pnmlv->lParam) { // Free any comment string associated with this item. if (((FILE_NODE*)pnmlv->lParam)->szComment) { delete[] (CHAR*)((FILE_NODE*)pnmlv->lParam)->szComment; } // Free the item itself. delete[] (LPBYTE)pnmlv->lParam; }}//******************************************************************************void OnItemChanged(NM_LISTVIEW *pnmlv) { int count = ListView_GetSelectedCount(pnmlv->hdr.hwndFrom); EnableAllMenuItems(IDM_FILE_PROPERTIES, count > 0); EnableAllMenuItems(IDM_ACTION_EXTRACT, count > 0); EnableAllMenuItems(IDM_ACTION_TEST, count > 0); EnableAllMenuItems(IDM_ACTION_VIEW, count == 1);}//******************************************************************************//***** List View Sort Functions//******************************************************************************void Sort(int sortColumn, BOOL fForce) { // Do not change the column header text if it is already correct. if (sortColumn != g_sortColumn) { TCHAR szColumn[32]; LV_COLUMN lvc; lvc.mask = LVCF_TEXT; lvc.pszText = szColumn; // Remove the '^' from the current sort column. if (g_sortColumn != -1) { _stprintf(szColumn, (g_columns[g_sortColumn].format == LVCFMT_LEFT) ? TEXT("%s ") : TEXT(" %s"), g_columns[g_sortColumn].szName); ListView_SetColumn(g_hWndList, g_sortColumn, &lvc); } // Set the new sort column. g_sortColumn = sortColumn; // Add the '^' to the new sort column. _stprintf(szColumn, (g_columns[g_sortColumn].format == LVCFMT_LEFT) ? TEXT("%s ^") : TEXT("^ %s"), g_columns[g_sortColumn].szName); ListView_SetColumn(g_hWndList, g_sortColumn, &lvc); // Sort the list by the new column. ListView_SortItems(g_hWndList, CompareFunc, g_sortColumn); } else if (fForce) { // Force the list to sort by the same column. ListView_SortItems(g_hWndList, CompareFunc, g_sortColumn); }}//******************************************************************************int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM sortColumn) { FILE_NODE *pFile1 = (FILE_NODE*)lParam1, *pFile2 = (FILE_NODE*)lParam2; TCHAR szBuffer1[8], szBuffer2[8]; // Return Negative value if the first item should precede the second. // Return Positive value if the first item should follow the second. // Return Zero if the two items are equivalent. int result = 0; // Compute the relationship based on the current sort column switch (sortColumn) { case 1: // Size - Smallest to Largest if (pFile1->dwSize != pFile2->dwSize) { result = ((pFile1->dwSize < pFile2->dwSize) ? -1 : 1); } break; case 2: { // Type - Volume Label's first, then directories, then files int f1 = (pFile1->dwAttributes & ZFILE_ATTRIBUTE_VOLUME) ? 1 : (pFile1->dwAttributes & FILE_ATTRIBUTE_DIRECTORY) ? 2 : 3; int f2 = (pFile2->dwAttributes & ZFILE_ATTRIBUTE_VOLUME) ? 1 : (pFile2->dwAttributes & FILE_ATTRIBUTE_DIRECTORY) ? 2 : 3; if ((f1 == 3) && (f2 == 3)) { CHAR szType1[128]; CHAR szType2[128]; result = _stricmp(BuildTypeString(pFile1, szType1), BuildTypeString(pFile2, szType2)); } else { result = f1 - f2; } break; } case 3: // Modified - Newest to Oldest
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -