1 // pcbuilderdialogDlg.cpp : implementation file
6 // a fun undef for DOT NET
8 #include "CMakeSetup.h"
10 #include "cmVersion.h"
11 #include "PathDialog.h"
12 #include "CMakeSetupDialog.h"
13 #include "CMakeCommandLineInfo.h"
14 #include "../cmExternalMakefileProjectGenerator.h"
15 #include "../cmListFileCache.h"
16 #include "../cmCacheManager.h"
18 #include "../cmGlobalGenerator.h"
19 #include "../cmDynamicLoader.h"
23 static char THIS_FILE
[] = __FILE__
;
27 /////////////////////////////////////////////////////////////////////////////
28 // CAboutDlg dialog used for App About
30 class CAboutDlg
: public CDialog
36 //{{AFX_DATA(CAboutDlg)
37 enum { IDD
= IDD_ABOUTBOX
};
40 // ClassWizard generated virtual function overrides
41 //{{AFX_VIRTUAL(CAboutDlg)
43 virtual void DoDataExchange(CDataExchange
* pDX
); // DDX/DDV support
48 //{{AFX_MSG(CAboutDlg)
53 CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD
)
55 //{{AFX_DATA_INIT(CAboutDlg)
59 void CAboutDlg::DoDataExchange(CDataExchange
* pDX
)
61 CDialog::DoDataExchange(pDX
);
62 //{{AFX_DATA_MAP(CAboutDlg)
66 BEGIN_MESSAGE_MAP(CAboutDlg
, CDialog
)
67 //{{AFX_MSG_MAP(CAboutDlg)
68 // No message handlers
73 void MFCMessageCallback(const char* m
, const char* title
, bool& nomore
, void*)
75 std::string message
= m
;
76 message
+= "\n\n(Press Cancel to suppress any further messages.)";
77 if(::MessageBox(0, message
.c_str(), title
,
78 MB_OKCANCEL
|MB_TASKMODAL
) == IDCANCEL
)
84 /////////////////////////////////////////////////////////////////////////////
85 // CMakeSetupDialog dialog
86 void updateProgress(const char *msg
, float prog
, void *cd
)
88 char* tmp
= new char[strlen(msg
) + 40];
91 sprintf(tmp
,"%s %i%%",msg
,(int)(100*prog
));
95 sprintf(tmp
,"%s",msg
);
97 CMakeSetupDialog
*self
= (CMakeSetupDialog
*)cd
;
98 self
->SetDlgItemText(IDC_PROGRESS
, tmp
);
99 CWnd
* cancel
= self
->GetDlgItem(IDCANCEL
);
101 // Retrieve and dispatch any waiting messages.
104 while (::PeekMessage (&wmsg
, NULL
, 0, 0, PM_REMOVE
))
110 case WM_LBUTTONDBLCLK
:
112 if(wmsg
.hwnd
== cancel
->m_hWnd
)
114 ::DispatchMessage(&wmsg
);
121 ::DispatchMessage(&wmsg
);
128 // Convert to Win32 path (slashes). This calls the system tools one and then
129 // removes the spaces. It is not in system tools because we don't want any
130 // generators accidentally use it
131 std::string
ConvertToWindowsPath(const char* path
)
133 // Convert to output path.
134 // Remove the "" around it (if any) since it's an output path for
135 // the shell. If another shell-oriented feature is not designed
136 // for a GUI use, then we are in trouble.
137 // save the value of the force to unix path option
138 bool saveForce
= cmSystemTools::GetForceUnixPaths();
139 // make sure we get windows paths no matter what for the GUI
140 cmSystemTools::SetForceUnixPaths(false);
141 std::string s
= cmSystemTools::ConvertToOutputPath(path
);
142 // now restore the force unix path to its previous value
143 cmSystemTools::SetForceUnixPaths(saveForce
);
146 std::string::iterator i
= s
.begin();
151 i
= s
.begin() + s
.length() - 1;
160 CMakeSetupDialog::CMakeSetupDialog(const CMakeCommandLineInfo
& cmdInfo
,
161 CWnd
* pParent
/*=NULL*/)
162 : CDialog(CMakeSetupDialog::IDD
, pParent
)
164 m_GeneratorPicked
= false;
165 m_Cursor
= LoadCursor(NULL
, IDC_ARROW
);
166 m_RunningConfigure
= false;
167 cmSystemTools::SetRunCommandHideConsole(true);
168 cmSystemTools::SetErrorCallback(MFCMessageCallback
);
169 m_RegistryKey
= "Software\\Kitware\\CMakeSetup\\Settings\\StartPath";
170 m_CacheEntriesList
.m_CMakeSetupDialog
= this;
172 m_CMakeInstance
= new cmake
;
173 m_CMakeInstance
->SetCMakeEditCommand("CMakeSetup");
174 m_CMakeInstance
->SetProgressCallback(updateProgress
, (void *)this);
176 //{{AFX_DATA_INIT(CMakeSetupDialog)
179 // Get the parameters from the command line info
180 // If an unknown parameter is found, try to interpret it too, since it
181 // is likely to be a file dropped on the shortcut :)
182 if (cmdInfo
.m_LastUnknownParameter
.IsEmpty())
184 this->m_WhereSource
= cmdInfo
.m_WhereSource
;
185 this->m_WhereBuild
= cmdInfo
.m_WhereBuild
;
186 this->m_GeneratorDialog
.m_GeneratorChoiceString
=
187 cmdInfo
.m_GeneratorChoiceString
;
188 this->m_AdvancedValues
= cmdInfo
.m_AdvancedValues
;
192 this->m_WhereSource
= _T("");
193 this->m_WhereBuild
= _T("");
194 this->m_AdvancedValues
= FALSE
;
195 this->m_GeneratorDialog
.m_GeneratorChoiceString
=
196 cmdInfo
.m_GeneratorChoiceString
;
197 this->ChangeDirectoriesFromFile((LPCTSTR
)cmdInfo
.m_LastUnknownParameter
);
200 // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
201 m_hIcon
= AfxGetApp()->LoadIcon(IDR_MAINFRAME
);
202 m_BuildPathChanged
= false;
203 // Find the path to the cmake.exe executable
205 ::GetModuleFileName(NULL
,fname
,1023);
206 // extract just the path part
207 m_PathToExecutable
= cmSystemTools::GetProgramPath(fname
).c_str();
208 // add the cmake.exe to the path
209 m_PathToExecutable
+= "/cmake.exe";
212 m_deltaXRemainder
= 0;
215 CMakeSetupDialog::~CMakeSetupDialog()
217 delete m_CMakeInstance
;
219 cmDynamicLoader::FlushCache();
222 void CMakeSetupDialog::DoDataExchange(CDataExchange
* pDX
)
224 CDialog::DoDataExchange(pDX
);
225 //{{AFX_DATA_MAP(CMakeSetupDialog)
226 DDX_Control(pDX
, IDC_AdvancedValues
, m_AdvancedValuesControl
);
227 DDX_Control(pDX
, IDC_SUPPRESS_DEV_WARNINGS
, m_SuppressDevWarningsControl
);
228 DDX_Check(pDX
, IDC_SUPPRESS_DEV_WARNINGS
, m_SuppressDevValue
);
229 DDX_Control(pDX
, IDC_BROWSE_SOURCE
, m_BrowseSource
);
230 DDX_Control(pDX
, IDC_BROWSE_BUILD
, m_BrowseBuild
);
231 DDX_Control(pDX
, IDC_DELETE_BUTTON
, m_DeleteButton
);
232 DDX_Control(pDX
, IDC_HELP_BUTTON
, m_HelpButton
);
233 DDX_Control(pDX
, IDC_OK
, m_OKButton
);
234 DDX_Control(pDX
, IDCANCEL
, m_CancelButton
);
235 DDX_CBStringExact(pDX
, IDC_WhereSource
, m_WhereSource
);
236 DDX_CBStringExact(pDX
, IDC_WhereBuild
, m_WhereBuild
);
237 DDX_Control(pDX
, IDC_FRAME
, m_ListFrame
);
238 DDX_Control(pDX
, IDC_WhereSource
, m_WhereSourceControl
);
239 DDX_Control(pDX
, IDC_WhereBuild
, m_WhereBuildControl
);
240 DDX_Control(pDX
, IDC_LIST2
, m_CacheEntriesList
);
241 DDX_Control(pDX
, IDC_MouseHelpCaption
, m_MouseHelp
);
242 DDX_Control(pDX
, IDC_PROGRESS
, m_StatusDisplay
);
243 DDX_Control(pDX
, IDC_BuildProjects
, m_Configure
);
244 DDX_Check(pDX
, IDC_AdvancedValues
, m_AdvancedValues
);
248 BEGIN_MESSAGE_MAP(CMakeSetupDialog
, CDialog
)
249 //{{AFX_MSG_MAP(CMakeSetupDialog)
252 ON_WM_QUERYDRAGICON()
253 ON_BN_CLICKED(IDC_BUTTON2
, OnBrowseWhereSource
)
254 ON_BN_CLICKED(IDC_BuildProjects
, OnConfigure
)
255 ON_BN_CLICKED(IDC_BUTTON3
, OnBrowseWhereBuild
)
256 ON_CBN_EDITCHANGE(IDC_WhereBuild
, OnChangeWhereBuild
)
257 ON_CBN_SELCHANGE(IDC_WhereBuild
, OnSelendokWhereBuild
)
258 ON_CBN_EDITCHANGE(IDC_WhereSource
, OnChangeWhereSource
)
259 ON_CBN_SELENDOK(IDC_WhereSource
, OnSelendokWhereSource
)
261 ON_WM_GETMINMAXINFO()
262 ON_BN_CLICKED(IDC_OK
, OnOk
)
263 ON_BN_CLICKED(IDC_DELETE_BUTTON
, OnDeleteButton
)
264 ON_BN_CLICKED(IDC_HELP_BUTTON
, OnHelpButton
)
265 ON_BN_CLICKED(IDC_AdvancedValues
, OnAdvancedValues
)
266 ON_BN_CLICKED(IDC_SUPPRESS_DEV_WARNINGS
, OnSuppressDevValue
)
267 ON_BN_DOUBLECLICKED(IDC_SUPPRESS_DEV_WARNINGS
, OnDoubleclickedSuppressDevValue
)
268 ON_BN_DOUBLECLICKED(IDC_AdvancedValues
, OnDoubleclickedAdvancedValues
)
270 ON_BN_CLICKED(IDCANCEL
, OnCancel
)
275 /////////////////////////////////////////////////////////////////////////////
276 // CMakeSetupDialog message handlers
278 BOOL
CMakeSetupDialog::OnInitDialog()
280 CDialog::OnInitDialog();
281 this->DragAcceptFiles(true);
283 // Add "Create shortcut" menu item to system menu.
285 // IDM_CREATESHORTCUT must be in the system command range.
286 ASSERT((IDM_CREATESHORTCUT
& 0xFFF0) == IDM_CREATESHORTCUT
);
287 ASSERT(IDM_CREATESHORTCUT
< 0xF000);
289 // Add "About..." menu item to system menu.
291 // IDM_ABOUTBOX must be in the system command range.
292 ASSERT((IDM_ABOUTBOX
& 0xFFF0) == IDM_ABOUTBOX
);
293 ASSERT(IDM_ABOUTBOX
< 0xF000);
295 CMenu
* pSysMenu
= GetSystemMenu(FALSE
);
296 if (pSysMenu
!= NULL
)
298 CString strCreateShortcutMenu
;
299 strCreateShortcutMenu
.LoadString(IDS_CREATESHORTCUT
);
300 if (!strCreateShortcutMenu
.IsEmpty())
302 pSysMenu
->AppendMenu(MF_SEPARATOR
);
303 pSysMenu
->AppendMenu(MF_STRING
,
305 strCreateShortcutMenu
);
308 CString strAboutMenu
;
309 strAboutMenu
.LoadString(IDS_ABOUTBOX
);
310 if (!strAboutMenu
.IsEmpty())
312 pSysMenu
->AppendMenu(MF_SEPARATOR
);
313 pSysMenu
->AppendMenu(MF_STRING
,
319 // Set the icon for this dialog. The framework does this automatically
320 // when the application's main window is not a dialog
321 SetIcon(m_hIcon
, TRUE
); // Set big icon
322 SetIcon(m_hIcon
, FALSE
); // Set small icon
323 // Load source and build dirs from registry
324 this->LoadFromRegistry();
326 // try to load the cmake cache from disk
327 this->LoadCacheFromDiskToGUI();
328 m_WhereBuildControl
.LimitText(2048);
329 m_WhereSourceControl
.LimitText(2048);
331 // Set the version number
333 sprintf(tmp
,"CMake %s", cmVersion::GetCMakeVersion());
334 SetDlgItemText(IDC_PROGRESS
, "");
335 this->SetWindowText(tmp
);
336 this->UpdateData(FALSE
);
337 return TRUE
; // return TRUE unless you set the focus to a control
341 // About dialog invoke
342 void CMakeSetupDialog::OnSysCommand(UINT nID
, LPARAM lParam
)
344 if ((nID
& 0xFFF0) == IDM_ABOUTBOX
)
349 else if ((nID
& 0xFFF0) == IDM_CREATESHORTCUT
)
355 CDialog::OnSysCommand(nID
, lParam
);
359 // If you add a minimize button to your dialog, you will need the code below
360 // to draw the icon. For MFC applications using the document/view model,
361 // this is automatically done for you by the framework.
363 void CMakeSetupDialog::OnPaint()
367 CPaintDC
dc(this); // device context for painting
369 SendMessage(WM_ICONERASEBKGND
, (WPARAM
) dc
.GetSafeHdc(), 0);
371 // Center icon in client rectangle
372 int cxIcon
= GetSystemMetrics(SM_CXICON
);
373 int cyIcon
= GetSystemMetrics(SM_CYICON
);
375 GetClientRect(&rect
);
376 int x
= (rect
.Width() - cxIcon
+ 1) / 2;
377 int y
= (rect
.Height() - cyIcon
+ 1) / 2;
380 dc
.DrawIcon(x
, y
, m_hIcon
);
388 // The system calls this to obtain the cursor to display while the user drags
389 // the minimized window.
390 HCURSOR
CMakeSetupDialog::OnQueryDragIcon()
392 return (HCURSOR
) m_hIcon
;
398 bool CMakeSetupDialog::Browse(CString
&result
, const char *title
)
400 CString initialDir
= result
;
401 initialDir
.Replace("/", "\\");
402 CPathDialog
dlg("Select Path", title
, initialDir
);
403 if(dlg
.DoModal()==IDOK
)
405 result
= dlg
.GetPathName();
417 void CMakeSetupDialog::SaveToRegistry()
422 if(RegCreateKeyEx(HKEY_CURRENT_USER
,
424 0, "", REG_OPTION_NON_VOLATILE
, KEY_READ
|KEY_WRITE
,
425 NULL
, &hKey
, &dwDummy
) != ERROR_SUCCESS
)
434 // write the size of the dialog
436 this->GetWindowRect(&size
);
437 unsigned long width
= size
.Width();
438 unsigned long height
= size
.Height();
439 RegSetValueEx(hKey
, _T("Width"), 0, REG_DWORD
,
440 (CONST BYTE
*)(&width
),4);
441 RegSetValueEx(hKey
, _T("Height"), 0, REG_DWORD
,
442 (CONST BYTE
*)(&height
),4);
444 this->ReadRegistryValue(hKey
, &(regvalue
),"WhereSource1","C:\\");
446 if(m_WhereSource
!= regvalue
)
451 for (i
= 2; i
< 10; ++i
)
454 sprintf(keyName
,"WhereSource%i",i
);
455 this->ReadRegistryValue(hKey
, &(regvalue
),keyName
,"");
456 // check for short circuit, if the new value is already in
457 // the list then we stop
458 if (m_WhereSource
== regvalue
)
464 for (i
= shiftEnd
; i
; --i
)
467 sprintf(keyName
,"WhereSource%i",i
);
468 sprintf(keyName2
,"WhereSource%i",i
+1);
470 this->ReadRegistryValue(hKey
, &(regvalue
),keyName
,"");
471 if (strlen(regvalue
))
473 RegSetValueEx(hKey
, _T(keyName2
), 0, REG_SZ
,
474 (CONST BYTE
*)(const char *)regvalue
,
475 regvalue
.GetLength());
478 RegSetValueEx(hKey
, _T("WhereSource1"), 0, REG_SZ
,
479 (CONST BYTE
*)(const char *)m_WhereSource
,
480 m_WhereSource
.GetLength());
483 this->ReadRegistryValue(hKey
, &(regvalue
),"WhereBuild1","C:\\");
484 if(m_WhereBuild
!= regvalue
)
489 for (i
= 2; i
< 10; ++i
)
492 sprintf(keyName
,"WhereBuild%i",i
);
493 this->ReadRegistryValue(hKey
, &(regvalue
),keyName
,"");
494 // check for short circuit, if the new value is already in
495 // the list then we stop
496 if (m_WhereBuild
== regvalue
)
501 for (i
= shiftEnd
; i
; --i
)
504 sprintf(keyName
,"WhereBuild%i",i
);
505 sprintf(keyName2
,"WhereBuild%i",i
+1);
507 this->ReadRegistryValue(hKey
, &(regvalue
),keyName
,"");
508 if (strlen(regvalue
))
510 RegSetValueEx(hKey
, _T(keyName2
), 0, REG_SZ
,
511 (CONST BYTE
*)(const char *)regvalue
,
512 regvalue
.GetLength());
515 RegSetValueEx(hKey
, _T("WhereBuild1"), 0, REG_SZ
,
516 (CONST BYTE
*)(const char *)m_WhereBuild
,
517 m_WhereBuild
.GetLength());
524 void CMakeSetupDialog::ReadRegistryValue(HKEY hKey
,
527 const char *adefault
)
529 DWORD dwType
, dwSize
;
533 pb
= val
->GetBuffer(MAX_PATH
);
535 if(RegQueryValueEx(hKey
,_T(key
), NULL
, &dwType
,
536 (BYTE
*)pb
, &dwSize
) != ERROR_SUCCESS
)
538 val
->ReleaseBuffer();
543 val
->ReleaseBuffer();
548 void CMakeSetupDialog::LoadFromRegistry()
551 if(RegOpenKeyEx(HKEY_CURRENT_USER
,
553 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
563 if (RegQueryValueEx(hKey
,_T("Width"), NULL
, NULL
,
564 (BYTE
*)&width
, &dwSize
) == ERROR_SUCCESS
&&
565 RegQueryValueEx(hKey
,_T("Height"), NULL
, NULL
,
566 (BYTE
*)&height
, &dwSize
) == ERROR_SUCCESS
)
568 this->SetWindowPos(0,0,0,width
,height
,SWP_NOZORDER
| SWP_NOMOVE
);
571 if (m_WhereSource
.IsEmpty())
573 this->ReadRegistryValue(hKey
, &(m_WhereSource
),"WhereSource1","C:\\");
575 if (m_WhereBuild
.IsEmpty())
577 this->ReadRegistryValue(hKey
, &(m_WhereBuild
),"WhereBuild1","C:\\");
579 m_WhereSourceControl
.AddString(m_WhereSource
);
580 m_WhereBuildControl
.AddString(m_WhereBuild
);
585 for (i
= 2; i
<= 10; ++i
)
587 sprintf(keyname
,"WhereSource%i",i
);
589 this->ReadRegistryValue(hKey
, &(regvalue
),keyname
,"C:\\");
590 if (strcmp("C:\\",regvalue
))
592 m_WhereSourceControl
.AddString(regvalue
);
594 sprintf(keyname
,"WhereBuild%i",i
);
596 this->ReadRegistryValue(hKey
, &(regvalue
),keyname
,"C:\\");
597 if (strcmp("C:\\",regvalue
))
599 m_WhereBuildControl
.AddString(regvalue
);
608 // Callback for browse source button
609 void CMakeSetupDialog::OnBrowseWhereSource()
612 Browse(m_WhereSource
, "Enter Path to Source");
613 this->UpdateData(false);
614 this->OnChangeWhereSource();
617 // Callback for browser build button
618 void CMakeSetupDialog::OnBrowseWhereBuild()
621 Browse(m_WhereBuild
, "Enter Path to Build");
622 this->UpdateData(false);
623 this->OnChangeWhereBuild();
626 void CMakeSetupDialog::RunCMake(bool generateProjectFiles
)
628 if(!cmSystemTools::FileExists(m_WhereBuild
))
630 std::string message
=
631 "Build directory does not exist, should I create it?\n\n"
633 message
+= (const char*)m_WhereBuild
;
634 if(MessageBox(message
.c_str(), "Create Directory", MB_OKCANCEL
) == IDOK
)
636 cmSystemTools::MakeDirectory(m_WhereBuild
);
640 MessageBox("Build Project aborted, nothing done.");
644 // set the wait cursor
645 m_Cursor
= LoadCursor(NULL
, IDC_WAIT
);
646 ::SetCursor(m_Cursor
);
647 m_RunningConfigure
= true;
649 // get all the info from the dialog
651 // always save the current gui values to disk
652 this->SaveCacheFromGUI();
653 // Make sure we are working from the cache on disk
654 this->LoadCacheFromDiskToGUI();
655 m_OKButton
.EnableWindow(false);
657 // setup the cmake instance
658 if (generateProjectFiles
)
660 if(m_CMakeInstance
->Generate() != 0)
662 cmSystemTools::Error(
663 "Error in generation process, project files may be invalid");
668 m_CMakeInstance
->SetHomeDirectory(m_WhereSource
);
669 m_CMakeInstance
->SetStartDirectory(m_WhereSource
);
670 m_CMakeInstance
->SetHomeOutputDirectory(m_WhereBuild
);
671 m_CMakeInstance
->SetStartOutputDirectory(m_WhereBuild
);
672 m_CMakeInstance
->SetGlobalGenerator(
673 m_CMakeInstance
->CreateGlobalGenerator(m_GeneratorDialog
.m_GeneratorChoiceString
));
674 m_CMakeInstance
->SetCMakeCommand(m_PathToExecutable
);
675 m_CMakeInstance
->LoadCache();
676 if(m_SuppressDevValue
)
678 m_CMakeInstance
->SetSuppressDevWarnings(true);
682 m_CMakeInstance
->SetSuppressDevWarnings(false);
684 if(m_CMakeInstance
->Configure() != 0)
686 cmSystemTools::Error(
687 "Error in configuration process, project files may be invalid");
689 // update the GUI with any new values in the caused by the
690 // generation process
691 this->LoadCacheFromDiskToGUI();
694 // save source and build paths to registry
695 this->SaveToRegistry();
696 // path is up-to-date now
697 m_BuildPathChanged
= false;
698 // put the cursor back
699 m_Cursor
= LoadCursor(NULL
, IDC_ARROW
);
700 ::SetCursor(m_Cursor
);
701 m_RunningConfigure
= false;
702 cmSystemTools::ResetErrorOccuredFlag();
706 // Callback for build projects button
707 void CMakeSetupDialog::OnConfigure()
709 if(!m_GeneratorPicked
)
711 m_GeneratorDialog
.m_CMakeInstance
= this->m_CMakeInstance
;
712 if(m_GeneratorDialog
.DoModal() != IDOK
)
716 // save the generator choice in the registry
720 if(RegCreateKeyEx(HKEY_CURRENT_USER
,
722 0, "", REG_OPTION_NON_VOLATILE
, KEY_READ
|KEY_WRITE
,
723 NULL
, &hKey
, &dwDummy
) == ERROR_SUCCESS
)
726 RegSetValueEx(hKey
, _T("LastGenerator"), 0, REG_SZ
,
727 (CONST BYTE
*)(const char *)m_GeneratorDialog
.m_GeneratorChoiceString
,
728 m_GeneratorDialog
.m_GeneratorChoiceString
.GetLength());
732 // enable error messages each time configure is pressed
733 cmSystemTools::EnableMessages();
734 this->RunCMake(false);
740 // callback for combo box menu where build selection
741 void CMakeSetupDialog::OnSelendokWhereBuild()
743 m_WhereBuildControl
.GetLBText(m_WhereBuildControl
.GetCurSel(),
745 m_WhereBuildControl
.SetWindowText( m_WhereBuild
);
746 this->UpdateData(FALSE
);
747 this->OnChangeWhereBuild();
750 // callback for combo box menu where source selection
751 void CMakeSetupDialog::OnSelendokWhereSource()
753 m_WhereSourceControl
.GetLBText(m_WhereSourceControl
.GetCurSel(),
755 this->UpdateData(FALSE
);
756 this->OnChangeWhereSource();
759 // callback for chaing source directory
760 void CMakeSetupDialog::OnChangeWhereSource()
764 // callback for changing the build directory
765 void CMakeSetupDialog::OnChangeWhereBuild()
769 // The build dir has changed, check if there is a cache, and
770 // grab the source dir from it
772 std::string path
= this->m_WhereBuild
;
773 cmSystemTools::ConvertToUnixSlashes(path
);
775 // adjust the cmake instance
776 m_CMakeInstance
->SetHomeOutputDirectory(m_WhereBuild
);
777 m_CMakeInstance
->SetStartOutputDirectory(m_WhereBuild
);
779 std::string cache_file
= path
;
780 cache_file
+= "/CMakeCache.txt";
782 cmCacheManager
*cachem
= this->m_CMakeInstance
->GetCacheManager();
783 cmCacheManager::CacheIterator it
= cachem
->NewIterator();
785 m_GeneratorPicked
= false;
787 // make sure we have a normal cache file, specifically if one exists make
788 // sure it can be read
789 if (cmSystemTools::FileExists(cache_file
.c_str()))
791 if (cachem
->LoadCache(path
.c_str()))
793 if (it
.Find("CMAKE_HOME_DIRECTORY"))
795 path
= ConvertToWindowsPath(it
.GetValue());
796 this->m_WhereSource
= path
.c_str();
797 this->m_WhereSourceControl
.SetWindowText(this->m_WhereSource
);
798 this->OnChangeWhereSource();
799 m_GeneratorPicked
= true;
804 //file exists but cqnnot be read
805 cmSystemTools::Error("There is a CMakeCache.txt file for the current binary tree but cmake does not have permission to read it. Please check the permissions of the directory you are trying to run CMake on.");
810 m_CacheEntriesList
.RemoveAll();
811 m_CacheEntriesList
.ShowWindow(SW_SHOW
);
812 this->LoadCacheFromDiskToGUI();
813 m_BuildPathChanged
= true;
817 // copy from the cache manager to the cache edit list box
818 void CMakeSetupDialog::FillCacheGUIFromCacheManager()
820 cmCacheManager
*cachem
= this->m_CMakeInstance
->GetCacheManager();
821 cmCacheManager::CacheIterator it
= cachem
->NewIterator();
823 // if there are already entries in the cache, then
824 // put the new ones in the top, so they show up first
825 bool reverseOrder
= false;
826 // all the current values are not new any more
827 std::set
<CPropertyItem
*> items
= m_CacheEntriesList
.GetItems();
828 for(std::set
<CPropertyItem
*>::iterator i
= items
.begin();
829 i
!= items
.end(); ++i
)
831 // first check to see if it is still in the cache
832 CPropertyItem
* item
= *i
;
833 if ( !it
.Find((const char*)item
->m_propName
) )
835 m_CacheEntriesList
.RemoveProperty((const char*)item
->m_propName
);
839 // if it is still in the cache then it is no longer new
840 item
->m_NewValue
= false;
843 for(cmCacheManager::CacheIterator i
= cachem
->NewIterator();
844 !i
.IsAtEnd(); i
.Next())
846 const char* key
= i
.GetName();
848 // if value has trailing space or tab, enclose it in single quotes
849 // to enforce the fact that it has 'invisible' trailing stuff
850 std::string value
= i
.GetValue();
852 (value
[value
.size() - 1] == ' ' ||
853 value
[value
.size() - 1] == '\t'))
855 value
= '\'' + value
+ '\'';
857 bool advanced
= i
.GetPropertyAsBool("ADVANCED");
860 case cmCacheManager::BOOL
:
861 if(cmSystemTools::IsOn(value
.c_str()))
863 m_CacheEntriesList
.AddProperty(key
,
865 i
.GetProperty("HELPSTRING"),
866 CPropertyList::COMBO
,"ON|OFF",
873 m_CacheEntriesList
.AddProperty(key
,
875 i
.GetProperty("HELPSTRING"),
876 CPropertyList::COMBO
,"ON|OFF",
877 reverseOrder
, advanced
881 case cmCacheManager::PATH
:
882 m_CacheEntriesList
.AddProperty(key
,
884 i
.GetProperty("HELPSTRING"),
885 CPropertyList::PATH
,"",
886 reverseOrder
, advanced
889 case cmCacheManager::FILEPATH
:
890 m_CacheEntriesList
.AddProperty(key
,
892 i
.GetProperty("HELPSTRING"),
893 CPropertyList::FILE,"",
894 reverseOrder
, advanced
897 case cmCacheManager::STRING
:
898 m_CacheEntriesList
.AddProperty(key
,
900 i
.GetProperty("HELPSTRING"),
901 CPropertyList::EDIT
,"",
902 reverseOrder
, advanced
905 case cmCacheManager::INTERNAL
:
906 m_CacheEntriesList
.RemoveProperty(key
);
910 if(m_CacheEntriesList
.GetShowAdvanced())
912 m_CacheEntriesList
.ShowAdvanced();
916 m_CacheEntriesList
.HideAdvanced();
919 m_OKButton
.EnableWindow(false);
920 if(cachem
->GetSize() > 0 && !cmSystemTools::GetErrorOccuredFlag())
923 items
= m_CacheEntriesList
.GetItems();
924 for(std::set
<CPropertyItem
*>::iterator i
= items
.begin();
925 i
!= items
.end(); ++i
)
927 CPropertyItem
* item
= *i
;
928 if(item
->m_Advanced
)
930 if(item
->m_NewValue
&& m_CacheEntriesList
.GetShowAdvanced())
940 // if one new value then disable to OK button
948 m_OKButton
.EnableWindow(true);
953 m_CacheEntriesList
.SetTopIndex(0);
954 m_CacheEntriesList
.Invalidate();
957 // copy from the list box to the cache manager
958 void CMakeSetupDialog::FillCacheManagerFromCacheGUI()
960 cmCacheManager
*cachem
= this->m_CMakeInstance
->GetCacheManager();
961 std::set
<CPropertyItem
*> items
= m_CacheEntriesList
.GetItems();
962 cmCacheManager::CacheIterator it
= cachem
->NewIterator();
963 for(std::set
<CPropertyItem
*>::iterator i
= items
.begin();
964 i
!= items
.end(); ++i
)
966 CPropertyItem
* item
= *i
;
967 if ( it
.Find((const char*)item
->m_propName
) )
969 // if value is enclosed in single quotes ('foo') then remove them
970 // they were used to enforce the fact that it had 'invisible'
972 if (item
->m_curValue
.GetLength() >= 2 &&
973 item
->m_curValue
[0] == '\'' &&
974 item
->m_curValue
[item
->m_curValue
.GetLength() - 1] == '\'')
976 it
.SetValue(item
->m_curValue
.Mid(
977 1, item
->m_curValue
.GetLength() - 2));
981 it
.SetValue(item
->m_curValue
);
989 //! Load cache file from m_WhereBuild and display in GUI editor
990 void CMakeSetupDialog::LoadCacheFromDiskToGUI()
992 cmCacheManager
*cachem
= this->m_CMakeInstance
->GetCacheManager();
993 if(m_WhereBuild
!= "")
995 if (!cachem
->LoadCache(m_WhereBuild
))
997 // if it does exist, but isn;t readable then warn the user
998 std::string cacheFile
= m_WhereBuild
;
999 cacheFile
+= "/CMakeCache.txt";
1000 if(cmSystemTools::FileExists(cacheFile
.c_str()))
1002 cmSystemTools::Error("There is a CMakeCache.txt file for the current binary tree but cmake does not have permission to read it. Please check the permissions of the directory you are trying to run CMake on.");
1006 cmCacheManager::CacheIterator itm
= cachem
->NewIterator();
1007 if ( itm
.Find("CMAKE_HOME_DIRECTORY"))
1009 std::string path
= ConvertToWindowsPath(itm
.GetValue());
1010 this->m_WhereSource
= path
.c_str();
1011 this->m_WhereSourceControl
.SetWindowText(this->m_WhereSource
);
1012 this->OnChangeWhereSource();
1014 m_CMakeInstance
->SetHomeDirectory(m_WhereSource
);
1015 m_CMakeInstance
->SetStartDirectory(m_WhereSource
);
1016 m_CMakeInstance
->SetHomeOutputDirectory(m_WhereBuild
);
1017 m_CMakeInstance
->SetStartOutputDirectory(m_WhereBuild
);
1018 m_CMakeInstance
->PreLoadCMakeFiles();
1019 this->FillCacheGUIFromCacheManager();
1020 cmCacheManager::CacheIterator it
=
1021 cachem
->GetCacheIterator("CMAKE_GENERATOR");
1024 m_GeneratorPicked
= true;
1025 const char* extraGen
= cachem
->GetCacheValue("CMAKE_EXTRA_GENERATOR");
1026 std::string curGen
= cmExternalMakefileProjectGenerator::
1027 CreateFullGeneratorName(it
.GetValue(), extraGen
);
1029 if(m_GeneratorDialog
.m_GeneratorChoiceString
!= curGen
.c_str())
1031 m_GeneratorDialog
.m_GeneratorChoiceString
= curGen
.c_str();
1032 this->UpdateData(FALSE
);
1038 //! Save GUI values to cmCacheManager and then save to disk.
1039 void CMakeSetupDialog::SaveCacheFromGUI()
1041 cmCacheManager
*cachem
= this->m_CMakeInstance
->GetCacheManager();
1042 this->FillCacheManagerFromCacheGUI();
1043 if(m_WhereBuild
!= "")
1045 cachem
->SaveCache(m_WhereBuild
);
1050 void CMakeSetupDialog::OnSize(UINT nType
, int cx
, int cy
)
1052 if (nType
== SIZE_MINIMIZED
)
1054 CDialog::OnSize(nType
, cx
, cy
);
1062 int deltax
= cx
- m_oldCX
;
1063 int deltay
= cy
- m_oldCY
;
1068 CDialog::OnSize(nType
, cx
, cy
);
1070 if (deltax
== 0 && deltay
== 0)
1075 if(m_CacheEntriesList
.m_hWnd
)
1077 // get the original sizes/positions
1079 m_AdvancedValuesControl
.GetWindowRect(&cRect
);
1080 this->ScreenToClient(&cRect
);
1081 m_AdvancedValuesControl
.SetWindowPos(&wndTop
, cRect
.left
+ deltax
,
1085 SWP_NOSIZE
| SWP_NOZORDER
);
1086 m_SuppressDevWarningsControl
.GetWindowRect(&cRect
);
1087 this->ScreenToClient(&cRect
);
1088 m_SuppressDevWarningsControl
.SetWindowPos(&wndTop
, cRect
.left
+ deltax
,
1092 SWP_NOSIZE
| SWP_NOZORDER
);
1093 m_BrowseSource
.GetWindowRect(&cRect
);
1094 this->ScreenToClient(&cRect
);
1095 m_BrowseSource
.SetWindowPos(&wndTop
, cRect
.left
+ deltax
,
1098 SWP_NOCOPYBITS
| SWP_NOSIZE
| SWP_NOZORDER
);
1099 m_BrowseBuild
.GetWindowRect(&cRect
);
1100 this->ScreenToClient(&cRect
);
1101 m_BrowseBuild
.SetWindowPos(&wndTop
, cRect
.left
+ deltax
,
1104 SWP_NOCOPYBITS
| SWP_NOSIZE
| SWP_NOZORDER
);
1106 m_WhereSourceControl
.GetWindowRect(&cRect
);
1107 m_WhereSourceControl
.SetWindowPos(&wndTop
, cRect
.left
, cRect
.top
,
1108 cRect
.Width() + deltax
,
1111 SWP_NOMOVE
| SWP_NOZORDER
);
1112 m_WhereBuildControl
.GetWindowRect(&cRect
);
1113 m_WhereBuildControl
.SetWindowPos(&wndTop
, cRect
.left
, cRect
.top
,
1114 cRect
.Width() + deltax
,
1117 SWP_NOMOVE
| SWP_NOZORDER
);
1118 m_ListFrame
.GetWindowRect(&cRect
);
1119 m_ListFrame
.SetWindowPos(&wndTop
, cRect
.left
, cRect
.top
,
1120 cRect
.Width() + deltax
,
1121 cRect
.Height() + deltay
,
1122 SWP_NOCOPYBITS
| SWP_NOMOVE
| SWP_NOZORDER
);
1123 m_CacheEntriesList
.GetWindowRect(&cRect
);
1124 m_CacheEntriesList
.SetWindowPos(&wndTop
, cRect
.left
, cRect
.top
,
1125 cRect
.Width() + deltax
,
1126 cRect
.Height() + deltay
,
1127 SWP_NOCOPYBITS
| SWP_NOMOVE
| SWP_NOZORDER
);
1129 m_StatusDisplay
.GetWindowRect(&cRect
);
1130 this->ScreenToClient(&cRect
);
1131 m_StatusDisplay
.SetWindowPos(&wndBottom
, cRect
.left
,
1133 cRect
.Width() + deltax
, cRect
.Height(),
1136 m_MouseHelp
.GetWindowRect(&cRect
);
1137 this->ScreenToClient(&cRect
);
1138 m_MouseHelp
.SetWindowPos(&wndTop
, cRect
.left
,
1140 cRect
.Width() + deltax
, cRect
.Height(),
1141 SWP_NOCOPYBITS
| SWP_NOZORDER
);
1143 deltax
= int(deltax
+ m_deltaXRemainder
);
1144 m_deltaXRemainder
= float(deltax
%2);
1147 m_Configure
.GetWindowRect(&cRect
);
1148 this->ScreenToClient(&cRect
);
1149 m_Configure
.SetWindowPos(&wndTop
, cRect
.left
+ deltax
/2,
1152 SWP_NOCOPYBITS
| SWP_NOSIZE
);
1153 m_CancelButton
.GetWindowRect(&cRect
);
1154 this->ScreenToClient(&cRect
);
1155 m_CancelButton
.SetWindowPos(&wndTop
, cRect
.left
+ deltax
/2,
1158 SWP_NOCOPYBITS
| SWP_NOSIZE
);
1159 m_OKButton
.GetWindowRect(&cRect
);
1160 this->ScreenToClient(&cRect
);
1161 m_OKButton
.SetWindowPos(&wndTop
, cRect
.left
+ deltax
/2,
1164 SWP_NOCOPYBITS
| SWP_NOSIZE
);
1165 m_DeleteButton
.GetWindowRect(&cRect
);
1166 this->ScreenToClient(&cRect
);
1167 m_DeleteButton
.SetWindowPos(&wndTop
, cRect
.left
+ deltax
/2,
1170 SWP_NOCOPYBITS
| SWP_NOSIZE
);
1171 m_HelpButton
.GetWindowRect(&cRect
);
1172 this->ScreenToClient(&cRect
);
1173 m_HelpButton
.SetWindowPos(&wndTop
, cRect
.left
+ deltax
/2,
1176 SWP_NOCOPYBITS
| SWP_NOSIZE
);
1182 void CMakeSetupDialog::OnGetMinMaxInfo( MINMAXINFO FAR
* lpMMI
)
1184 lpMMI
->ptMinTrackSize
.x
= 550;
1185 lpMMI
->ptMinTrackSize
.y
= 272;
1188 void CMakeSetupDialog::OnCancel()
1190 if(m_RunningConfigure
)
1192 if(MessageBox("You are in the middle of a Configure.\n"
1193 "If you Cancel now the configure information will be lost.\n"
1194 "Are you sure you want to Cancel?", "Confirm Exit",
1197 cmSystemTools::SetFatalErrorOccured();
1201 if(m_CacheEntriesList
.IsDirty())
1203 if(MessageBox("You have changed options but not rebuilt, "
1204 "are you sure you want to exit?", "Confirm Exit",
1216 void CMakeSetupDialog::OnOk()
1218 // enable error messages each time configure is pressed
1219 cmSystemTools::EnableMessages();
1220 m_CacheEntriesList
.ClearDirty();
1221 this->RunCMake(true);
1223 // save the size of the dialog
1226 if (!(::GetKeyState(VK_SHIFT
) & 0x1000))
1232 // Create a shortcut on the desktop with the current Source/Build dir.
1233 int CMakeSetupDialog::CreateShortcut()
1235 // Find the desktop folder and create the link name
1238 if(RegOpenKeyEx(HKEY_CURRENT_USER
,
1239 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
1240 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
1242 AfxMessageBox ("Create shortcut: unable to find 'Shell Folders' key in registry!");
1246 DWORD dwType
, dwSize
;
1247 #define MAXPATH 1024
1248 char link_name
[MAXPATH
];
1250 if(RegQueryValueEx(hKey
,
1255 &dwSize
) != ERROR_SUCCESS
)
1257 AfxMessageBox ("Create shortcut: unable to find 'Desktop' registry value in 'Shell Folders' key!");
1261 if(dwType
!= REG_SZ
)
1263 AfxMessageBox ("Create shortcut: 'Desktop' registry value in 'Shell Folders' key has wrong type!");
1267 strcat(link_name
, "\\CMake - ");
1268 std::string current_dir
= cmSystemTools::GetFilenameName((LPCTSTR
)m_WhereSource
);
1269 strcat(link_name
, current_dir
.c_str());
1270 strcat(link_name
, ".lnk");
1272 // Find the path to the current executable
1274 char path_to_current_exe
[MAXPATH
];
1275 ::GetModuleFileName(NULL
, path_to_current_exe
, MAXPATH
);
1277 // Create the shortcut
1282 // Initialize the COM library
1284 hres
= CoInitialize(NULL
);
1286 if (! SUCCEEDED (hres
))
1288 AfxMessageBox ("Create shortcut: unable to initialize the COM library!");
1292 // Create an IShellLink object and get a pointer to the IShellLink
1293 // interface (returned from CoCreateInstance).
1295 hres
= CoCreateInstance(CLSID_ShellLink
,
1297 CLSCTX_INPROC_SERVER
,
1301 if (! SUCCEEDED (hres
))
1303 AfxMessageBox ("Create shortcut: unable to create IShellLink instance!");
1309 // Query IShellLink for the IPersistFile interface for
1310 // saving the shortcut in persistent storage.
1312 hres
= psl
->QueryInterface(IID_IPersistFile
, (void **)&ppf
);
1314 if (SUCCEEDED (hres
))
1316 // Set the path to the shortcut target.
1317 hres
= psl
->SetPath(path_to_current_exe
);
1319 if (! SUCCEEDED (hres
))
1321 AfxMessageBox ("Create shortcut: SetPath failed!");
1324 // Set the arguments of the shortcut.
1325 CString args
= " /H=\"" + m_WhereSource
+ "\" /B=\"" + m_WhereBuild
+ "\" /G=\"" + m_GeneratorDialog
.m_GeneratorChoiceString
+ "\" /A=\"" + (m_AdvancedValues
? "TRUE" : "FALSE") + "\"";
1327 hres
= psl
->SetArguments(args
);
1329 if (! SUCCEEDED (hres
))
1331 AfxMessageBox ("Create shortcut: SetArguments failed!");
1334 // Set the description of the shortcut.
1335 hres
= psl
->SetDescription("Shortcut to CMakeSetup");
1337 if (! SUCCEEDED (hres
))
1339 AfxMessageBox ("Create shortcut: SetDescription failed!");
1342 // Ensure that the string consists of ANSI characters.
1343 WORD wszAr
[MAX_PATH
];
1344 LPWSTR wsz
= (LPWSTR
)wszAr
;
1345 MultiByteToWideChar(CP_ACP
, 0, link_name
, -1, (LPWSTR
)(wsz
), MAX_PATH
);
1347 // Save the shortcut via the IPersistFile::Save member function.
1348 hres
= ppf
->Save(wsz
, TRUE
);
1350 if (! SUCCEEDED (hres
))
1352 AfxMessageBox ("Create shortcut: Save failed!");
1355 // Release the pointer to IPersistFile.
1358 // Release the pointer to IShellLink.
1364 void CMakeSetupDialog::OnHelpButton()
1370 void CMakeSetupDialog::OnDeleteButton()
1372 std::string message
= "Are you sure you want to delete the CMakeCache.txt file for:\n";
1373 message
+= m_WhereBuild
;
1374 if(::MessageBox(0, message
.c_str(), "Delete Cache?",
1375 MB_YESNO
|MB_TASKMODAL
) == IDNO
)
1379 m_GeneratorPicked
= false;
1381 if(m_WhereBuild
!= "" && this->m_CMakeInstance
)
1383 this->m_CMakeInstance
->GetCacheManager()->DeleteCache(m_WhereBuild
);
1386 // Make sure we are working from the cache on disk
1387 this->LoadCacheFromDiskToGUI();
1389 m_OKButton
.EnableWindow(false);
1392 void CMakeSetupDialog::ShowAdvancedValues()
1394 m_CacheEntriesList
.ShowAdvanced();
1397 void CMakeSetupDialog::RemoveAdvancedValues()
1399 m_CacheEntriesList
.HideAdvanced();
1403 void CMakeSetupDialog::OnSuppressDevValue()
1407 void CMakeSetupDialog::OnDoubleclickedSuppressDevValue()
1409 this->OnSuppressDevValue();
1412 void CMakeSetupDialog::OnAdvancedValues()
1415 if(m_AdvancedValues
)
1417 this->ShowAdvancedValues();
1421 this->RemoveAdvancedValues();
1425 void CMakeSetupDialog::OnDoubleclickedAdvancedValues()
1427 this->OnAdvancedValues();
1430 // Handle param or single dropped file.
1431 void CMakeSetupDialog::ChangeDirectoriesFromFile(const char* arg
)
1433 // Check if the argument refers to a CMakeCache.txt or
1434 // CMakeLists.txt file.
1435 std::string listPath
;
1436 std::string cachePath
;
1437 bool argIsFile
= false;
1438 if(cmSystemTools::FileIsDirectory(arg
))
1440 std::string path
= cmSystemTools::CollapseFullPath(arg
);
1441 cmSystemTools::ConvertToUnixSlashes(path
);
1442 std::string cacheFile
= path
;
1443 cacheFile
+= "/CMakeCache.txt";
1444 std::string listFile
= path
;
1445 listFile
+= "/CMakeLists.txt";
1446 if(cmSystemTools::FileExists(cacheFile
.c_str()))
1450 if(cmSystemTools::FileExists(listFile
.c_str()))
1455 else if(cmSystemTools::FileExists(arg
))
1458 std::string fullPath
= cmSystemTools::CollapseFullPath(arg
);
1459 std::string name
= cmSystemTools::GetFilenameName(fullPath
.c_str());
1460 name
= cmSystemTools::LowerCase(name
);
1461 if(name
== "cmakecache.txt")
1463 cachePath
= cmSystemTools::GetFilenamePath(fullPath
.c_str());
1465 else if(name
== "cmakelists.txt")
1467 listPath
= cmSystemTools::GetFilenamePath(fullPath
.c_str());
1471 // If there is a CMakeCache.txt file, use its settings.
1472 if(cachePath
.length() > 0)
1474 cmCacheManager
* cachem
= m_CMakeInstance
->GetCacheManager();
1475 cmCacheManager::CacheIterator it
= cachem
->NewIterator();
1476 if(cachem
->LoadCache(cachePath
.c_str()) && it
.Find("CMAKE_HOME_DIRECTORY"))
1478 std::string path
= ConvertToWindowsPath(cachePath
.c_str());
1479 m_WhereBuild
= path
.c_str();
1481 path
= ConvertToWindowsPath(it
.GetValue());
1482 m_WhereSource
= path
.c_str();
1484 m_GeneratorDialog
.m_GeneratorChoiceString
= _T("");
1489 // If there is a CMakeLists.txt file, use it as the source tree.
1490 if(listPath
.length() > 0)
1492 std::string path
= ConvertToWindowsPath(listPath
.c_str());
1493 m_WhereSource
= path
.c_str();
1497 // Source CMakeLists.txt file given. It was probably dropped
1498 // onto the window or executable. Default to an in-source
1500 m_WhereBuild
= path
.c_str();
1504 // Source directory given on command line. Use current working
1505 // directory as build tree.
1506 std::string cwd
= cmSystemTools::GetCurrentWorkingDirectory();
1507 path
= ConvertToWindowsPath(cwd
.c_str());
1508 m_WhereBuild
= path
.c_str();
1514 // The framework calls this member function when the user releases the
1515 // left mouse button over a window that has registered itself as the
1516 // recipient of dropped files.
1518 void CMakeSetupDialog::OnDropFiles(HDROP hDropInfo
)
1520 UINT nb_files
= DragQueryFile(hDropInfo
, 0xFFFFFFFF, NULL
, 0);
1523 UINT buffer_size
= DragQueryFile(hDropInfo
, 0, NULL
, 0);
1524 char *buffer
= new char [buffer_size
+ 1];
1525 DragQueryFile(hDropInfo
, 0, buffer
, buffer_size
+ 1);
1527 this->ChangeDirectoriesFromFile(buffer
);
1530 this->m_WhereSourceControl
.SetWindowText(this->m_WhereSource
);
1531 this->m_WhereBuildControl
.SetWindowText(this->m_WhereBuild
);
1533 this->UpdateData(FALSE
);
1535 this->OnChangeWhereSource();
1536 this->OnChangeWhereBuild();
1539 DragFinish(hDropInfo
);
1542 BOOL
CMakeSetupDialog::OnSetCursor(CWnd
* pWnd
, UINT nHitTest
, UINT message
)
1544 CDialog::OnSetCursor(pWnd
, nHitTest
, message
);
1545 if(m_Cursor
== LoadCursor(NULL
, IDC_WAIT
))
1547 ::SetCursor(m_Cursor
);