xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/FileManager/MenuPage.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
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