Fixed issue #1264: TortoiseProc might crash if commands are executed w/o a working...
[TortoiseGit.git] / src / Utils / CommonAppUtils.cpp
blob6e7b77d2041f20180f7fa0ae797867557cd30b39
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2012 - TortoiseGit
4 // Copyright (C) 2003-2008,2010 - TortoiseSVN
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "StdAfx.h"
21 #include "..\Resources\LoglistCommonResource.h"
22 #include "CommonAppUtils.h"
23 #include "PathUtils.h"
24 #include "StringUtils.h"
25 #include "CreateProcessHelper.h"
26 #include "FormatMessageWrapper.h"
27 #include "Registry.h"
29 extern CString sOrigCWD;
31 bool CCommonAppUtils::LaunchApplication(const CString& sCommandLine, UINT idErrMessageFormat, bool bWaitForStartup, CString *cwd)
33 STARTUPINFO startup;
34 PROCESS_INFORMATION process;
35 memset(&startup, 0, sizeof(startup));
36 startup.cb = sizeof(startup);
37 memset(&process, 0, sizeof(process));
39 CString cleanCommandLine(sCommandLine);
41 CString theCWD = sOrigCWD;
42 if (cwd != NULL)
43 theCWD = *cwd;
45 if (CreateProcess(NULL, const_cast<TCHAR*>((LPCTSTR)cleanCommandLine), NULL, NULL, FALSE, 0, 0, theCWD, &startup, &process)==0)
47 if(idErrMessageFormat != 0)
49 CString temp;
50 temp.Format(idErrMessageFormat, CFormatMessageWrapper());
51 MessageBox(NULL, temp, _T("TortoiseGit"), MB_OK | MB_ICONINFORMATION);
53 return false;
56 if (bWaitForStartup)
58 WaitForInputIdle(process.hProcess, 10000);
61 CloseHandle(process.hThread);
62 CloseHandle(process.hProcess);
63 return true;
66 bool CCommonAppUtils::RunTortoiseProc(const CString& sCommandLine)
68 CString pathToExecutable = CPathUtils::GetAppDirectory() + _T("TortoiseProc.exe");
69 CString sCmd;
70 sCmd.Format(_T("\"%s\" %s"), (LPCTSTR)pathToExecutable, (LPCTSTR)sCommandLine);
71 if (AfxGetMainWnd()->GetSafeHwnd() && (sCommandLine.Find(L"/hwnd:") < 0))
73 CString sCmdLine;
74 sCmdLine.Format(L"%s /hwnd:%ld", (LPCTSTR)sCommandLine, AfxGetMainWnd()->GetSafeHwnd());
75 sCmd.Format(_T("\"%s\" %s"), (LPCTSTR)pathToExecutable, (LPCTSTR)sCmdLine);
78 return LaunchApplication(sCmd, NULL, false);
81 bool CCommonAppUtils::SetListCtrlBackgroundImage(HWND hListCtrl, UINT nID, int width /* = 128 */, int height /* = 128 */)
83 if ((((DWORD)CRegStdDWORD(_T("Software\\TortoiseGit\\ShowListBackgroundImage"), TRUE)) == FALSE))
84 return false;
85 ListView_SetTextBkColor(hListCtrl, CLR_NONE);
86 COLORREF bkColor = ListView_GetBkColor(hListCtrl);
87 // create a bitmap from the icon
88 HICON hIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(nID), IMAGE_ICON, width, height, LR_DEFAULTCOLOR);
89 if (!hIcon)
90 return false;
92 RECT rect = {0};
93 rect.right = width;
94 rect.bottom = height;
95 HBITMAP bmp = NULL;
97 HWND desktop = ::GetDesktopWindow();
98 if (desktop)
100 HDC screen_dev = ::GetDC(desktop);
101 if (screen_dev)
103 // Create a compatible DC
104 HDC dst_hdc = ::CreateCompatibleDC(screen_dev);
105 if (dst_hdc)
107 // Create a new bitmap of icon size
108 bmp = ::CreateCompatibleBitmap(screen_dev, rect.right, rect.bottom);
109 if (bmp)
111 // Select it into the compatible DC
112 HBITMAP old_dst_bmp = (HBITMAP)::SelectObject(dst_hdc, bmp);
113 // Fill the background of the compatible DC with the given color
114 ::SetBkColor(dst_hdc, bkColor);
115 ::ExtTextOut(dst_hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
117 // Draw the icon into the compatible DC
118 ::DrawIconEx(dst_hdc, 0, 0, hIcon, rect.right, rect.bottom, 0, NULL, DI_NORMAL);
119 ::SelectObject(dst_hdc, old_dst_bmp);
121 ::DeleteDC(dst_hdc);
124 ::ReleaseDC(desktop, screen_dev);
127 // Restore settings
128 DestroyIcon(hIcon);
130 if (bmp == NULL)
131 return false;
133 LVBKIMAGE lv;
134 lv.ulFlags = LVBKIF_TYPE_WATERMARK;
135 lv.hbm = bmp;
136 lv.xOffsetPercent = 100;
137 lv.yOffsetPercent = 100;
138 ListView_SetBkImage(hListCtrl, &lv);
139 return true;
142 bool CCommonAppUtils::FileOpenSave(CString& path, int * filterindex, UINT title, UINT filter, bool bOpen, HWND hwndOwner)
144 OPENFILENAME ofn = {0}; // common dialog box structure
145 TCHAR szFile[MAX_PATH] = {0}; // buffer for file name. Explorer can't handle paths longer than MAX_PATH.
146 ofn.lStructSize = sizeof(OPENFILENAME);
147 ofn.hwndOwner = hwndOwner;
148 _tcscpy_s(szFile, MAX_PATH, (LPCTSTR)path);
149 ofn.lpstrFile = szFile;
150 ofn.nMaxFile = _countof(szFile);
151 CString sFilter;
152 TCHAR * pszFilters = NULL;
153 if (filter)
155 sFilter.LoadString(filter);
156 pszFilters = new TCHAR[sFilter.GetLength()+4];
157 _tcscpy_s (pszFilters, sFilter.GetLength()+4, sFilter);
158 // Replace '|' delimiters with '\0's
159 TCHAR *ptr = pszFilters + _tcslen(pszFilters); //set ptr at the NULL
160 while (ptr != pszFilters)
162 if (*ptr == '|')
163 *ptr = '\0';
164 ptr--;
166 ofn.lpstrFilter = pszFilters;
168 ofn.nFilterIndex = 1;
169 ofn.lpstrFileTitle = NULL;
170 ofn.nMaxFileTitle = 0;
171 ofn.lpstrInitialDir = NULL;
172 CString temp;
173 if (title)
175 temp.LoadString(title);
176 CStringUtils::RemoveAccelerators(temp);
178 ofn.lpstrTitle = temp;
179 if (bOpen)
180 ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_EXPLORER;
181 else
182 ofn.Flags = OFN_OVERWRITEPROMPT | OFN_EXPLORER;
185 // Display the Open dialog box.
186 bool bRet = false;
187 if (bOpen)
189 bRet = !!GetOpenFileName(&ofn);
191 else
193 bRet = !!GetSaveFileName(&ofn);
195 SetCurrentDirectory(sOrigCWD.GetBuffer());
196 sOrigCWD.ReleaseBuffer();
197 if (bRet)
199 if (pszFilters)
200 delete [] pszFilters;
201 path = CString(ofn.lpstrFile);
202 if (filterindex)
203 *filterindex = ofn.nFilterIndex;
204 return true;
206 if (pszFilters)
207 delete [] pszFilters;
208 return false;