1 // FM.cpp
2
3 #include "StdAfx.h"
4
5 #include "../../../Common/MyWindows.h"
6
7 #include <shlwapi.h>
8
9 #include "../../../../C/Alloc.h"
10
11 #include "../../../Common/StringConvert.h"
12 #include "../../../Common/StringToInt.h"
13
14 #include "../../../Windows/ErrorMsg.h"
15 #include "../../../Windows/MemoryLock.h"
16 #include "../../../Windows/NtCheck.h"
17 #include "../../../Windows/System.h"
18
19 #ifndef UNDER_CE
20 #include "../../../Windows/SecurityUtils.h"
21 #endif
22
23 #include "../GUI/ExtractRes.h"
24
25 #include "resource.h"
26
27 #include "App.h"
28 #include "FormatUtils.h"
29 #include "LangUtils.h"
30 #include "MyLoadMenu.h"
31 #include "Panel.h"
32 #include "RegistryUtils.h"
33 #include "StringUtils.h"
34 #include "ViewSettings.h"
35
36 using namespace NWindows;
37 using namespace NFile;
38 using namespace NFind;
39
40 #define MAX_LOADSTRING 100
41
42 #define MENU_HEIGHT 26
43
44 bool g_RAM_Size_Defined;
45 bool g_LargePagesMode = false;
46 bool g_OpenArchive = false;
47
48 static bool g_Maximized = false;
49
50 UInt64 g_RAM_Size;
51
52 #ifdef _WIN32
53 HINSTANCE g_hInstance;
54 #endif
55
56 HWND g_HWND;
57
58 static UString g_MainPath;
59 static UString g_ArcFormat;
60
61 // HRESULT LoadGlobalCodecs();
62 void FreeGlobalCodecs();
63
64 #ifndef UNDER_CE
65
66 DWORD g_ComCtl32Version;
67
GetDllVersion(LPCTSTR dllName)68 static DWORD GetDllVersion(LPCTSTR dllName)
69 {
70 DWORD dwVersion = 0;
71 HINSTANCE hinstDll = LoadLibrary(dllName);
72 if (hinstDll)
73 {
74 DLLGETVERSIONPROC pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstDll, "DllGetVersion");
75 if (pDllGetVersion)
76 {
77 DLLVERSIONINFO dvi;
78 ZeroMemory(&dvi, sizeof(dvi));
79 dvi.cbSize = sizeof(dvi);
80 HRESULT hr = (*pDllGetVersion)(&dvi);
81 if (SUCCEEDED(hr))
82 dwVersion = MAKELONG(dvi.dwMinorVersion, dvi.dwMajorVersion);
83 }
84 FreeLibrary(hinstDll);
85 }
86 return dwVersion;
87 }
88
89 #endif
90
91 bool g_IsSmallScreen = false;
92
93 bool g_LVN_ITEMACTIVATE_Support = true;
94 // LVN_ITEMACTIVATE replaces both NM_DBLCLK & NM_RETURN
95 // Windows 2000
96 // NT/98 + IE 3 (g_ComCtl32Version >= 4.70)
97
98
99 const int kNumDefaultPanels = 1;
100
101 const int kSplitterWidth = 4;
102 int kSplitterRateMax = 1 << 16;
103 int kPanelSizeMin = 120;
104
105 // bool OnMenuCommand(HWND hWnd, int id);
106
107 class CSplitterPos
108 {
109 int _ratio; // 10000 is max
110 int _pos;
111 int _fullWidth;
SetRatioFromPos(HWND hWnd)112 void SetRatioFromPos(HWND hWnd)
113 { _ratio = (_pos + kSplitterWidth / 2) * kSplitterRateMax /
114 MyMax(GetWidth(hWnd), 1); }
115 public:
GetPos() const116 int GetPos() const
117 { return _pos; }
GetWidth(HWND hWnd) const118 int GetWidth(HWND hWnd) const
119 {
120 RECT rect;
121 ::GetClientRect(hWnd, &rect);
122 return rect.right;
123 }
SetRatio(HWND hWnd,int aRatio)124 void SetRatio(HWND hWnd, int aRatio)
125 {
126 _ratio = aRatio;
127 SetPosFromRatio(hWnd);
128 }
SetPosPure(HWND hWnd,int pos)129 void SetPosPure(HWND hWnd, int pos)
130 {
131 int posMax = GetWidth(hWnd) - kSplitterWidth;
132 if (posMax < kPanelSizeMin * 2)
133 pos = posMax / 2;
134 else
135 {
136 if (pos > posMax - kPanelSizeMin)
137 pos = posMax - kPanelSizeMin;
138 else if (pos < kPanelSizeMin)
139 pos = kPanelSizeMin;
140 }
141 _pos = pos;
142 }
SetPos(HWND hWnd,int pos)143 void SetPos(HWND hWnd, int pos)
144 {
145 _fullWidth = GetWidth(hWnd);
146 SetPosPure(hWnd, pos);
147 SetRatioFromPos(hWnd);
148 }
SetPosFromRatio(HWND hWnd)149 void SetPosFromRatio(HWND hWnd)
150 {
151 int fullWidth = GetWidth(hWnd);
152 if (_fullWidth != fullWidth && fullWidth != 0)
153 {
154 _fullWidth = fullWidth;
155 SetPosPure(hWnd, GetWidth(hWnd) * _ratio / kSplitterRateMax - kSplitterWidth / 2);
156 }
157 }
158 };
159
160 static bool g_CanChangeSplitter = false;
161 static UInt32 g_SplitterPos = 0;
162 static CSplitterPos g_Splitter;
163 static bool g_PanelsInfoDefined = false;
164 static bool g_WindowWasCreated = false;
165
166 static int g_StartCaptureMousePos;
167 static int g_StartCaptureSplitterPos;
168
169 CApp g_App;
170
171 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
172
173 static const wchar_t * const kWindowClass = L"FM";
174
175 #ifdef UNDER_CE
176 #define WS_OVERLAPPEDWINDOW ( \
177 WS_OVERLAPPED | \
178 WS_CAPTION | \
179 WS_SYSMENU | \
180 WS_THICKFRAME | \
181 WS_MINIMIZEBOX | \
182 WS_MAXIMIZEBOX)
183 #endif
184
185 // FUNCTION: InitInstance(HANDLE, int)
InitInstance(int nCmdShow)186 static BOOL InitInstance(int nCmdShow)
187 {
188 CWindow wnd;
189
190 // LoadString(hInstance, IDS_CLASS, windowClass, MAX_LOADSTRING);
191
192 UString title ("7-Zip"); // LangString(IDS_APP_TITLE, 0x03000000);
193
194 /*
195 //If it is already running, then focus on the window
196 hWnd = FindWindow(windowClass, title);
197 if (hWnd)
198 {
199 SetForegroundWindow ((HWND) (((DWORD)hWnd) | 0x01));
200 return 0;
201 }
202 */
203
204 WNDCLASSW wc;
205
206 // wc.style = CS_HREDRAW | CS_VREDRAW;
207 wc.style = 0;
208 wc.lpfnWndProc = (WNDPROC) WndProc;
209 wc.cbClsExtra = 0;
210 wc.cbWndExtra = 0;
211 wc.hInstance = g_hInstance;
212 wc.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_ICON));
213
214 // wc.hCursor = LoadCursor (NULL, IDC_ARROW);
215 wc.hCursor = ::LoadCursor(0, IDC_SIZEWE);
216 // wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
217 wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
218
219 wc.lpszMenuName =
220 #ifdef UNDER_CE
221 0
222 #else
223 MAKEINTRESOURCEW(IDM_MENU)
224 #endif
225 ;
226
227 wc.lpszClassName = kWindowClass;
228
229 MyRegisterClass(&wc);
230
231 // RECT rect;
232 // GetClientRect(hWnd, &rect);
233
234 DWORD style = WS_OVERLAPPEDWINDOW;
235 // DWORD style = 0;
236
237 CWindowInfo info;
238 info.maximized = false;
239 int x, y, xSize, ySize;
240 x = y = xSize = ySize = CW_USEDEFAULT;
241 bool windowPosIsRead;
242 info.Read(windowPosIsRead, g_PanelsInfoDefined);
243
244 if (windowPosIsRead)
245 {
246 x = info.rect.left;
247 y = info.rect.top;
248
249 xSize = RECT_SIZE_X(info.rect);
250 ySize = RECT_SIZE_Y(info.rect);
251 }
252
253
254 if (g_PanelsInfoDefined)
255 {
256 g_SplitterPos = info.splitterPos;
257 if (info.numPanels < 1 || info.numPanels > 2)
258 info.numPanels = kNumDefaultPanels;
259 if (info.currentPanel >= 2)
260 info.currentPanel = 0;
261 }
262 else
263 {
264 info.numPanels = kNumDefaultPanels;
265 info.currentPanel = 0;
266 }
267
268 g_App.NumPanels = info.numPanels;
269 g_App.LastFocusedPanel = info.currentPanel;
270
271 if (!wnd.Create(kWindowClass, title, style,
272 x, y, xSize, ySize, NULL, NULL, g_hInstance, NULL))
273 return FALSE;
274
275 if (nCmdShow == SW_SHOWNORMAL ||
276 nCmdShow == SW_SHOW
277 #ifndef UNDER_CE
278 || nCmdShow == SW_SHOWDEFAULT
279 #endif
280 )
281 {
282 if (info.maximized)
283 nCmdShow = SW_SHOWMAXIMIZED;
284 else
285 nCmdShow = SW_SHOWNORMAL;
286 }
287
288 if (nCmdShow == SW_SHOWMAXIMIZED)
289 g_Maximized = true;
290
291 #ifndef UNDER_CE
292 WINDOWPLACEMENT placement;
293 placement.length = sizeof(placement);
294 if (wnd.GetPlacement(&placement))
295 {
296 if (windowPosIsRead)
297 placement.rcNormalPosition = info.rect;
298 placement.showCmd = nCmdShow;
299 wnd.SetPlacement(&placement);
300 }
301 else
302 #endif
303 wnd.Show(nCmdShow);
304
305 return TRUE;
306 }
307
308 /*
309 static void GetCommands(const UString &aCommandLine, UString &aCommands)
310 {
311 UString aProgramName;
312 aCommands.Empty();
313 bool aQuoteMode = false;
314 for (int i = 0; i < aCommandLine.Length(); i++)
315 {
316 wchar_t aChar = aCommandLine[i];
317 if (aChar == L'\"')
318 aQuoteMode = !aQuoteMode;
319 else if (aChar == L' ' && !aQuoteMode)
320 {
321 if (!aQuoteMode)
322 {
323 i++;
324 break;
325 }
326 }
327 else
328 aProgramName += aChar;
329 }
330 aCommands = aCommandLine.Ptr(i);
331 }
332 */
333
334 #if defined(_WIN32) && !defined(_WIN64) && !defined(UNDER_CE)
335
336 bool g_Is_Wow64;
337
338 typedef BOOL (WINAPI *Func_IsWow64Process)(HANDLE, PBOOL);
339
Set_Wow64()340 static void Set_Wow64()
341 {
342 g_Is_Wow64 = false;
343 Func_IsWow64Process fnIsWow64Process = (Func_IsWow64Process)GetProcAddress(
344 GetModuleHandleA("kernel32.dll"), "IsWow64Process");
345 if (fnIsWow64Process)
346 {
347 BOOL isWow;
348 if (fnIsWow64Process(GetCurrentProcess(), &isWow))
349 g_Is_Wow64 = (isWow != FALSE);
350 }
351 }
352
353 #endif
354
355
IsLargePageSupported()356 bool IsLargePageSupported()
357 {
358 #ifdef _WIN64
359 return true;
360 #else
361 OSVERSIONINFO vi;
362 vi.dwOSVersionInfoSize = sizeof(vi);
363 if (!::GetVersionEx(&vi))
364 return false;
365 if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT)
366 return false;
367 if (vi.dwMajorVersion < 5) return false;
368 if (vi.dwMajorVersion > 5) return true;
369 if (vi.dwMinorVersion < 1) return false;
370 if (vi.dwMinorVersion > 1) return true;
371 // return g_Is_Wow64;
372 return false;
373 #endif
374 }
375
376 #ifndef UNDER_CE
377
SetMemoryLock()378 static void SetMemoryLock()
379 {
380 if (!IsLargePageSupported())
381 return;
382 // if (ReadLockMemoryAdd())
383 NSecurity::AddLockMemoryPrivilege();
384
385 if (ReadLockMemoryEnable())
386 {
387 // note: child processes can inherit that Privilege
388 g_LargePagesMode = NSecurity::EnablePrivilege_LockMemory();
389 }
390 }
391
392 bool g_SymLink_Supported = false;
393
Set_SymLink_Supported()394 static void Set_SymLink_Supported()
395 {
396 g_SymLink_Supported = false;
397 OSVERSIONINFO vi;
398 vi.dwOSVersionInfoSize = sizeof(vi);
399 if (!::GetVersionEx(&vi))
400 return;
401 if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT || vi.dwMajorVersion < 6)
402 return;
403 g_SymLink_Supported = true;
404 // if (g_SymLink_Supported)
405 {
406 NSecurity::EnablePrivilege_SymLink();
407 }
408 }
409
410 #endif
411
412 /*
413 static const int kNumSwitches = 1;
414
415 namespace NKey {
416 enum Enum
417 {
418 kOpenArachive = 0
419 };
420
421 }
422
423 static const CSwitchForm kSwitchForms[kNumSwitches] =
424 {
425 { L"SOA", NSwitchType::kSimple, false },
426 };
427 */
428
429 // int APIENTRY WinMain2(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, LPSTR /* lpCmdLine */, int /* nCmdShow */);
430
ErrorMessage(const wchar_t * s)431 static void ErrorMessage(const wchar_t *s)
432 {
433 MessageBoxW(0, s, L"7-Zip", MB_ICONERROR);
434 }
435
ErrorMessage(const char * s)436 static void ErrorMessage(const char *s)
437 {
438 ErrorMessage(GetUnicodeString(s));
439 }
440
441
442 #define NT_CHECK_FAIL_ACTION ErrorMessage("Unsupported Windows version"); return 1;
443
WinMain2(int nCmdShow)444 static int WINAPI WinMain2(int nCmdShow)
445 {
446 g_RAM_Size_Defined = NSystem::GetRamSize(g_RAM_Size);
447
448 #ifdef _WIN32
449
450 /*
451 #ifndef _WIN64
452 #ifndef UNDER_CE
453 {
454 HMODULE hMod = GetModuleHandle("Kernel32.dll");
455 if (hMod)
456 {
457 typedef BOOL (WINAPI *PSETDEP)(DWORD);
458 #define MY_PROCESS_DEP_ENABLE 1
459 PSETDEP procSet = (PSETDEP)GetProcAddress(hMod,"SetProcessDEPPolicy");
460 if (procSet)
461 procSet(MY_PROCESS_DEP_ENABLE);
462
463 typedef BOOL (WINAPI *HSI)(HANDLE, HEAP_INFORMATION_CLASS ,PVOID, SIZE_T);
464 HSI hsi = (HSI)GetProcAddress(hMod, "HeapSetInformation");
465 #define MY_HeapEnableTerminationOnCorruption ((HEAP_INFORMATION_CLASS)1)
466 if (hsi)
467 hsi(NULL, MY_HeapEnableTerminationOnCorruption, NULL, 0);
468 }
469 }
470 #endif
471 #endif
472 */
473
474 NT_CHECK
475 SetLargePageSize();
476
477 #endif
478
479 LoadLangOneTime();
480
481 InitCommonControls();
482
483 #ifndef UNDER_CE
484 g_ComCtl32Version = ::GetDllVersion(TEXT("comctl32.dll"));
485 g_LVN_ITEMACTIVATE_Support = (g_ComCtl32Version >= MAKELONG(71, 4));
486 #endif
487
488 #if defined(_WIN32) && !defined(_WIN64) && !defined(UNDER_CE)
489 Set_Wow64();
490 #endif
491
492
493 g_IsSmallScreen = !NWindows::NControl::IsDialogSizeOK(200, 200);
494
495 // OleInitialize is required for drag and drop.
496 #ifndef UNDER_CE
497 OleInitialize(NULL);
498 #endif
499 // Maybe needs CoInitializeEx also ?
500 // NCOM::CComInitializer comInitializer;
501
502 UString commandsString;
503 // MessageBoxW(0, GetCommandLineW(), L"", 0);
504
505 #ifdef UNDER_CE
506 commandsString = GetCommandLineW();
507 #else
508 UString programString;
509 SplitStringToTwoStrings(GetCommandLineW(), programString, commandsString);
510 #endif
511
512 commandsString.Trim();
513 UString paramString, tailString;
514 SplitStringToTwoStrings(commandsString, paramString, tailString);
515 paramString.Trim();
516 tailString.Trim();
517 if (tailString.IsPrefixedBy(L"-t"))
518 g_ArcFormat = tailString.Ptr(2);
519
520 /*
521 UStringVector switches;
522 for (;;)
523 {
524 if (tailString.IsEmpty())
525 break;
526 UString s1, s2;
527 SplitStringToTwoStrings(tailString, s1, s2);
528 if (s2.IsEmpty())
529 {
530 tailString.Trim();
531 switches.Add(tailString);
532 break;
533 }
534 s1.Trim();
535 switches.Add(s1);
536 tailString = s2;
537 }
538
539 FOR_VECTOR(i, switches)
540 {
541 const UString &sw = switches[i];
542 if (sw.IsPrefixedBy(L"-t"))
543 g_ArcFormat = sw.Ptr(2);
544 //
545 else if (sw.IsPrefixedBy(L"-stp"))
546 {
547 const wchar_t *end;
548 UInt32 val = ConvertStringToUInt32(sw.Ptr(4), &end);
549 if (*end != 0)
550 throw 111;
551 g_TypeParseLevel = val;
552 }
553 else
554 //
555 throw 112;
556 }
557 */
558
559 if (!paramString.IsEmpty())
560 {
561 g_MainPath = paramString;
562 // return WinMain2(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
563
564 // MessageBoxW(0, paramString, L"", 0);
565 }
566 /*
567 UStringVector commandStrings;
568 NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
569 NCommandLineParser::CParser parser(kNumSwitches);
570 try
571 {
572 parser.ParseStrings(kSwitchForms, commandStrings);
573 const UStringVector &nonSwitchStrings = parser.NonSwitchStrings;
574 if (nonSwitchStrings.Size() > 1)
575 {
576 g_MainPath = nonSwitchStrings[1];
577 // g_OpenArchive = parser[NKey::kOpenArachive].ThereIs;
578 CFileInfoW fileInfo;
579 if (FindFile(g_MainPath, fileInfo))
580 {
581 if (!fileInfo.IsDir())
582 g_OpenArchive = true;
583 }
584 }
585 }
586 catch(...) { }
587 */
588
589
590 #if defined(_WIN32) && !defined(UNDER_CE)
591 SetMemoryLock();
592 Set_SymLink_Supported();
593 #endif
594
595 g_App.ReloadLang();
596
597 MSG msg;
598 if (!InitInstance (nCmdShow))
599 return FALSE;
600
601 // we will load Global_Codecs at first use instead.
602 /*
603 OutputDebugStringW(L"Before LoadGlobalCodecs");
604 LoadGlobalCodecs();
605 OutputDebugStringW(L"After LoadGlobalCodecs");
606 */
607
608 #ifndef _UNICODE
609 if (g_IsNT)
610 {
611 HACCEL hAccels = LoadAcceleratorsW(g_hInstance, MAKEINTRESOURCEW(IDR_ACCELERATOR1));
612 while (GetMessageW(&msg, NULL, 0, 0))
613 {
614 if (TranslateAcceleratorW(g_HWND, hAccels, &msg) == 0)
615 {
616 TranslateMessage(&msg);
617 DispatchMessageW(&msg);
618 }
619 }
620 }
621 else
622 #endif
623 {
624 HACCEL hAccels = LoadAccelerators(g_hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1));
625 while (GetMessage(&msg, NULL, 0, 0))
626 {
627 if (TranslateAccelerator(g_HWND, hAccels, &msg) == 0)
628 {
629 // if (g_Hwnd != NULL || !IsDialogMessage(g_Hwnd, &msg))
630 // if (!IsDialogMessage(g_Hwnd, &msg))
631 TranslateMessage(&msg);
632 DispatchMessage(&msg);
633 }
634 }
635 }
636
637 // Destructor of g_CodecsReleaser can release DLLs.
638 // But we suppose that it's better to release DLLs here (before destructor).
639 FreeGlobalCodecs();
640
641 g_HWND = 0;
642 #ifndef UNDER_CE
643 OleUninitialize();
644 #endif
645 return (int)msg.wParam;
646 }
647
WinMain(HINSTANCE hInstance,HINSTANCE,LPWSTR,int nCmdShow)648 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
649 #ifdef UNDER_CE
650 LPWSTR
651 #else
652 LPSTR
653 #endif
654 /* lpCmdLine */, int nCmdShow)
655 {
656 g_hInstance = hInstance;
657
658 try
659 {
660 try
661 {
662 return WinMain2(nCmdShow);
663 }
664 catch (...)
665 {
666 g_ExitEventLauncher.Exit(true);
667 throw;
668 }
669 }
670 catch(const CNewException &)
671 {
672 ErrorMessage(LangString(IDS_MEM_ERROR));
673 return 1;
674 }
675 catch(const UString &s)
676 {
677 ErrorMessage(s);
678 return 1;
679 }
680 catch(const AString &s)
681 {
682 ErrorMessage(s.Ptr());
683 return 1;
684 }
685 catch(const wchar_t *s)
686 {
687 ErrorMessage(s);
688 return 1;
689 }
690 catch(const char *s)
691 {
692 ErrorMessage(s);
693 return 1;
694 }
695 catch(int v)
696 {
697 AString e ("Error: ");
698 e.Add_UInt32(v);
699 ErrorMessage(e);
700 return 1;
701 }
702 catch(...)
703 {
704 ErrorMessage("Unknown error");
705 return 1;
706 }
707 }
708
SaveWindowInfo(HWND aWnd)709 static void SaveWindowInfo(HWND aWnd)
710 {
711 CWindowInfo info;
712
713 #ifdef UNDER_CE
714
715 if (!::GetWindowRect(aWnd, &info.rect))
716 return;
717 info.maximized = g_Maximized;
718
719 #else
720
721 WINDOWPLACEMENT placement;
722 placement.length = sizeof(placement);
723 if (!::GetWindowPlacement(aWnd, &placement))
724 return;
725 info.rect = placement.rcNormalPosition;
726 info.maximized = BOOLToBool(::IsZoomed(aWnd));
727
728 #endif
729
730 info.numPanels = g_App.NumPanels;
731 info.currentPanel = g_App.LastFocusedPanel;
732 info.splitterPos = g_Splitter.GetPos();
733
734 info.Save();
735 }
736
ExecuteCommand(UINT commandID)737 static void ExecuteCommand(UINT commandID)
738 {
739 CPanel::CDisableTimerProcessing disableTimerProcessing1(g_App.Panels[0]);
740 CPanel::CDisableTimerProcessing disableTimerProcessing2(g_App.Panels[1]);
741
742 switch (commandID)
743 {
744 case kMenuCmdID_Toolbar_Add: g_App.AddToArchive(); break;
745 case kMenuCmdID_Toolbar_Extract: g_App.ExtractArchives(); break;
746 case kMenuCmdID_Toolbar_Test: g_App.TestArchives(); break;
747 }
748 }
749
WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)750 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
751 {
752 int wmId, wmEvent;
753 switch (message)
754 {
755 case WM_COMMAND:
756 wmId = LOWORD(wParam);
757 wmEvent = HIWORD(wParam);
758 if ((HWND) lParam != NULL && wmEvent != 0)
759 break;
760 if (wmId >= kMenuCmdID_Toolbar_Start && wmId < kMenuCmdID_Toolbar_End)
761 {
762 ExecuteCommand(wmId);
763 return 0;
764 }
765 if (OnMenuCommand(hWnd, wmId))
766 return 0;
767 break;
768 case WM_INITMENUPOPUP:
769 OnMenuActivating(hWnd, HMENU(wParam), LOWORD(lParam));
770 break;
771
772 /*
773 It doesn't help
774 case WM_EXITMENULOOP:
775 {
776 OnMenuUnActivating(hWnd);
777 break;
778 }
779 case WM_UNINITMENUPOPUP:
780 OnMenuUnActivating(hWnd, HMENU(wParam), lParam);
781 break;
782 */
783
784 case WM_CREATE:
785 {
786 g_HWND = hWnd;
787 /*
788 INITCOMMONCONTROLSEX icex;
789 icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
790 icex.dwICC = ICC_BAR_CLASSES;
791 InitCommonControlsEx(&icex);
792
793 // Toolbar buttons used to create the first 4 buttons.
794 TBBUTTON tbb [ ] =
795 {
796 // {0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0},
797 // {VIEW_PARENTFOLDER, kParentFolderID, TBSTATE_ENABLED, BTNS_BUTTON, 0L, 0},
798 // {0, 0, TBSTATE_ENABLED, BTNS_SEP, 0L, 0},
799 {VIEW_NEWFOLDER, ID_FILE_CREATEFOLDER, TBSTATE_ENABLED, BTNS_BUTTON, 0L, 0},
800 };
801
802 int baseID = 100;
803 NWindows::NControl::CToolBar aToolBar;
804 aToolBar.Attach(::CreateToolbarEx (hWnd,
805 WS_CHILD | WS_BORDER | WS_VISIBLE | TBSTYLE_TOOLTIPS, // | TBSTYLE_FLAT
806 baseID + 2, 11,
807 (HINSTANCE)HINST_COMMCTRL, IDB_VIEW_SMALL_COLOR,
808 (LPCTBBUTTON)&tbb, ARRAY_SIZE(tbb),
809 0, 0, 100, 30, sizeof (TBBUTTON)));
810 */
811 // HCURSOR cursor = ::LoadCursor(0, IDC_SIZEWE);
812 // ::SetCursor(cursor);
813
814 if (g_PanelsInfoDefined)
815 g_Splitter.SetPos(hWnd, g_SplitterPos);
816 else
817 {
818 g_Splitter.SetRatio(hWnd, kSplitterRateMax / 2);
819 g_SplitterPos = g_Splitter.GetPos();
820 }
821
822 RECT rect;
823 ::GetClientRect(hWnd, &rect);
824 int xSize = rect.right;
825 int xSizes[2];
826 xSizes[0] = g_Splitter.GetPos();
827 xSizes[1] = xSize - kSplitterWidth - xSizes[0];
828 if (xSizes[1] < 0)
829 xSizes[1] = 0;
830
831 g_App.CreateDragTarget();
832
833 bool archiveIsOpened;
834 bool encrypted;
835 bool needOpenFile = false;
836
837 UString fullPath = g_MainPath;
838 if (!fullPath.IsEmpty() /* && g_OpenArchive */)
839 {
840 if (!NFile::NName::IsAbsolutePath(fullPath))
841 {
842 FString fullPathF;
843 if (NFile::NName::GetFullPath(us2fs(fullPath), fullPathF))
844 fullPath = fs2us(fullPathF);
845 }
846 if (NFile::NFind::DoesFileExist(us2fs(fullPath)))
847 needOpenFile = true;
848 }
849
850 HRESULT res = g_App.Create(hWnd, fullPath, g_ArcFormat, xSizes,
851 needOpenFile,
852 archiveIsOpened, encrypted);
853
854 if (res == E_ABORT)
855 return -1;
856
857 if (needOpenFile && !archiveIsOpened || res != S_OK)
858 {
859 UString m ("Error");
860 if (res == S_FALSE || res == S_OK)
861 {
862 m = MyFormatNew(encrypted ?
863 IDS_CANT_OPEN_ENCRYPTED_ARCHIVE :
864 IDS_CANT_OPEN_ARCHIVE,
865 fullPath);
866 }
867 else if (res != S_OK)
868 m = HResultToMessage(res);
869 ErrorMessage(m);
870 return -1;
871 }
872
873 g_WindowWasCreated = true;
874
875 // g_SplitterPos = 0;
876
877 // ::DragAcceptFiles(hWnd, TRUE);
878 RegisterDragDrop(hWnd, g_App._dropTarget);
879
880 break;
881 }
882
883 case WM_DESTROY:
884 {
885 // ::DragAcceptFiles(hWnd, FALSE);
886 RevokeDragDrop(hWnd);
887 g_App._dropTarget.Release();
888
889 if (g_WindowWasCreated)
890 g_App.Save();
891
892 g_App.Release();
893
894 if (g_WindowWasCreated)
895 SaveWindowInfo(hWnd);
896
897 g_ExitEventLauncher.Exit(true);
898 PostQuitMessage(0);
899 break;
900 }
901
902 // case WM_MOVE: break;
903
904 case WM_LBUTTONDOWN:
905 g_StartCaptureMousePos = LOWORD(lParam);
906 g_StartCaptureSplitterPos = g_Splitter.GetPos();
907 ::SetCapture(hWnd);
908 break;
909
910 case WM_LBUTTONUP:
911 {
912 ::ReleaseCapture();
913 break;
914 }
915
916 case WM_MOUSEMOVE:
917 {
918 if ((wParam & MK_LBUTTON) != 0 && ::GetCapture() == hWnd)
919 {
920 g_Splitter.SetPos(hWnd, g_StartCaptureSplitterPos +
921 (short)LOWORD(lParam) - g_StartCaptureMousePos);
922 g_App.MoveSubWindows();
923 }
924 break;
925 }
926
927 case WM_SIZE:
928 {
929 if (g_CanChangeSplitter)
930 g_Splitter.SetPosFromRatio(hWnd);
931 else
932 {
933 g_Splitter.SetPos(hWnd, g_SplitterPos );
934 g_CanChangeSplitter = true;
935 }
936
937 g_Maximized = (wParam == SIZE_MAXIMIZED) || (wParam == SIZE_MAXSHOW);
938
939 g_App.MoveSubWindows();
940 /*
941 int xSize = LOWORD(lParam);
942 int ySize = HIWORD(lParam);
943 // int xSplitter = 2;
944 int xWidth = g_SplitPos;
945 // int xSplitPos = xWidth;
946 g_Panel[0]._listView.MoveWindow(0, 0, xWidth, ySize);
947 g_Panel[1]._listView.MoveWindow(xSize - xWidth, 0, xWidth, ySize);
948 */
949 return 0;
950 break;
951 }
952
953 case WM_SETFOCUS:
954 // g_App.SetFocus(g_App.LastFocusedPanel);
955 g_App.SetFocusToLastItem();
956 break;
957
958 /*
959 case WM_ACTIVATE:
960 {
961 int fActive = LOWORD(wParam);
962 switch (fActive)
963 {
964 case WA_INACTIVE:
965 {
966 // g_FocusIndex = g_App.LastFocusedPanel;
967 // g_App.LastFocusedPanel = g_App.GetFocusedPanelIndex();
968 // return 0;
969 }
970 }
971 break;
972 }
973 */
974
975 /*
976 case kLangWasChangedMessage:
977 MyLoadMenu();
978 return 0;
979 */
980
981 /*
982 case WM_SETTINGCHANGE:
983 break;
984 */
985
986 case WM_NOTIFY:
987 {
988 g_App.OnNotify((int)wParam, (LPNMHDR)lParam);
989 break;
990 }
991
992 /*
993 case WM_DROPFILES:
994 {
995 g_App.GetFocusedPanel().CompressDropFiles((HDROP)wParam);
996 return 0 ;
997 }
998 */
999 }
1000 #ifndef _UNICODE
1001 if (g_IsNT)
1002 return DefWindowProcW(hWnd, message, wParam, lParam);
1003 else
1004 #endif
1005 return DefWindowProc(hWnd, message, wParam, lParam);
1006
1007 }
1008
Window_GetRealHeight(NWindows::CWindow & w)1009 static int Window_GetRealHeight(NWindows::CWindow &w)
1010 {
1011 RECT rect;
1012 w.GetWindowRect(&rect);
1013 int res = RECT_SIZE_Y(rect);
1014 #ifndef UNDER_CE
1015 WINDOWPLACEMENT placement;
1016 if (w.GetPlacement(&placement))
1017 res += placement.rcNormalPosition.top;
1018 #endif
1019 return res;
1020 }
1021
MoveSubWindows()1022 void CApp::MoveSubWindows()
1023 {
1024 HWND hWnd = _window;
1025 RECT rect;
1026 if (hWnd == 0)
1027 return;
1028 ::GetClientRect(hWnd, &rect);
1029 int xSize = rect.right;
1030 if (xSize == 0)
1031 return;
1032 int headerSize = 0;
1033
1034 #ifdef UNDER_CE
1035 _commandBar.AutoSize();
1036 {
1037 _commandBar.Show(true); // maybe we need it for
1038 headerSize += _commandBar.Height();
1039 }
1040 #endif
1041
1042 if (_toolBar)
1043 {
1044 _toolBar.AutoSize();
1045 #ifdef UNDER_CE
1046 int h2 = Window_GetRealHeight(_toolBar);
1047 _toolBar.Move(0, headerSize, xSize, h2);
1048 #endif
1049 headerSize += Window_GetRealHeight(_toolBar);
1050 }
1051
1052 int ySize = MyMax((int)(rect.bottom - headerSize), 0);
1053
1054 if (NumPanels > 1)
1055 {
1056 Panels[0].Move(0, headerSize, g_Splitter.GetPos(), ySize);
1057 int xWidth1 = g_Splitter.GetPos() + kSplitterWidth;
1058 Panels[1].Move(xWidth1, headerSize, xSize - xWidth1, ySize);
1059 }
1060 else
1061 {
1062 /*
1063 int otherPanel = 1 - LastFocusedPanel;
1064 if (PanelsCreated[otherPanel])
1065 Panels[otherPanel].Move(0, headerSize, 0, ySize);
1066 */
1067 Panels[LastFocusedPanel].Move(0, headerSize, xSize, ySize);
1068 }
1069 }
1070