Dropped auto_buffer
[TortoiseGit.git] / src / Utils / CommonAppUtils.cpp
blobe5186119a056d71f2a92e14768f5efd6d6719a12
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, bool uac)
33 CString theCWD = sOrigCWD;
34 if (cwd != NULL)
35 theCWD = *cwd;
37 if (uac)
39 CString file, param;
40 SHELLEXECUTEINFO shellinfo;
41 memset(&shellinfo, 0, sizeof(shellinfo));
42 shellinfo.cbSize = sizeof(shellinfo);
43 shellinfo.hwnd = NULL;
44 shellinfo.lpVerb = _T("runas");
45 shellinfo.nShow = SW_SHOWNORMAL;
46 shellinfo.fMask = SEE_MASK_NOCLOSEPROCESS;
47 shellinfo.lpDirectory = theCWD;
49 int pos = sCommandLine.Find('"');
50 if (pos == 0)
52 pos = sCommandLine.Find('"', 2);
53 if (pos > 1)
55 file = sCommandLine.Mid(1, pos - 1);
56 param = sCommandLine.Mid(pos + 1);
58 else
60 if (idErrMessageFormat != 0)
62 CString temp;
63 temp.Format(idErrMessageFormat, CFormatMessageWrapper());
64 MessageBox(NULL, temp, _T("TortoiseGit"), MB_OK | MB_ICONINFORMATION);
66 return false;
69 else
71 pos = sCommandLine.Find(' ', 1);
72 if (pos > 0)
74 file = sCommandLine.Mid(0, pos);
75 param = sCommandLine.Mid(pos + 1);
77 else
78 file = sCommandLine;
81 shellinfo.lpFile = file;
82 shellinfo.lpParameters = param;
84 if (!ShellExecuteEx(&shellinfo))
86 if (idErrMessageFormat != 0)
88 CString temp;
89 temp.Format(idErrMessageFormat, CFormatMessageWrapper());
90 MessageBox(NULL, temp, _T("TortoiseGit"), MB_OK | MB_ICONINFORMATION);
92 return false;
95 if (bWaitForStartup)
97 WaitForInputIdle(shellinfo.hProcess, 10000);
100 CloseHandle(shellinfo.hProcess);
102 else
104 STARTUPINFO startup;
105 PROCESS_INFORMATION process;
106 memset(&startup, 0, sizeof(startup));
107 startup.cb = sizeof(startup);
108 memset(&process, 0, sizeof(process));
110 CString cleanCommandLine(sCommandLine);
112 if (CreateProcess(NULL, const_cast<TCHAR*>((LPCTSTR)cleanCommandLine), NULL, NULL, FALSE, 0, 0, theCWD, &startup, &process)==0)
114 if(idErrMessageFormat != 0)
116 CString temp;
117 temp.Format(idErrMessageFormat, CFormatMessageWrapper());
118 MessageBox(NULL, temp, _T("TortoiseGit"), MB_OK | MB_ICONINFORMATION);
120 return false;
123 if (bWaitForStartup)
125 WaitForInputIdle(process.hProcess, 10000);
128 CloseHandle(process.hThread);
129 CloseHandle(process.hProcess);
131 return true;
134 bool CCommonAppUtils::RunTortoiseGitProc(const CString& sCommandLine)
136 CString pathToExecutable = CPathUtils::GetAppDirectory() + _T("TortoiseGitProc.exe");
137 CString sCmd;
138 sCmd.Format(_T("\"%s\" %s"), (LPCTSTR)pathToExecutable, (LPCTSTR)sCommandLine);
139 if (AfxGetMainWnd()->GetSafeHwnd() && (sCommandLine.Find(L"/hwnd:") < 0))
141 CString sCmdLine;
142 sCmdLine.Format(L"%s /hwnd:%ld", (LPCTSTR)sCommandLine, AfxGetMainWnd()->GetSafeHwnd());
143 sCmd.Format(_T("\"%s\" %s"), (LPCTSTR)pathToExecutable, (LPCTSTR)sCmdLine);
146 return LaunchApplication(sCmd, NULL, false);
149 bool CCommonAppUtils::SetListCtrlBackgroundImage(HWND hListCtrl, UINT nID, int width /* = 128 */, int height /* = 128 */)
151 if ((((DWORD)CRegStdDWORD(_T("Software\\TortoiseGit\\ShowListBackgroundImage"), TRUE)) == FALSE))
152 return false;
153 ListView_SetTextBkColor(hListCtrl, CLR_NONE);
154 COLORREF bkColor = ListView_GetBkColor(hListCtrl);
155 // create a bitmap from the icon
156 HICON hIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(nID), IMAGE_ICON, width, height, LR_DEFAULTCOLOR);
157 if (!hIcon)
158 return false;
160 RECT rect = {0};
161 rect.right = width;
162 rect.bottom = height;
163 HBITMAP bmp = NULL;
165 HWND desktop = ::GetDesktopWindow();
166 if (desktop)
168 HDC screen_dev = ::GetDC(desktop);
169 if (screen_dev)
171 // Create a compatible DC
172 HDC dst_hdc = ::CreateCompatibleDC(screen_dev);
173 if (dst_hdc)
175 // Create a new bitmap of icon size
176 bmp = ::CreateCompatibleBitmap(screen_dev, rect.right, rect.bottom);
177 if (bmp)
179 // Select it into the compatible DC
180 HBITMAP old_dst_bmp = (HBITMAP)::SelectObject(dst_hdc, bmp);
181 // Fill the background of the compatible DC with the given color
182 ::SetBkColor(dst_hdc, bkColor);
183 ::ExtTextOut(dst_hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
185 // Draw the icon into the compatible DC
186 ::DrawIconEx(dst_hdc, 0, 0, hIcon, rect.right, rect.bottom, 0, NULL, DI_NORMAL);
187 ::SelectObject(dst_hdc, old_dst_bmp);
189 ::DeleteDC(dst_hdc);
192 ::ReleaseDC(desktop, screen_dev);
195 // Restore settings
196 DestroyIcon(hIcon);
198 if (bmp == NULL)
199 return false;
201 LVBKIMAGE lv;
202 lv.ulFlags = LVBKIF_TYPE_WATERMARK;
203 lv.hbm = bmp;
204 lv.xOffsetPercent = 100;
205 lv.yOffsetPercent = 100;
206 ListView_SetBkImage(hListCtrl, &lv);
207 return true;
210 bool CCommonAppUtils::FileOpenSave(CString& path, int * filterindex, UINT title, UINT filter, bool bOpen, HWND hwndOwner)
212 OPENFILENAME ofn = {0}; // common dialog box structure
213 TCHAR szFile[MAX_PATH] = {0}; // buffer for file name. Explorer can't handle paths longer than MAX_PATH.
214 ofn.lStructSize = sizeof(OPENFILENAME);
215 ofn.hwndOwner = hwndOwner;
216 _tcscpy_s(szFile, MAX_PATH, (LPCTSTR)path);
217 ofn.lpstrFile = szFile;
218 ofn.nMaxFile = _countof(szFile);
219 CString sFilter;
220 TCHAR * pszFilters = NULL;
221 if (filter)
223 sFilter.LoadString(filter);
224 pszFilters = new TCHAR[sFilter.GetLength()+4];
225 _tcscpy_s (pszFilters, sFilter.GetLength()+4, sFilter);
226 // Replace '|' delimiters with '\0's
227 TCHAR *ptr = pszFilters + _tcslen(pszFilters); //set ptr at the NULL
228 while (ptr != pszFilters)
230 if (*ptr == '|')
231 *ptr = '\0';
232 ptr--;
234 ofn.lpstrFilter = pszFilters;
236 ofn.nFilterIndex = 1;
237 ofn.lpstrFileTitle = NULL;
238 ofn.nMaxFileTitle = 0;
239 ofn.lpstrInitialDir = NULL;
240 CString temp;
241 if (title)
243 temp.LoadString(title);
244 CStringUtils::RemoveAccelerators(temp);
246 ofn.lpstrTitle = temp;
247 if (bOpen)
248 ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_EXPLORER;
249 else
250 ofn.Flags = OFN_OVERWRITEPROMPT | OFN_EXPLORER;
253 // Display the Open dialog box.
254 bool bRet = false;
255 if (bOpen)
257 bRet = !!GetOpenFileName(&ofn);
259 else
261 bRet = !!GetSaveFileName(&ofn);
263 SetCurrentDirectory(sOrigCWD.GetBuffer());
264 sOrigCWD.ReleaseBuffer();
265 if (bRet)
267 if (pszFilters)
268 delete [] pszFilters;
269 path = CString(ofn.lpstrFile);
270 if (filterindex)
271 *filterindex = ofn.nFilterIndex;
272 return true;
274 if (pszFilters)
275 delete [] pszFilters;
276 return false;
279 void CCommonAppUtils::SetCharFormat(CWnd* window, DWORD mask , DWORD effects, const std::vector<CHARRANGE>& positions)
281 CHARFORMAT2 format;
282 SecureZeroMemory(&format, sizeof(CHARFORMAT2));
283 format.cbSize = sizeof(CHARFORMAT2);
284 format.dwMask = mask;
285 format.dwEffects = effects;
286 format.crTextColor = effects;
288 for (std::vector<CHARRANGE>::const_iterator iter = positions.begin(), end = positions.end(); iter != end; ++iter)
290 CHARRANGE range = *iter;
291 window->SendMessage(EM_EXSETSEL, NULL, (LPARAM)&range);
292 window->SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&format);
296 void CCommonAppUtils::SetCharFormat(CWnd* window, DWORD mask, DWORD effects )
298 CHARFORMAT2 format;
299 SecureZeroMemory(&format, sizeof(CHARFORMAT2));
300 format.cbSize = sizeof(CHARFORMAT2);
301 format.dwMask = mask;
302 format.dwEffects = effects;
303 window->SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&format);