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