OSDN Git Service

Fix init repos commit\show log problem.
[tortoisegit/TortoiseGitJp.git] / src / TortoiseMerge / TortoiseMerge.cpp
1 // TortoiseMerge - a Diff/Patch program\r
2 \r
3 // Copyright (C) 2006-2008 - TortoiseSVN\r
4 \r
5 // This program is free software; you can redistribute it and/or\r
6 // modify it under the terms of the GNU General Public License\r
7 // as published by the Free Software Foundation; either version 2\r
8 // of the License, or (at your option) any later version.\r
9 \r
10 // This program is distributed in the hope that it will be useful,\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 // GNU General Public License for more details.\r
14 \r
15 // You should have received a copy of the GNU General Public License\r
16 // along with this program; if not, write to the Free Software Foundation,\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
18 //\r
19 #include "stdafx.h"\r
20 #include <dlgs.h>\r
21 #include "TortoiseMerge.h"\r
22 #include "MainFrm.h"\r
23 #include "AboutDlg.h"\r
24 #include "CmdLineParser.h"\r
25 #include "..\\version.h"\r
26 #include "AppUtils.h"\r
27 #include "PathUtils.h"\r
28 #include "BrowseFolder.h"\r
29 \r
30 #ifdef _DEBUG\r
31 #define new DEBUG_NEW\r
32 #endif\r
33 \r
34 #pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")\r
35 \r
36 BEGIN_MESSAGE_MAP(CTortoiseMergeApp, CWinAppEx)\r
37         ON_COMMAND(ID_APP_ABOUT, OnAppAbout)\r
38 END_MESSAGE_MAP()\r
39 \r
40 \r
41 CTortoiseMergeApp::CTortoiseMergeApp()\r
42 {\r
43         EnableHtmlHelp();\r
44         m_bLoadUserToolbars = FALSE;\r
45         m_bSaveState = FALSE;\r
46 }\r
47 \r
48 // The one and only CTortoiseMergeApp object\r
49 CTortoiseMergeApp theApp;\r
50 //CCrashReport g_crasher("crashreports@tortoisesvn.tigris.org", "Crash Report for TortoiseMerge " APP_X64_STRING " : " STRPRODUCTVER, TRUE);\r
51 \r
52 // CTortoiseMergeApp initialization\r
53 BOOL CTortoiseMergeApp::InitInstance()\r
54 {\r
55         CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));\r
56         CMFCButton::EnableWindowsTheming();\r
57         //set the resource dll for the required language\r
58         CRegDWORD loc = CRegDWORD(_T("Software\\TortoiseSVN\\LanguageID"), 1033);\r
59         long langId = loc;\r
60         CString langDll;\r
61         HINSTANCE hInst = NULL;\r
62         do\r
63         {\r
64                 langDll.Format(_T("..\\Languages\\TortoiseMerge%d.dll"), langId);\r
65                 \r
66                 hInst = LoadLibrary(langDll);\r
67                 CString sVer = _T(STRPRODUCTVER);\r
68                 CString sFileVer = CPathUtils::GetVersionFromFile(langDll);\r
69                 if (sFileVer.Compare(sVer)!=0)\r
70                 {\r
71                         FreeLibrary(hInst);\r
72                         hInst = NULL;\r
73                 }\r
74                 if (hInst != NULL)\r
75                         AfxSetResourceHandle(hInst);\r
76                 else\r
77                 {\r
78                         DWORD lid = SUBLANGID(langId);\r
79                         lid--;\r
80                         if (lid > 0)\r
81                         {\r
82                                 langId = MAKELANGID(PRIMARYLANGID(langId), lid);\r
83                         }\r
84                         else\r
85                                 langId = 0;\r
86                 }\r
87         } while ((hInst == NULL) && (langId != 0));\r
88         TCHAR buf[6];\r
89         _tcscpy_s(buf, _T("en"));\r
90         langId = loc;\r
91         CString sHelppath;\r
92         sHelppath = this->m_pszHelpFilePath;\r
93         sHelppath = sHelppath.MakeLower();\r
94         sHelppath.Replace(_T(".chm"), _T("_en.chm"));\r
95         free((void*)m_pszHelpFilePath);\r
96         m_pszHelpFilePath=_tcsdup(sHelppath);\r
97         sHelppath = CPathUtils::GetAppParentDirectory() + _T("Languages\\TortoiseMerge_en.chm");\r
98         do\r
99         {\r
100                 GetLocaleInfo(MAKELCID(langId, SORT_DEFAULT), LOCALE_SISO639LANGNAME, buf, sizeof(buf));\r
101                 CString sLang = _T("_");\r
102                 sLang += buf;\r
103                 sHelppath.Replace(_T("_en"), sLang);\r
104                 if (PathFileExists(sHelppath))\r
105                 {\r
106                         free((void*)m_pszHelpFilePath);\r
107                         m_pszHelpFilePath=_tcsdup(sHelppath);\r
108                         break;\r
109                 }\r
110                 sHelppath.Replace(sLang, _T("_en"));\r
111                 GetLocaleInfo(MAKELCID(langId, SORT_DEFAULT), LOCALE_SISO3166CTRYNAME, buf, sizeof(buf));\r
112                 sLang += _T("_");\r
113                 sLang += buf;\r
114                 sHelppath.Replace(_T("_en"), sLang);\r
115                 if (PathFileExists(sHelppath))\r
116                 {\r
117                         free((void*)m_pszHelpFilePath);\r
118                         m_pszHelpFilePath=_tcsdup(sHelppath);\r
119                         break;\r
120                 }\r
121                 sHelppath.Replace(sLang, _T("_en"));\r
122 \r
123                 DWORD lid = SUBLANGID(langId);\r
124                 lid--;\r
125                 if (lid > 0)\r
126                 {\r
127                         langId = MAKELANGID(PRIMARYLANGID(langId), lid);\r
128                 }\r
129                 else\r
130                         langId = 0;\r
131         } while (langId);\r
132         setlocale(LC_ALL, ""); \r
133 \r
134         // InitCommonControls() is required on Windows XP if an application\r
135         // manifest specifies use of ComCtl32.dll version 6 or later to enable\r
136         // visual styles.  Otherwise, any window creation will fail.\r
137         InitCommonControls();\r
138 \r
139         // Initialize all Managers for usage. They are automatically constructed\r
140         // if not yet present\r
141         InitContextMenuManager();\r
142         InitKeyboardManager();\r
143 \r
144         CCmdLineParser parser = CCmdLineParser(this->m_lpCmdLine);\r
145 \r
146         if (parser.HasKey(_T("?")) || parser.HasKey(_T("help")))\r
147         {\r
148                 CString sHelpText;\r
149                 sHelpText.LoadString(IDS_COMMANDLINEHELP);\r
150                 MessageBox(NULL, sHelpText, _T("TortoiseMerge"), MB_ICONINFORMATION);\r
151                 return FALSE;\r
152         }\r
153 \r
154         // Initialize OLE libraries\r
155         if (!AfxOleInit())\r
156         {\r
157                 AfxMessageBox(IDP_OLE_INIT_FAILED);\r
158                 return FALSE;\r
159         }\r
160         AfxEnableControlContainer();\r
161         // Standard initialization\r
162         // If you are not using these features and wish to reduce the size\r
163         // of your final executable, you should remove from the following\r
164         // the specific initialization routines you do not need\r
165         // Change the registry key under which our settings are stored\r
166         SetRegistryKey(_T("TortoiseMerge"));\r
167 \r
168         if (CRegDWORD(_T("Software\\TortoiseMerge\\Debug"), FALSE)==TRUE)\r
169                 AfxMessageBox(AfxGetApp()->m_lpCmdLine, MB_OK | MB_ICONINFORMATION);\r
170 \r
171         // To create the main window, this code creates a new frame window\r
172         // object and then sets it as the application's main window object\r
173         CMainFrame* pFrame = new CMainFrame;\r
174         if (pFrame == NULL)\r
175                 return FALSE;\r
176         m_pMainWnd = pFrame;\r
177 \r
178         // create and load the frame with its resources\r
179         pFrame->LoadFrame(IDR_MAINFRAME,\r
180                 WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL,\r
181                 NULL);\r
182 \r
183         // Fill in the command line options\r
184         pFrame->m_Data.m_baseFile.SetFileName(parser.GetVal(_T("base")));\r
185         pFrame->m_Data.m_baseFile.SetDescriptiveName(parser.GetVal(_T("basename")));\r
186         pFrame->m_Data.m_theirFile.SetFileName(parser.GetVal(_T("theirs")));\r
187         pFrame->m_Data.m_theirFile.SetDescriptiveName(parser.GetVal(_T("theirsname")));\r
188         pFrame->m_Data.m_yourFile.SetFileName(parser.GetVal(_T("mine")));\r
189         pFrame->m_Data.m_yourFile.SetDescriptiveName(parser.GetVal(_T("minename")));\r
190         pFrame->m_Data.m_mergedFile.SetFileName(parser.GetVal(_T("merged")));\r
191         pFrame->m_Data.m_mergedFile.SetDescriptiveName(parser.GetVal(_T("mergedname")));\r
192         pFrame->m_Data.m_sPatchPath = parser.HasVal(_T("patchpath")) ? parser.GetVal(_T("patchpath")) : _T("");\r
193         pFrame->m_Data.m_sPatchPath.Replace('/', '\\');\r
194         if (parser.HasKey(_T("patchoriginal")))\r
195                 pFrame->m_Data.m_sPatchOriginal = parser.GetVal(_T("patchoriginal"));\r
196         if (parser.HasKey(_T("patchpatched")))\r
197                 pFrame->m_Data.m_sPatchPatched = parser.GetVal(_T("patchpatched"));\r
198         pFrame->m_Data.m_sDiffFile = parser.GetVal(_T("diff"));\r
199         pFrame->m_Data.m_sDiffFile.Replace('/', '\\');\r
200         if (parser.HasKey(_T("oneway")))\r
201         pFrame->m_bOneWay = TRUE;\r
202         if (parser.HasKey(_T("diff")))\r
203                 pFrame->m_bOneWay = FALSE;\r
204         if (parser.HasKey(_T("reversedpatch")))\r
205                 pFrame->m_bReversedPatch = TRUE;\r
206         if (pFrame->m_Data.IsBaseFileInUse() && !pFrame->m_Data.IsYourFileInUse() && pFrame->m_Data.IsTheirFileInUse())\r
207         {\r
208                 pFrame->m_Data.m_yourFile.TransferDetailsFrom(pFrame->m_Data.m_theirFile);\r
209         }\r
210 \r
211         if ((!parser.HasKey(_T("patchpath")))&&(parser.HasVal(_T("diff"))))\r
212         {\r
213                 // a patchfile was given, but not folder path to apply the patch to\r
214                 // If the patchfile is located inside a working copy, then use the parent directory\r
215                 // of the patchfile as the target directory, otherwise ask the user for a path.\r
216                 if (parser.HasKey(_T("wc")))\r
217                         pFrame->m_Data.m_sPatchPath = pFrame->m_Data.m_sDiffFile.Left(pFrame->m_Data.m_sDiffFile.ReverseFind('\\'));\r
218                 else\r
219                 {\r
220                         CBrowseFolder fbrowser;\r
221                         fbrowser.m_style = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS;\r
222                         if (fbrowser.Show(NULL, pFrame->m_Data.m_sPatchPath)==CBrowseFolder::CANCEL)\r
223                                 return FALSE;\r
224                 }\r
225         }\r
226 \r
227         if ((parser.HasKey(_T("patchpath")))&&(!parser.HasVal(_T("diff"))))\r
228         {\r
229                 // A path was given for applying a patchfile, but\r
230                 // the patchfile itself was not.\r
231                 // So ask the user for that patchfile\r
232 \r
233                 OPENFILENAME ofn = {0};                 // common dialog box structure\r
234                 TCHAR szFile[MAX_PATH] = {0};   // buffer for file name\r
235                 // Initialize OPENFILENAME\r
236                 ofn.lStructSize = sizeof(OPENFILENAME);\r
237                 ofn.hwndOwner = pFrame->m_hWnd;\r
238                 ofn.lpstrFile = szFile;\r
239                 ofn.nMaxFile = sizeof(szFile)/sizeof(TCHAR);\r
240                 CString temp;\r
241                 temp.LoadString(IDS_OPENDIFFFILETITLE);\r
242                 if (temp.IsEmpty())\r
243                         ofn.lpstrTitle = NULL;\r
244                 else\r
245                         ofn.lpstrTitle = temp;\r
246 \r
247                 ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_EXPLORER;\r
248                 // check if there's a patchfile in the clipboard\r
249                 UINT cFormat = RegisterClipboardFormat(_T("TSVN_UNIFIEDDIFF"));\r
250                 if (cFormat)\r
251                 {\r
252                         if (OpenClipboard(NULL))\r
253                         {\r
254                                 UINT enumFormat = 0;\r
255                                 do \r
256                                 {\r
257                                         if (enumFormat == cFormat)\r
258                                         {\r
259                                                 // yes, there's a patchfile in the clipboard\r
260                                                 ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_ENABLETEMPLATE | OFN_ENABLEHOOK | OFN_EXPLORER;\r
261 \r
262                                                 ofn.hInstance = AfxGetResourceHandle();\r
263                                                 ofn.lpTemplateName = MAKEINTRESOURCE(IDD_PATCH_FILE_OPEN_CUSTOM);\r
264                                                 ofn.lpfnHook = CreatePatchFileOpenHook;\r
265                                         }\r
266                                 } while((enumFormat = EnumClipboardFormats(enumFormat))!=0);\r
267                                 CloseClipboard();\r
268                         }\r
269                 }\r
270 \r
271                 CString sFilter;\r
272                 sFilter.LoadString(IDS_PATCHFILEFILTER);\r
273                 TCHAR * pszFilters = new TCHAR[sFilter.GetLength()+4];\r
274                 _tcscpy_s (pszFilters, sFilter.GetLength()+4, sFilter);\r
275                 // Replace '|' delimiters with '\0's\r
276                 TCHAR *ptr = pszFilters + _tcslen(pszFilters);  //set ptr at the NULL\r
277                 while (ptr != pszFilters)\r
278                 {\r
279                         if (*ptr == '|')\r
280                                 *ptr = '\0';\r
281                         ptr--;\r
282                 }\r
283                 ofn.lpstrFilter = pszFilters;\r
284                 ofn.nFilterIndex = 1;\r
285 \r
286                 // Display the Open dialog box. \r
287                 CString tempfile;\r
288                 if (GetOpenFileName(&ofn)==FALSE)\r
289                 {\r
290                         delete [] pszFilters;\r
291                         return FALSE;\r
292                 }\r
293                 delete [] pszFilters;\r
294                 pFrame->m_Data.m_sDiffFile = ofn.lpstrFile;\r
295         }\r
296 \r
297         if ( pFrame->m_Data.m_baseFile.GetFilename().IsEmpty() && pFrame->m_Data.m_yourFile.GetFilename().IsEmpty() )\r
298         {\r
299                 LPWSTR *szArglist;\r
300                 int nArgs;\r
301 \r
302                 szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);\r
303                 if( NULL == szArglist )\r
304                 {\r
305                         TRACE("CommandLineToArgvW failed\n");\r
306                 }\r
307                 else\r
308                 {\r
309                         if ( nArgs==3 || nArgs==4 )\r
310                         {\r
311                                 // Four parameters:\r
312                                 // [0]: Program name\r
313                                 // [1]: BASE file\r
314                                 // [2]: my file\r
315                                 // [3]: THEIR file (optional)\r
316                                 // This is the same format CAppUtils::StartExtDiff\r
317                                 // uses if %base and %mine are not set and most\r
318                                 // other diff tools use it too.\r
319                                 if ( PathFileExists(szArglist[1]) && PathFileExists(szArglist[2]) )\r
320                                 {\r
321                                         pFrame->m_Data.m_baseFile.SetFileName(szArglist[1]);\r
322                                         pFrame->m_Data.m_yourFile.SetFileName(szArglist[2]);\r
323                                         if ( nArgs == 4 && PathFileExists(szArglist[3]) )\r
324                                         {\r
325                                                 pFrame->m_Data.m_theirFile.SetFileName(szArglist[3]);\r
326                                         }\r
327                                 }\r
328                         }\r
329                 }\r
330 \r
331                 // Free memory allocated for CommandLineToArgvW arguments.\r
332                 LocalFree(szArglist);\r
333         }\r
334 \r
335         pFrame->m_bReadOnly = !!parser.HasKey(_T("readonly"));\r
336         if (GetFileAttributes(pFrame->m_Data.m_yourFile.GetFilename()) & FILE_ATTRIBUTE_READONLY)\r
337                 pFrame->m_bReadOnly = true;\r
338         pFrame->m_bBlame = !!parser.HasKey(_T("blame"));\r
339         // diffing a blame means no editing!\r
340         if (pFrame->m_bBlame)\r
341                 pFrame->m_bReadOnly = true;\r
342 \r
343         // try to find a suitable window title\r
344         CString sYour = pFrame->m_Data.m_yourFile.GetDescriptiveName();\r
345         if (sYour.Find(_T(" - "))>=0)\r
346                 sYour = sYour.Left(sYour.Find(_T(" - ")));\r
347         if (sYour.Find(_T(" : "))>=0)\r
348                 sYour = sYour.Left(sYour.Find(_T(" : ")));\r
349         CString sTheir = pFrame->m_Data.m_theirFile.GetDescriptiveName();\r
350         if (sTheir.Find(_T(" - "))>=0)\r
351                 sTheir = sTheir.Left(sTheir.Find(_T(" - ")));\r
352         if (sTheir.Find(_T(" : "))>=0)\r
353                 sTheir = sTheir.Left(sTheir.Find(_T(" : ")));\r
354 \r
355         if (!sYour.IsEmpty() && !sTheir.IsEmpty())\r
356         {\r
357                 if (sYour.CompareNoCase(sTheir)==0)\r
358                         pFrame->SetWindowText(sYour + _T(" - TortoiseMerge"));\r
359                 else if ((sYour.GetLength() < 10) &&\r
360                                 (sTheir.GetLength() < 10))\r
361                         pFrame->SetWindowText(sYour + _T(" - ") + sTheir + _T(" - TortoiseMerge"));\r
362                 else\r
363                 {\r
364                         // we have two very long descriptive texts here, which\r
365                         // means we have to find a way to use them as a window \r
366                         // title in a shorter way.\r
367                         // for simplicity, we just use the one from "yourfile"\r
368                         pFrame->SetWindowText(sYour + _T(" - TortoiseMerge"));\r
369                 }\r
370         }\r
371         else if (!sYour.IsEmpty())\r
372                 pFrame->SetWindowText(sYour + _T(" - TortoiseMerge"));\r
373         else if (!sTheir.IsEmpty())\r
374                 pFrame->SetWindowText(sTheir + _T(" - TortoiseMerge"));\r
375 \r
376         if (parser.HasKey(_T("createunifieddiff")))\r
377         {\r
378                 // user requested to create a unified diff file\r
379                 CString origFile = parser.GetVal(_T("origfile"));\r
380                 CString modifiedFile = parser.GetVal(_T("modifiedfile"));\r
381                 if (!origFile.IsEmpty() && !modifiedFile.IsEmpty())\r
382                 {\r
383                         CString outfile = parser.GetVal(_T("outfile"));\r
384                         if (outfile.IsEmpty())\r
385                         {\r
386                                 OPENFILENAME ofn = {0};                 // common dialog box structure\r
387                                 TCHAR szFile[MAX_PATH] = {0};   // buffer for file name\r
388                                 ofn.lStructSize = sizeof(OPENFILENAME);\r
389                                 ofn.lpstrFile = szFile;\r
390                                 ofn.nMaxFile = sizeof(szFile)/sizeof(TCHAR);\r
391                                 CString temp;\r
392                                 temp.LoadString(IDS_SAVEASTITLE);\r
393                                 if (!temp.IsEmpty())\r
394                                         ofn.lpstrTitle = temp;\r
395                                 ofn.Flags = OFN_OVERWRITEPROMPT;\r
396                                 CString sFilter;\r
397                                 sFilter.LoadString(IDS_COMMONFILEFILTER);\r
398                                 TCHAR * pszFilters = new TCHAR[sFilter.GetLength()+4];\r
399                                 _tcscpy_s (pszFilters, sFilter.GetLength()+4, sFilter);\r
400                                 // Replace '|' delimiters with '\0's\r
401                                 TCHAR *ptr = pszFilters + _tcslen(pszFilters);  //set ptr at the NULL\r
402                                 while (ptr != pszFilters)\r
403                                 {\r
404                                         if (*ptr == '|')\r
405                                                 *ptr = '\0';\r
406                                         ptr--;\r
407                                 }\r
408                                 ofn.lpstrFilter = pszFilters;\r
409                                 ofn.nFilterIndex = 1;\r
410 \r
411                                 // Display the Save dialog box. \r
412                                 CString sFile;\r
413                                 if (GetSaveFileName(&ofn)==TRUE)\r
414                                 {\r
415                                         outfile = CString(ofn.lpstrFile);\r
416                                 }\r
417                                 delete [] pszFilters;\r
418                         }\r
419                         if (!outfile.IsEmpty())\r
420                         {\r
421                                 CAppUtils::CreateUnifiedDiff(origFile, modifiedFile, outfile, false);\r
422                                 return FALSE;\r
423                         }\r
424                 }\r
425         }\r
426         // The one and only window has been initialized, so show and update it\r
427         pFrame->ActivateFrame();\r
428         pFrame->ShowWindow(SW_SHOW);\r
429         pFrame->UpdateWindow();\r
430         if (!pFrame->m_Data.IsBaseFileInUse() && pFrame->m_Data.m_sPatchPath.IsEmpty() && pFrame->m_Data.m_sDiffFile.IsEmpty())\r
431         {\r
432                 pFrame->OnFileOpen();\r
433                 return TRUE;\r
434         }\r
435         return pFrame->LoadViews();\r
436 }\r
437 \r
438 // CTortoiseMergeApp message handlers\r
439 \r
440 void CTortoiseMergeApp::OnAppAbout()\r
441 {\r
442         CAboutDlg aboutDlg;\r
443         aboutDlg.DoModal();\r
444 }\r
445 \r
446 UINT_PTR CALLBACK \r
447 CTortoiseMergeApp::CreatePatchFileOpenHook(HWND hDlg, UINT uiMsg, WPARAM wParam, LPARAM /*lParam*/)\r
448 {\r
449         if(uiMsg ==     WM_COMMAND && LOWORD(wParam) == IDC_PATCH_TO_CLIPBOARD)\r
450         {\r
451                 HWND hFileDialog = GetParent(hDlg);\r
452 \r
453                 // if there's a patchfile in the clipboard, we save it\r
454                 // to a temporary file and tell TortoiseMerge to use that one\r
455                 UINT cFormat = RegisterClipboardFormat(_T("TSVN_UNIFIEDDIFF"));\r
456                 if ((cFormat)&&(OpenClipboard(NULL)))\r
457                 { \r
458                         HGLOBAL hglb = GetClipboardData(cFormat); \r
459                         LPCSTR lpstr = (LPCSTR)GlobalLock(hglb); \r
460 \r
461                         DWORD len = GetTempPath(0, NULL);\r
462                         TCHAR * path = new TCHAR[len+1];\r
463                         TCHAR * tempF = new TCHAR[len+100];\r
464                         GetTempPath (len+1, path);\r
465                         GetTempFileName (path, TEXT("svn"), 0, tempF);\r
466                         std::wstring sTempFile = std::wstring(tempF);\r
467                         delete [] path;\r
468                         delete [] tempF;\r
469 \r
470                         FILE * outFile;\r
471                         size_t patchlen = strlen(lpstr);\r
472                         _tfopen_s(&outFile, sTempFile.c_str(), _T("wb"));\r
473                         if(outFile)\r
474                         {\r
475                                 size_t size = fwrite(lpstr, sizeof(char), patchlen, outFile);\r
476                                 if (size == patchlen)\r
477                                 {\r
478                                         CommDlg_OpenSave_SetControlText(hFileDialog, edt1, sTempFile.c_str());   \r
479                                         PostMessage(hFileDialog, WM_COMMAND, MAKEWPARAM(IDOK, BM_CLICK), (LPARAM)(GetDlgItem(hDlg, IDOK)));\r
480                                 }\r
481                                 fclose(outFile);\r
482                         }\r
483                         GlobalUnlock(hglb); \r
484                         CloseClipboard(); \r
485                 } \r
486         }\r
487         return 0;\r
488 }\r