1 // MenuPage.cpp 2 3 #include "StdAfx.h" 4 5 #include "../Common/ZipRegistry.h" 6 7 #include "../../../Windows/DLL.h" 8 #include "../../../Windows/ErrorMsg.h" 9 #include "../../../Windows/FileFind.h" 10 11 #include "../Explorer/ContextMenuFlags.h" 12 #include "../Explorer/RegistryContextMenu.h" 13 #include "../Explorer/resource.h" 14 15 #include "../FileManager/PropertyNameRes.h" 16 17 #include "../GUI/ExtractDialogRes.h" 18 19 #include "FormatUtils.h" 20 #include "HelpUtils.h" 21 #include "LangUtils.h" 22 #include "MenuPage.h" 23 #include "MenuPageRes.h" 24 25 26 using namespace NWindows; 27 using namespace NContextMenuFlags; 28 29 #ifdef Z7_LANG 30 static const UInt32 kLangIDs[] = 31 { 32 IDX_SYSTEM_INTEGRATE_TO_MENU, 33 IDX_SYSTEM_CASCADED_MENU, 34 IDX_SYSTEM_ICON_IN_MENU, 35 IDX_EXTRACT_ELIM_DUP, 36 IDT_SYSTEM_ZONE, 37 IDT_SYSTEM_CONTEXT_MENU_ITEMS 38 }; 39 #endif 40 41 #define kMenuTopic "fm/options.htm#sevenZip" 42 43 struct CContextMenuItem 44 { 45 unsigned ControlID; 46 UInt32 Flag; 47 }; 48 49 static const CContextMenuItem kMenuItems[] = 50 { 51 { IDS_CONTEXT_OPEN, kOpen }, 52 { IDS_CONTEXT_OPEN, kOpenAs }, 53 { IDS_CONTEXT_EXTRACT, kExtract }, 54 { IDS_CONTEXT_EXTRACT_HERE, kExtractHere }, 55 { IDS_CONTEXT_EXTRACT_TO, kExtractTo }, 56 57 { IDS_CONTEXT_TEST, kTest }, 58 59 { IDS_CONTEXT_COMPRESS, kCompress }, 60 { IDS_CONTEXT_COMPRESS_TO, kCompressTo7z }, 61 { IDS_CONTEXT_COMPRESS_TO, kCompressToZip }, 62 63 #ifndef UNDER_CE 64 { IDS_CONTEXT_COMPRESS_EMAIL, kCompressEmail }, 65 { IDS_CONTEXT_COMPRESS_TO_EMAIL, kCompressTo7zEmail }, 66 { IDS_CONTEXT_COMPRESS_TO_EMAIL, kCompressToZipEmail }, 67 #endif 68 69 { IDS_PROP_CHECKSUM, kCRC }, 70 { IDS_PROP_CHECKSUM, kCRC_Cascaded }, 71 }; 72 73 74 #if !defined(_WIN64) 75 extern bool g_Is_Wow64; 76 #endif 77 78 #ifndef KEY_WOW64_64KEY 79 #define KEY_WOW64_64KEY (0x0100) 80 #endif 81 82 #ifndef KEY_WOW64_32KEY 83 #define KEY_WOW64_32KEY (0x0200) 84 #endif 85 86 LoadLang_Spec(UString & s,UInt32 id,const char * eng)87 static void LoadLang_Spec(UString &s, UInt32 id, const char *eng) 88 { 89 LangString(id, s); 90 if (s.IsEmpty()) 91 s = eng; 92 s.RemoveChar(L'&'); 93 } 94 95 OnInit()96 bool CMenuPage::OnInit() 97 { 98 _initMode = true; 99 100 Clear_MenuChanged(); 101 102 #ifdef Z7_LANG 103 LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs)); 104 #endif 105 106 #ifdef UNDER_CE 107 108 HideItem(IDX_SYSTEM_INTEGRATE_TO_MENU); 109 HideItem(IDX_SYSTEM_INTEGRATE_TO_MENU_2); 110 111 #else 112 113 { 114 UString s; 115 { 116 CWindow window(GetItem(IDX_SYSTEM_INTEGRATE_TO_MENU)); 117 window.GetText(s); 118 } 119 UString bit64 = LangString(IDS_PROP_BIT64); 120 if (bit64.IsEmpty()) 121 bit64 = "64-bit"; 122 #ifdef _WIN64 123 bit64.Replace(L"64", L"32"); 124 #endif 125 s.Add_Space(); 126 s.Add_Char('('); 127 s += bit64; 128 s.Add_Char(')'); 129 SetItemText(IDX_SYSTEM_INTEGRATE_TO_MENU_2, s); 130 } 131 132 const FString prefix = NDLL::GetModuleDirPrefix(); 133 134 _dlls[0].ctrl = IDX_SYSTEM_INTEGRATE_TO_MENU; 135 _dlls[1].ctrl = IDX_SYSTEM_INTEGRATE_TO_MENU_2; 136 137 _dlls[0].wow = 0; 138 _dlls[1].wow = 139 #ifdef _WIN64 140 KEY_WOW64_32KEY 141 #else 142 KEY_WOW64_64KEY 143 #endif 144 ; 145 146 for (unsigned d = 0; d < 2; d++) 147 { 148 CShellDll &dll = _dlls[d]; 149 150 dll.wasChanged = false; 151 152 #ifndef _WIN64 153 if (d != 0 && !g_Is_Wow64) 154 { 155 HideItem(dll.ctrl); 156 continue; 157 } 158 #endif 159 160 FString &path = dll.Path; 161 path = prefix; 162 path += (d == 0 ? "7-zip.dll" : 163 #ifdef _WIN64 164 "7-zip32.dll" 165 #else 166 "7-zip64.dll" 167 #endif 168 ); 169 170 171 if (!NFile::NFind::DoesFileExist_Raw(path)) 172 { 173 path.Empty(); 174 EnableItem(dll.ctrl, false); 175 } 176 else 177 { 178 dll.prevValue = CheckContextMenuHandler(fs2us(path), dll.wow); 179 CheckButton(dll.ctrl, dll.prevValue); 180 } 181 } 182 183 #endif 184 185 186 CContextMenuInfo ci; 187 ci.Load(); 188 189 CheckButton(IDX_SYSTEM_CASCADED_MENU, ci.Cascaded.Val); 190 CheckButton(IDX_SYSTEM_ICON_IN_MENU, ci.MenuIcons.Val); 191 CheckButton(IDX_EXTRACT_ELIM_DUP, ci.ElimDup.Val); 192 193 _listView.Attach(GetItem(IDL_SYSTEM_OPTIONS)); 194 _zoneCombo.Attach(GetItem(IDC_SYSTEM_ZONE)); 195 196 { 197 unsigned wz = ci.WriteZone; 198 if (wz == (UInt32)(Int32)-1) 199 wz = 0; 200 for (unsigned i = 0; i <= 3; i++) 201 { 202 unsigned val = i; 203 UString s; 204 if (i == 3) 205 { 206 if (wz < 3) 207 break; 208 val = wz; 209 } 210 else 211 { 212 #define MY_IDYES 406 213 #define MY_IDNO 407 214 if (i == 0) 215 LoadLang_Spec(s, MY_IDNO, "No"); 216 else if (i == 1) 217 LoadLang_Spec(s, MY_IDYES, "Yes"); 218 else 219 LangString(IDT_ZONE_FOR_OFFICE, s); 220 } 221 if (s.IsEmpty()) 222 s.Add_UInt32(val); 223 if (i == 0) 224 s.Insert(0, L"* "); 225 const int index = (int)_zoneCombo.AddString(s); 226 _zoneCombo.SetItemData(index, (LPARAM)val); 227 if (val == wz) 228 _zoneCombo.SetCurSel(index); 229 } 230 } 231 232 233 const UInt32 newFlags = LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT; 234 _listView.SetExtendedListViewStyle(newFlags, newFlags); 235 236 _listView.InsertColumn(0, L"", 200); 237 238 for (unsigned i = 0; i < Z7_ARRAY_SIZE(kMenuItems); i++) 239 { 240 const CContextMenuItem &menuItem = kMenuItems[i]; 241 242 UString s = LangString(menuItem.ControlID); 243 if (menuItem.Flag == kCRC) 244 s = "CRC SHA"; 245 else if (menuItem.Flag == kCRC_Cascaded) 246 s = "7-Zip > CRC SHA"; 247 if (menuItem.Flag == kOpenAs 248 || menuItem.Flag == kCRC 249 || menuItem.Flag == kCRC_Cascaded) 250 s += " >"; 251 252 switch (menuItem.ControlID) 253 { 254 case IDS_CONTEXT_EXTRACT_TO: 255 { 256 s = MyFormatNew(s, LangString(IDS_CONTEXT_FOLDER)); 257 break; 258 } 259 case IDS_CONTEXT_COMPRESS_TO: 260 case IDS_CONTEXT_COMPRESS_TO_EMAIL: 261 { 262 UString s2 = LangString(IDS_CONTEXT_ARCHIVE); 263 switch (menuItem.Flag) 264 { 265 case kCompressTo7z: 266 case kCompressTo7zEmail: 267 s2 += (".7z"); 268 break; 269 case kCompressToZip: 270 case kCompressToZipEmail: 271 s2 += (".zip"); 272 break; 273 } 274 s = MyFormatNew(s, s2); 275 break; 276 } 277 } 278 279 const int itemIndex = _listView.InsertItem(i, s); 280 _listView.SetCheckState((unsigned)itemIndex, ((ci.Flags & menuItem.Flag) != 0)); 281 } 282 283 _listView.SetColumnWidthAuto(0); 284 _initMode = false; 285 286 return CPropertyPage::OnInit(); 287 } 288 289 290 #ifndef UNDER_CE 291 ShowMenuErrorMessage(const wchar_t * m,HWND hwnd)292 static void ShowMenuErrorMessage(const wchar_t *m, HWND hwnd) 293 { 294 MessageBoxW(hwnd, m, L"7-Zip", MB_ICONERROR); 295 } 296 297 #endif 298 299 OnApply()300 LONG CMenuPage::OnApply() 301 { 302 #ifndef UNDER_CE 303 304 for (unsigned d = 2; d != 0;) 305 { 306 d--; 307 CShellDll &dll = _dlls[d]; 308 if (dll.wasChanged && !dll.Path.IsEmpty()) 309 { 310 const bool newVal = IsButtonCheckedBool(dll.ctrl); 311 const LONG res = SetContextMenuHandler(newVal, fs2us(dll.Path), dll.wow); 312 if (res != ERROR_SUCCESS && (dll.prevValue != newVal || newVal)) 313 ShowMenuErrorMessage(NError::MyFormatMessage(res), *this); 314 dll.prevValue = CheckContextMenuHandler(fs2us(dll.Path), dll.wow); 315 CheckButton(dll.ctrl, dll.prevValue); 316 dll.wasChanged = false; 317 } 318 } 319 320 #endif 321 322 if (_cascaded_Changed 323 || _menuIcons_Changed 324 || _elimDup_Changed 325 || _writeZone_Changed 326 || _flags_Changed) 327 { 328 CContextMenuInfo ci; 329 ci.Cascaded.Val = IsButtonCheckedBool(IDX_SYSTEM_CASCADED_MENU); 330 ci.Cascaded.Def = _cascaded_Changed; 331 332 ci.MenuIcons.Val = IsButtonCheckedBool(IDX_SYSTEM_ICON_IN_MENU); 333 ci.MenuIcons.Def = _menuIcons_Changed; 334 335 ci.ElimDup.Val = IsButtonCheckedBool(IDX_EXTRACT_ELIM_DUP); 336 ci.ElimDup.Def = _elimDup_Changed; 337 338 { 339 int zoneIndex = (int)_zoneCombo.GetItemData_of_CurSel(); 340 if (zoneIndex <= 0) 341 zoneIndex = -1; 342 ci.WriteZone = (UInt32)(Int32)zoneIndex; 343 } 344 345 ci.Flags = 0; 346 347 for (unsigned i = 0; i < Z7_ARRAY_SIZE(kMenuItems); i++) 348 if (_listView.GetCheckState(i)) 349 ci.Flags |= kMenuItems[i].Flag; 350 351 ci.Flags_Def = _flags_Changed; 352 ci.Save(); 353 354 Clear_MenuChanged(); 355 } 356 357 // UnChanged(); 358 359 return PSNRET_NOERROR; 360 } 361 OnNotifyHelp()362 void CMenuPage::OnNotifyHelp() 363 { 364 ShowHelpWindow(kMenuTopic); 365 } 366 OnButtonClicked(unsigned buttonID,HWND buttonHWND)367 bool CMenuPage::OnButtonClicked(unsigned buttonID, HWND buttonHWND) 368 { 369 switch (buttonID) 370 { 371 #ifndef UNDER_CE 372 case IDX_SYSTEM_INTEGRATE_TO_MENU: 373 case IDX_SYSTEM_INTEGRATE_TO_MENU_2: 374 { 375 for (unsigned d = 0; d < 2; d++) 376 { 377 CShellDll &dll = _dlls[d]; 378 if (buttonID == dll.ctrl && !dll.Path.IsEmpty()) 379 dll.wasChanged = true; 380 } 381 break; 382 } 383 #endif 384 385 case IDX_SYSTEM_CASCADED_MENU: _cascaded_Changed = true; break; 386 case IDX_SYSTEM_ICON_IN_MENU: _menuIcons_Changed = true; break; 387 case IDX_EXTRACT_ELIM_DUP: _elimDup_Changed = true; break; 388 // case IDX_EXTRACT_WRITE_ZONE: _writeZone_Changed = true; break; 389 390 default: 391 return CPropertyPage::OnButtonClicked(buttonID, buttonHWND); 392 } 393 394 Changed(); 395 return true; 396 } 397 398 OnCommand(unsigned code,unsigned itemID,LPARAM param)399 bool CMenuPage::OnCommand(unsigned code, unsigned itemID, LPARAM param) 400 { 401 if (code == CBN_SELCHANGE && itemID == IDC_SYSTEM_ZONE) 402 { 403 _writeZone_Changed = true; 404 Changed(); 405 return true; 406 } 407 return CPropertyPage::OnCommand(code, itemID, param); 408 } 409 410 OnNotify(UINT controlID,LPNMHDR lParam)411 bool CMenuPage::OnNotify(UINT controlID, LPNMHDR lParam) 412 { 413 if (lParam->hwndFrom == HWND(_listView)) 414 { 415 switch (lParam->code) 416 { 417 case (LVN_ITEMCHANGED): 418 return OnItemChanged((const NMLISTVIEW *)lParam); 419 } 420 } 421 return CPropertyPage::OnNotify(controlID, lParam); 422 } 423 424 OnItemChanged(const NMLISTVIEW * info)425 bool CMenuPage::OnItemChanged(const NMLISTVIEW *info) 426 { 427 if (_initMode) 428 return true; 429 if ((info->uChanged & LVIF_STATE) != 0) 430 { 431 UINT oldState = info->uOldState & LVIS_STATEIMAGEMASK; 432 UINT newState = info->uNewState & LVIS_STATEIMAGEMASK; 433 if (oldState != newState) 434 { 435 _flags_Changed = true; 436 Changed(); 437 } 438 } 439 return true; 440 } 441