1 /********************************************************************
2 * Module: main.cpp. This is part of Visual-MinGW.
4 * Purpose: Main module.
8 * License: Visual-MinGW is a C/C++ Integrated Development Environment.
9 * Copyright (C) 2001 Manu.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
26 * (See license.htm for more details.)
29 * Manu B. 12/15/01 CFileList created.
31 ********************************************************************/
41 #define MSG_MODIFIED "Modified"
43 CCriticalSection CriticalSection
;
44 extern CMessageBox MsgBox
;
45 CFindReplaceDlg EditorDlg
;
46 void Main_CmdTest(HWND hwnd
);
49 char * g_env_path
= NULL
;
50 char * g_vm_path
= NULL
;
55 // File filters & flags.
56 DWORD singleFileOpen
= OFN_EXPLORER
| OFN_FILEMUSTEXIST
;
57 DWORD multipleFileOpen
= OFN_EXPLORER
| OFN_FILEMUSTEXIST
| OFN_ALLOWMULTISELECT
;
58 DWORD fileSave
= OFN_EXPLORER
| OFN_PATHMUSTEXIST
| OFN_HIDEREADONLY
|
61 char * defFilter
= "All Sources\0*.c;*.cpp;*.cxx;*.h;*.hpp;*.hxx;*.rc;*.mingw;*.prj\0"
62 "C Files\0*.c;*.cpp;*.cxx;*.rc\0"
63 "Headers\0*.h;*.hpp;*.hxx\0"
65 "All Files (*.*)\0*.*\0\0";
67 char * prjFilter
= "Project Files (*.prj)\0*.prj\0All Files (*.*)\0*.*\0\0";
68 char * prjDefExt
= "prj";
70 char * srcFilter
= "All Sources\0*.c;*.cpp;*.cxx;*.h;*.hpp;*.hxx;*.rc\0"
71 "C Files\0*.c;*.cpp;*.cxx;*.rc\0"
72 "Headers\0*.h;*.hpp;*.hxx\0"
73 "All Files (*.*)\0*.*\0\0";
74 char * srcDefExt
= "cpp";
77 CChooseFontDlg CChooseFont
;
78 void Main_CmdTest(HWND
){
79 winApp
.Process
.AddTask(
81 IN_PIPE
|| OUTERR_PIPE
,
84 /* CChooseFont.Create(&winApp);*/
89 /********************************************************************
92 * Purpose: A CFileDlgBase for Open/Save dlg boxes.
96 ********************************************************************/
100 CFileDlg::~CFileDlg(){
103 bool CFileDlg::Open(CWindow
* pWindow
, char * pszFileName
, DWORD nMaxFile
, int fileflag
){
108 SetData(prjFilter
, prjDefExt
, singleFileOpen
);
111 // Add multiple files to project.
114 SetTitle("Add files to project");
117 SetData(srcFilter
, srcDefExt
, multipleFileOpen
);
121 SetData(defFilter
, srcDefExt
, singleFileOpen
);
125 return OpenFileName(pWindow
, pszFileName
, nMaxFile
);
128 bool CFileDlg::Save(CWindow
* pWindow
, char * pszFileName
, DWORD nMaxFile
, int fileflag
){
133 SetData(defFilter
, srcDefExt
, fileSave
);
138 SetData(prjFilter
, prjDefExt
, fileSave
);
141 return SaveFileName(pWindow
, pszFileName
, nMaxFile
);
145 /********************************************************************
146 * Class: CPreferencesDlg.
152 ********************************************************************/
153 CPreferencesDlg::CPreferencesDlg(){
156 CPreferencesDlg::~CPreferencesDlg(){
159 int CPreferencesDlg::Create(void){
160 return CreateModal(&winApp
, IDD_PREFERENCES
, (LPARAM
) this);
163 LRESULT CALLBACK
CPreferencesDlg::CDlgProc(UINT Message
, WPARAM wParam
, LPARAM lParam
){
166 return OnInitDialog((HWND
) wParam
, lParam
);
169 OnNotify((int) wParam
, (LPNMHDR
) lParam
);
173 OnCommand(HIWORD(wParam
), LOWORD(wParam
), (HWND
) lParam
);
183 BOOL
CPreferencesDlg::OnInitDialog(HWND
, LPARAM
){
184 // Tab control handle and TCITEM.
185 _hWndTab
= ::GetDlgItem(_hWnd
, IDC_PREF_TABS
);
186 tcitem
.mask
= TCIF_TEXT
| TCIF_PARAM
;
189 HWND hwndChild
= EnvDlg
.Create(this, IDD_ENVIRON
, NULL
, (long) NULL
);
190 tcitem
.pszText
= "Environment";
191 tcitem
.lParam
= (long) &EnvDlg
;
192 ::SendMessage(_hWndTab
, TCM_INSERTITEM
, 0, (LPARAM
)&tcitem
);
193 SetChildPosition(hwndChild
);
195 /* tcitem.pszText = "General";
196 tcitem.lParam = (long) NULL;
197 ::SendMessage(_hWndTab, TCM_INSERTITEM, 1, (LPARAM)&tcitem);
199 tcitem.pszText = "Find in files";
200 tcitem.lParam = (long) NULL;
201 ::SendMessage(_hWndTab, TCM_INSERTITEM, 2, (LPARAM)&tcitem);*/
203 // Show the dialog and default pane.
210 BOOL
CPreferencesDlg::OnCommand(WORD
, WORD wID
, HWND
){
213 EnvDlg
.OnCommand(0, wID
, 0);
222 EnvDlg
.OnCommand(0, wID
, 0);
228 BOOL
CPreferencesDlg::EndDlg(int nResult
){
230 EnvDlg
.bIsVisible
= false;
232 BOOL result
= ::EndDialog(_hWnd
, nResult
);
240 /********************************************************************
247 ********************************************************************/
254 LRESULT CALLBACK
CEnvDlg::CDlgProc(UINT Message
, WPARAM wParam
, LPARAM lParam
){
257 return OnInitDialog((HWND
) wParam
, lParam
);
260 OnCommand(HIWORD(wParam
), LOWORD(wParam
), (HWND
) lParam
);
266 BOOL
CEnvDlg::OnInitDialog(HWND
, LPARAM
){
269 /* Get control handles */
270 hApply
= ::GetDlgItem(_pParent
->_hWnd
, IDAPPLY
);
271 hSetCcBin
= GetItem(IDC_SET_CCBIN
);
272 hCcBinDir
= GetItem(IDC_CCBIN
);
273 hBrowseCc
= GetItem(IDC_BROWSE_CC
);
274 hSetCmdBin
= GetItem(IDC_SET_CMDBIN
);
275 hCmdBinDir
= GetItem(IDC_CMDBIN
);
276 hBrowseCmd
= GetItem(IDC_BROWSE_CMD
);
277 hAutoexec
= GetItem(IDC_AUTOEXEC
);
278 hEnvView
= GetItem(IDC_ENV_VIEW
);
280 if (winApp
.bSetCcEnv
)
281 ::SendMessage(hSetCcBin
, BM_SETCHECK
, BST_CHECKED
, 0);
282 if (winApp
.bSetCmdEnv
)
283 ::SendMessage(hSetCmdBin
, BM_SETCHECK
, BST_CHECKED
, 0);
284 if (winApp
.bSetDefEnv
)
285 ::SendMessage(hAutoexec
, BM_SETCHECK
, BST_CHECKED
, 0);
287 SetItemText(hCcBinDir
, winApp
.szCcBinDir
);
288 SetItemText(hCmdBinDir
, winApp
.szCmdBinDir
);
290 /* hCcIncDir = GetItem(IDC_CC_INCDIR);
292 SetItemText(hCcIncDir, winApp.includeDir);*/
297 BOOL
CEnvDlg::OnCommand(WORD wNotifyCode
, WORD wID
, HWND
){
298 char directory
[MAX_PATH
];
302 if (winApp
.ShellDlg
.BrowseForFolder(&winApp
, directory
, "Browse",
303 BIF_RETURNONLYFSDIRS
)){
304 SetItemText(hCcBinDir
, directory
);
309 if (winApp
.ShellDlg
.BrowseForFolder(&winApp
, directory
, "Browse",
310 BIF_RETURNONLYFSDIRS
)){
311 SetItemText(hCmdBinDir
, directory
);
317 (BST_CHECKED
==::SendMessage(hSetCcBin
, BM_GETCHECK
, 0, 0));
319 (BST_CHECKED
==::SendMessage(hSetCmdBin
, BM_GETCHECK
, 0, 0));
321 (BST_CHECKED
==::SendMessage(hAutoexec
, BM_GETCHECK
, 0, 0));
323 GetItemText(hCcBinDir
, winApp
.szCcBinDir
, MAX_PATH
);
324 GetItemText(hCmdBinDir
, winApp
.szCmdBinDir
, MAX_PATH
);
325 // GetItemText(hCcIncDir, winApp.includeDir, MAX_PATH);
336 (BST_CHECKED
==::SendMessage(hSetCcBin
, BM_GETCHECK
, 0, 0));
338 (BST_CHECKED
==::SendMessage(hSetCmdBin
, BM_GETCHECK
, 0, 0));
340 (BST_CHECKED
==::SendMessage(hAutoexec
, BM_GETCHECK
, 0, 0));
342 GetItemText(hCcBinDir
, winApp
.szCcBinDir
, MAX_PATH
);
343 GetItemText(hCmdBinDir
, winApp
.szCmdBinDir
, MAX_PATH
);
347 ::EnableWindow(hApply
, false);
352 if (bIsVisible
&& !bModified
){
357 ::EnableWindow(hApply
, true);
366 void CEnvDlg::SetEnvText(void){
368 char * text
= (char *) malloc(strlen(g_vm_path
)+20); // 10 lines max.
370 char * parse
= g_vm_path
;
373 // Change ';' into CR/LF.
379 }else if (*parse
== '='){
391 SetItemText(hEnvView
, start
);
397 /********************************************************************
404 ********************************************************************/
405 CGrepDlg::CGrepDlg(){
410 CGrepDlg::~CGrepDlg(){
413 int CGrepDlg::Create(void){
414 return CreateModal(&winApp
, IDD_GREP
, (LPARAM
) this);
417 LRESULT CALLBACK
CGrepDlg::CDlgProc(UINT Message
, WPARAM wParam
, LPARAM lParam
){
420 return OnInitDialog((HWND
) wParam
, lParam
);
423 OnCommand(HIWORD(wParam
), LOWORD(wParam
), (HWND
) lParam
);
433 BOOL
CGrepDlg::OnInitDialog(HWND
, LPARAM
){
434 hFindWhat
= GetItem(IDC_FINDWHAT
);
435 hgDir
= GetItem(IDC_GFILTER
);
437 SetItemText(hFindWhat
, findWhat
);
438 SetItemText(hgDir
, gDir
);
439 // Show the dialog and default pane.
444 BOOL
CGrepDlg::OnCommand(WORD
, WORD wID
, HWND
){
447 GetItemText(hFindWhat
, findWhat
, sizeof(findWhat
));
448 GetItemText(hgDir
, gDir
, sizeof(gDir
));
449 FindInFiles(findWhat
, gDir
);
459 void CGrepDlg::FindInFiles(char * findWhat
, char * fileFilter
){
460 if (!findWhat
|| !fileFilter
|| winApp
.Process
.isRunning())
463 winApp
.Report
.Clear();
464 winApp
.Report
.Append("Grep search...", LVOUT_NORMAL
);
466 winApp
.Process
.AddTask("grep -G -n -H ", OUTERR_PIPE
, LVOUT_ERROR
);
467 winApp
.Process
.CmdCat(findWhat
);
468 winApp
.Process
.CmdCat(" ");
469 winApp
.Process
.CmdCat(fileFilter
);
471 winApp
.Process
.Run();
475 /********************************************************************
476 * Functions: WinMain procedure.
478 * Purpose: Runs the application.
482 ********************************************************************/
483 int WINAPI
WinMain (HINSTANCE hInstance
, HINSTANCE hPrevInstance
, LPSTR lpCmdLine
, int nCmdShow
){
484 return winApp
.Run(hInstance
, hPrevInstance
, lpCmdLine
, nCmdShow
);
488 /********************************************************************
491 * Purpose: Manages the all application.
495 ********************************************************************/
509 // Child windows dimensions.
523 bool CWinApp::CustomInit(void){
524 /* Get PATH environment variable */
525 char * env_path
= getenv("PATH");
527 g_env_path
= strdup(env_path
);
529 SetName("Visual MinGW", APP_VERSION
);
530 MsgBox
.SetCaption("Visual MinGW");
532 ReadIniFile("visual-mingw.ini");
534 hAccel
= LoadAccelerators(_hInst
, "ACCELS");
535 hmod
= LoadLibrary("SciLexer.DLL");
537 MsgBox
.DisplayFatal("Unable to load SciLexer.DLL");
543 bool CWinApp::Release(void){
552 bool CWinApp::ReadIniFile(char * fileName
){
553 ParseCmdLine(iniFileName
);
554 strcat(iniFileName
, fileName
);
556 if (!IniFile
.Load(iniFileName
)){
557 /* Create an empty file and fill it */
559 MsgBox
.DisplayWarning("Visual-MinGW first run !\n"
560 "Step 1: User interface initialization.\n"
561 "Please report bugs to Visual-MinGW home page.\n"
562 "See the Readme text for more information.");
563 FILE * file
= fopen(iniFileName
, "wb");
571 IniFile
.GetString(openFilesDir
, "FilesDirectory", "General" );
572 IniFile
.GetString(projectDir
, "ProjectDirectory" );
573 bSetDefEnv
= IniFile
.GetInt( "SetDefEnv" );
574 bSetCmdEnv
= IniFile
.GetInt( "SetBinDir" );
575 IniFile
.GetString(szCmdBinDir
, "BinDir" );
576 // [Compiler] section
577 IniFile
.GetString(includeDir
, "IncludeDir", "Compiler" );
578 bSetCcEnv
= IniFile
.GetInt( "SetBinDir" );
579 IniFile
.GetString(szCcBinDir
, "BinDir" );
585 void CWinApp::SaveIniFile(FILE * file
){
587 fprintf (file
, "\t; Generated automatically by Visual-MinGW.\n");
588 fprintf (file
, "\t ; http://visual-mingw.sourceforge.net/\n");
589 fprintf (file
, "[General]\nSignature = 40");
590 fprintf (file
, "\nFilesDirectory = %s", openFilesDir
);
591 fprintf (file
, "\nProjectDirectory = %s", projectDir
);
592 fprintf (file
, "\nTvWidth = %d", tvWidth
);
593 fprintf (file
, "\nLvHeight = %d", lvHeight
);
594 fprintf (file
, "\nSetDefEnv = %d", bSetDefEnv
);
595 fprintf (file
, "\nSetBinDir = %d", bSetCmdEnv
);
596 fprintf (file
, "\nBinDir = %s", szCmdBinDir
);
598 fprintf (file
, "\n\n[Compiler]\nIncludeDir = %s", includeDir
);
599 fprintf (file
, "\nSetBinDir = %d", bSetCcEnv
);
600 fprintf (file
, "\nBinDir = %s", szCcBinDir
);
603 bool CWinApp::WriteIniFile(void){
604 if (*iniFileName
== '\0')
606 FILE * file
= fopen(iniFileName
, "wb");
615 bool CWinApp::SetEnv(void){
616 // Free previous variable.
621 len
+= strlen(winApp
.szCcBinDir
);
623 len
+= strlen(winApp
.szCmdBinDir
);
624 if (bSetDefEnv
&& g_env_path
)
625 len
+= strlen(g_env_path
);
626 g_vm_path
= (char *) malloc(len
+8);
628 // Copy the environment variable.
629 strcpy(g_vm_path
, "PATH=");
630 if (bSetCcEnv
&& *winApp
.szCcBinDir
){
631 strcat(g_vm_path
, winApp
.szCcBinDir
);
632 strcat(g_vm_path
, ";");
634 if (bSetCmdEnv
&& *winApp
.szCmdBinDir
){
635 strcat(g_vm_path
, winApp
.szCmdBinDir
);
636 strcat(g_vm_path
, ";");
638 if (bSetDefEnv
&& g_env_path
)
639 strcat(g_vm_path
, g_env_path
);
641 len
= strlen(g_vm_path
) - 1;
642 if (g_vm_path
[len
] == ';')
643 g_vm_path
[len
] = '\0';
644 if (putenv(g_vm_path
) == -1){
653 /********************************************************************
654 * CWinApp: Create each application's window.
655 ********************************************************************/
656 bool CWinApp::CreateUI(void){
658 InitCommonControls();
662 wc
.hIcon
= LoadIcon(NULL
, IDI_APPLICATION
);
664 wc
.hbrBackground
= //NULL;
665 (HBRUSH
)(COLOR_INACTIVEBORDER
+ 1);
666 wc
.lpszMenuName
= MAKEINTRESOURCE(ID_MENU
);
667 wc
.hIconSm
= LoadIcon(NULL
, IDI_APPLICATION
);
669 if(!MainRegisterEx("main_class")) {
670 MsgBox
.DisplayFatal("Can't Register Main Window");
675 wc
.hbrBackground
= NULL
;
678 if(!ChildRegisterEx("child_class")) {
679 MsgBox
.DisplayFatal("Can't Register MDI Class");
683 // Use a CreateWindowEx like procedure.
684 HWND hwnd
= CreateEx(
685 this, // Owner class.
689 WS_OVERLAPPEDWINDOW
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
,
698 MsgBox
.DisplayFatal("Can't create Main window");
701 MsgBox
.SetParent(hwnd
);
704 ::ShowWindow(hwnd
, SW_SHOWMAXIMIZED
);
705 ::UpdateWindow(hwnd
);
712 void CWinApp::FirstRunTest(void){
713 MsgBox
.DisplayWarning("Visual-MinGW first run !\n"
714 "Step 2: You will now set your environment variables.\n"
715 "\"Use default environment variables\" should be checked.\n"
716 "Then Visual-MinGW will try to launch the compiler.");
717 PreferencesDlg
.Create();
718 MsgBox
.DisplayWarning("Visual-MinGW first run !\n"
719 "Step 3: Installation checking.\n"
720 "Try to launch rm and gcc.\n"
721 "See \"Main\" or \"Log\" report views for results.\n");
722 winApp
.Report
.Clear();
723 winApp
.Report
.Append("Testing for first run...", LVOUT_NORMAL
);
725 // Put the command line and the run flag in the command stack.
726 winApp
.Process
.AddTask("gcc -v", OUTERR_PIPE
, LVOUT_NORMAL
);
727 winApp
.Process
.AddTask("rm --version", OUTERR_PIPE
, LVOUT_NORMAL
);
728 winApp
.Process
.Run();
732 void CWinApp::CreateToolbar(void){
736 WS_VISIBLE
| WS_CHILD
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
737 |TBSTYLE_FLAT
| TBSTYLE_TOOLTIPS
740 Toolbar
.AddBitmap(IDB_TOOLBAR
, 15);
742 TBBUTTON tbButtons
[] =
743 { { 0, 0, TBSTATE_ENABLED
, TBSTYLE_SEP
, {0, 0}, 0, 0},
744 { 0, IDM_NEW
, TBSTATE_ENABLED
, TBSTYLE_BUTTON
, {0, 0}, 0, 0},
745 { 1, IDM_OPEN
, TBSTATE_ENABLED
, TBSTYLE_BUTTON
, {0, 0}, 0, 0},
746 { 2, IDM_SAVE
, TBSTATE_ENABLED
, TBSTYLE_BUTTON
, {0, 0}, 0, 0},
747 { 0, 0, TBSTATE_ENABLED
, TBSTYLE_SEP
, {0, 0}, 0, 0},
748 { 3, IDM_CUT
, TBSTATE_ENABLED
, TBSTYLE_BUTTON
, {0, 0}, 0, 0},
749 { 4, IDM_COPY
, TBSTATE_ENABLED
, TBSTYLE_BUTTON
, {0, 0}, 0, 0},
750 { 5, IDM_PASTE
, TBSTATE_ENABLED
, TBSTYLE_BUTTON
, {0, 0}, 0, 0},
751 { 0, 0, TBSTATE_ENABLED
, TBSTYLE_SEP
, {0, 0}, 0, 0},
752 { 6, IDM_UNDO
, TBSTATE_ENABLED
, TBSTYLE_BUTTON
, {0, 0}, 0, 0},
753 { 7, IDM_REDO
, TBSTATE_ENABLED
, TBSTYLE_BUTTON
, {0, 0}, 0, 0} };
755 int numbutton
= sizeof tbButtons
/sizeof tbButtons
[0];
757 Toolbar
.AddButtons(&tbButtons
[0], numbutton
);
760 void CWinApp::CreateSplitter(void){
761 MainSplitter
.Init(&ChildSplitter
, &Report
, SPLSTYLE_HORZ
, lvHeight
, SPLMODE_2
);
762 ChildSplitter
.Init(&Manager
, &MdiClient
, SPLSTYLE_VERT
, tvWidth
, SPLMODE_1
);
765 Manager
.Create(this);
772 void CWinApp::CreateMDI(void){
773 MdiClient
.Init(3, ID_FIRSTCHILD
);
777 WS_VISIBLE
| WS_CHILD
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
778 | WS_VSCROLL
| WS_HSCROLL
782 HWND
CWinApp::CreateChild(char * caption
, LPVOID lParam
){
784 CChildView
* mdiChild
= new CChildView
;
786 HWND hwnd
= mdiChild
->CreateEx(
787 &MdiClient
, // MUST be an MdiClient *.
789 MDIS_ALLCHILDSTYLES
| WS_CHILD
| WS_SYSMENU
| WS_CAPTION
790 | WS_THICKFRAME
| WS_MINIMIZEBOX
| WS_MAXIMIZEBOX
801 void CWinApp::CreateStatusBar(void){
805 WS_CHILD
| WS_VISIBLE
| WS_CLIPSIBLINGS
| SBARS_SIZEGRIP
);
807 int sbWidths
[] = {60, 120, -1};
809 int numparts
= sizeof sbWidths
/sizeof sbWidths
[0];
811 Sbar
.SetParts(numparts
, &sbWidths
[0]);
814 void CWinApp::SendCaretPos(int caretPos
) {
815 // To display the "Line : xxxx" message, we use our standard msgBuf[256].
816 sprintf(msgBuf
, "Line : %d", caretPos
);
817 Sbar
.SendMessage(SB_SETTEXT
, 0, (LPARAM
) msgBuf
);
822 /********************************************************************
823 * CWinApp: Message handling procedures.
824 ********************************************************************/
825 LRESULT CALLBACK
CWinApp::CMainWndProc(UINT Message
, WPARAM wParam
, LPARAM lParam
){
828 return OnCreate((LPCREATESTRUCT
) lParam
);
831 return OnPaint((HDC
) wParam
);
834 return OnSize(wParam
, LOWORD(lParam
), HIWORD(lParam
));
840 return OnCommand(wParam
, lParam
);
846 return OnNotify((int) wParam
, (LPNMHDR
) lParam
);
849 return OnLButtonDown((short) LOWORD(lParam
), (short) HIWORD(lParam
), wParam
);
852 return OnMouseMove((short) LOWORD(lParam
), (short) HIWORD(lParam
), wParam
);
855 return OnLButtonUp((short) LOWORD(lParam
), (short) HIWORD(lParam
), wParam
);
858 OnSetCursor((HWND
) wParam
, (UINT
) LOWORD(lParam
), (UINT
) HIWORD(lParam
));
859 return DefWindowProc(_hWnd
, Message
, wParam
, lParam
);
862 return DefFrameProc(_hWnd
, MdiClient
.GetId(), Message
, wParam
, lParam
);
867 BOOL
CWinApp::OnCreate(LPCREATESTRUCT
){
877 BOOL
CWinApp::OnPaint(HDC
){
879 BeginPaint(_hWnd
, &ps
);
880 EndPaint(_hWnd
, &ps
);
884 BOOL
CWinApp::OnSize(UINT
, int width
, int height
){
885 // TreeView and MDI Client delta-height.
886 deltaY
= height
-sbarHeight
-lvHeight
-vSplitter
-tbarHeight
;
889 Toolbar
.SetPosition(0,
894 MainSplitter
.SetPosition(0,
896 width
, height
-tbarHeight
-sbarHeight
,
900 0, height
-sbarHeight
,
904 InvalidateRect(_hWnd
, NULL
, false);
908 BOOL
CWinApp::OnDestroy(void){
913 BOOL
CWinApp::OnClose(void){
914 if (IDCANCEL
== Manager
.SaveAll(IDASK
)) // Ask to save.
915 return TRUE
; // Cancelled by user.
916 ::DestroyWindow(_hWnd
);
920 BOOL
CWinApp::OnNotify(int idCtrl
, LPNMHDR notify
){
921 Manager
.OnNotify(idCtrl
, notify
);
922 Report
.OnNotify(idCtrl
, notify
);
926 BOOL
CWinApp::OnLButtonDown(short xPos
, short yPos
, UINT
){
927 MainSplitter
.OnLButtonDown(_hWnd
, xPos
, yPos
);
928 ChildSplitter
.OnLButtonDown(_hWnd
, xPos
, yPos
);
932 BOOL
CWinApp::OnMouseMove(short xPos
, short yPos
, UINT
){
933 MainSplitter
.OnMouseMove(_hWnd
, xPos
, yPos
);
934 ChildSplitter
.OnMouseMove(_hWnd
, xPos
, yPos
);
938 BOOL
CWinApp::OnLButtonUp(short xPos
, short yPos
, UINT
){
939 MainSplitter
.OnLButtonUp(_hWnd
, xPos
, yPos
);
940 ChildSplitter
.OnLButtonUp(_hWnd
, xPos
, yPos
);
944 BOOL
CWinApp::OnSetCursor(HWND
, UINT nHittest
, UINT
){
945 if (nHittest
== HTCLIENT
) {
946 if (MainSplitter
.OnSetCursor(_hWnd
, 0)){
948 }else if (ChildSplitter
.OnSetCursor(_hWnd
, 0)){
951 ::SetCursor(::LoadCursor(NULL
, IDC_ARROW
));
958 /********************************************************************
959 * CWinApp: Dispatch command messages.
960 ********************************************************************/
961 BOOL
CWinApp::OnCommand(WPARAM wParam
, LPARAM lParam
){
962 int wID
= LOWORD(wParam
);
967 Manager
.FilesView
.New();
971 Manager
.OpenFileDialog();
974 case IDM_NEW_PROJECT
:
975 Manager
.NewProjectDialog();
978 case IDM_OPEN_PROJECT
:
979 Manager
.OpenProjectDialog();
982 case IDM_SAVE_PROJECT
:
983 Manager
.SaveProjectFiles(IDYES
);
986 case IDM_CLOSE_PROJECT
:
987 Manager
.CloseProject();
990 case IDM_PREFERENCES
:
991 PreferencesDlg
.Create();
995 PostMessage(_hWnd
, WM_CLOSE
, 0, 0);
1005 PostMessage(MdiClient
.GetId(), WM_MDICASCADE
, 0, 0);
1008 PostMessage(MdiClient
.GetId(), WM_MDITILE
, MDITILE_HORIZONTAL
, 0);
1011 PostMessage(MdiClient
.GetId(), WM_MDITILE
, MDITILE_VERTICAL
, 0);
1014 PostMessage(MdiClient
.GetId(), WM_MDIICONARRANGE
, 0, 0);
1018 case IDM_NEW_MODULE
:
1019 Project
.NewModuleDlg();
1026 case IDM_REMOVE_FILE
:
1027 Manager
.RemoveProjectFile();
1030 case IDM_REMOVE_MODULE
:
1031 Manager
.RemoveProjectModule();
1035 Project
.OptionsDlg();
1043 Project
.Explore(_hWnd
);
1051 case IDM_REBUILDALL
:
1052 Project
.RebuildAll();
1055 case IDM_RUN_TARGET
:
1056 Project
.RunTarget();
1060 Project
.MakeClean();
1064 Project
.BuildMakefile();
1068 winApp
.Process
.CommandDlg
.Create();
1072 Main_CmdTest(_hWnd
);
1076 if (wID
>= ID_FIRSTCHILD
){
1077 DefFrameProc(_hWnd
, MdiClient
.GetId(), WM_COMMAND
, wParam
, lParam
);
1079 HWND hChildWindow
= (HWND
) MdiClient
.SendMessage(WM_MDIGETACTIVE
);
1082 ::SendMessage(hChildWindow
, WM_COMMAND
, wParam
, lParam
);
1090 /********************************************************************
1091 * CWinApp: Handles child messages.
1092 ********************************************************************/
1093 LRESULT CALLBACK
CWinApp::CChildWndProc(CWindow
* pWnd
, UINT Message
, WPARAM wParam
, LPARAM lParam
){
1095 CChildView
* childView
= (CChildView
*) pWnd
;
1096 HWND hwndChild
= childView
->_hWnd
;
1100 childView
->OnCreate((LPCREATESTRUCT
) lParam
);
1104 childView
->OnSize(wParam
, LOWORD(lParam
), HIWORD(lParam
));
1108 childView
->OnCommand(wParam
, lParam
);
1112 childView
->OnDestroy();
1116 if (childView
->OnClose()){
1117 MdiClient
.SendMessage(WM_MDIDESTROY
,(WPARAM
) hwndChild
, 0);
1122 childView
->OnNotify((int) wParam
, (LPNMHDR
) lParam
);
1126 childView
->OnSetFocus((HWND
) wParam
);
1129 case WM_MDIACTIVATE
:
1130 childView
->OnActivate((HWND
) wParam
, (HWND
) lParam
);
1133 return DefMDIChildProc(hwndChild
, Message
, wParam
, lParam
);
1137 /********************************************************************
1138 * Class: CChildView.
1140 * Purpose: MDI child window class.
1144 ********************************************************************/
1145 CChildView::CChildView(){
1149 CChildView::~CChildView(){
1152 bool CChildView::OnCreate(LPCREATESTRUCT
){
1153 CFileItem
* file
= (CFileItem
*) GetLong(GWL_USERDATA
);
1155 // Create Scintilla Editor Control.
1156 HWND hwnd
= Editor
.CreateEx(
1159 WS_VISIBLE
| WS_CHILD
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
1160 | WS_VSCROLL
| WS_HSCROLL
);
1163 return false; // @@TODO need to manage creation failure.
1165 // Set window handles
1166 file
->pMdiChild
= this;
1168 // Load a file if there is one to load.
1169 Editor
.LoadFile(file
);
1173 bool CChildView::OnSize(UINT wParam
, int width
, int height
){
1174 if(wParam
!= SIZE_MINIMIZED
){
1175 Editor
.SetPosition(0,
1185 BOOL
CChildView::OnClose(void){
1187 int decision
= MsgBox
.AskToSave(true);
1200 BOOL
CChildView::OnDestroy(void){
1201 CFileItem
* file
= (CFileItem
*) GetLong(GWL_USERDATA
);
1204 if (!file
->isInProject
){
1206 winApp
.Manager
.FilesView
.CloseFile(file
);
1209 file
->pMdiChild
= NULL
;
1216 BOOL
CChildView::OnNotify(int, LPNMHDR notify
){
1217 SCNotification
* notification
= (SCNotification
*) notify
;
1219 // Notify Message from Current Editor Control.
1220 if (notify
->hwndFrom
== Editor
._hWnd
){
1221 switch (notify
->code
){
1223 Editor
.GetCurrentPos();
1224 winApp
.SendCaretPos(Editor
.caretPos
);
1227 case SCN_SAVEPOINTREACHED
:
1229 winApp
.Sbar
.WriteString("", 1);
1232 case SCN_SAVEPOINTLEFT
:
1234 winApp
.Sbar
.WriteString(MSG_MODIFIED
, 1);
1237 case SCN_MARGINCLICK
:
1238 if (notification
->margin
== 2)
1239 Editor
.MarginClick(notification
->position
, notification
->modifiers
);
1246 BOOL
CChildView::OnSetFocus(HWND
){
1247 CFileItem
* file
= (CFileItem
*) GetLong(GWL_USERDATA
);
1250 // Select corresponding TreeView item.
1251 CTreeView
* pTreeView
= file
->pTreeView
;
1256 pTreeView
->SendMessage(TVM_SELECTITEM
, (WPARAM
)TVGN_CARET
, (LPARAM
)file
->_hItem
);
1258 // Set Focus on Editor Control.
1261 // Display "Modified" message or nothing in the Status Bar.
1262 winApp
.SendCaretPos(Editor
.caretPos
);
1265 winApp
.Sbar
.SendMessage(SB_SETTEXT
, 1, (LPARAM
) MSG_MODIFIED
);
1267 winApp
.Sbar
.SendMessage(SB_SETTEXT
, 1, (LPARAM
) "");
1269 int selectedTab
= winApp
.Manager
.SendMessage(TCM_GETCURSEL
);
1271 if (file
->isInProject
== true && selectedTab
!= PROJECT_TAB
){
1272 winApp
.Manager
.SendMessage(TCM_SETCURFOCUS
, PROJECT_TAB
);
1273 }else if (file
->isInProject
== false && selectedTab
!= FILES_TAB
){
1274 winApp
.Manager
.SendMessage(TCM_SETCURFOCUS
, FILES_TAB
);
1279 BOOL
CChildView::OnActivate(HWND
, HWND hwndChildAct
){
1283 HWND hwndMain
= winApp
._hWnd
;
1285 hMenu
= GetMenu(hwndMain
);
1287 if(_hWnd
== hwndChildAct
){
1288 EnableFlag
= TRUE
; //being activated
1290 EnableFlag
= FALSE
; //being de-activated
1293 EnableMenuItem(hMenu
, 1, MF_BYPOSITION
| (EnableFlag
? MF_ENABLED
: MF_GRAYED
));
1294 EnableMenuItem(hMenu
, 3, MF_BYPOSITION
| (EnableFlag
? MF_ENABLED
: MF_GRAYED
));
1297 hFileMenu
= GetSubMenu(hMenu
, 0);
1298 EnableMenuItem(hFileMenu
, IDM_SAVE
, MF_BYCOMMAND
| (EnableFlag
? MF_ENABLED
: MF_GRAYED
));
1299 EnableMenuItem(hFileMenu
, IDM_SAVEAS
, MF_BYCOMMAND
| (EnableFlag
? MF_ENABLED
: MF_GRAYED
));
1300 hFileMenu
= GetSubMenu(hMenu
, 2);
1301 EnableMenuItem(hFileMenu
, IDM_FIND
, MF_BYCOMMAND
| (EnableFlag
? MF_ENABLED
: MF_GRAYED
));
1302 EnableMenuItem(hFileMenu
, IDM_REPLACE
, MF_BYCOMMAND
| (EnableFlag
? MF_ENABLED
: MF_GRAYED
));
1303 DrawMenuBar(hwndMain
);
1307 void CChildView::CmdSave(void){
1308 CFileItem
* file
= (CFileItem
*) GetLong(GWL_USERDATA
);
1312 /* Untitled file ? */
1313 if (file
->nFileOffset
== 0){
1318 if (!file
->isInProject
){
1320 Editor
.SaveFile(file
->szFileName
);
1323 Project
.szDirBuffer
[Project
.nFileOffset
- 1] = '\\';
1324 strcpy(&Project
.szDirBuffer
[Project
.nFileOffset
], file
->szFileName
);
1325 Editor
.SaveFile(Project
.szDirBuffer
);
1326 Project
.szDirBuffer
[Project
.nFileOffset
- 1] = '\0';
1330 void CChildView::CmdSaveAs(void){
1331 CFileItem
* file
= (CFileItem
*) GetLong(GWL_USERDATA
);
1335 char fileName
[MAX_PATH
];
1336 if (!winApp
.FileDlg
.Save(&winApp
, fileName
, MAX_PATH
, SRC_FILE
)) //@@
1337 return; // canceled by user
1339 ::SetWindowText(_hWnd
, fileName
);
1340 strcpy(file
->szFileName
, fileName
);
1342 Editor
.SaveFile(file
->szFileName
);
1343 //@@ TODO we need to check for errors
1346 BOOL
CChildView::OnCommand(WPARAM wParam
, LPARAM
){
1347 CFileItem
* file
= (CFileItem
*) GetLong(GWL_USERDATA
);
1352 switch (LOWORD(wParam
)){
1362 winApp
.Manager
.SaveAll(IDYES
); // Silent.
1366 PostMessage(pWnd, WM_CLOSE, 0, 0);
1369 // To Scintilla control.
1371 EditorDlg
.Find(&Editor
);
1375 EditorDlg
.Replace(&Editor
);
1379 Editor
.SendMessage(SCI_CUT
);
1382 Editor
.SendMessage(SCI_COPY
);
1385 Editor
.SendMessage(SCI_PASTE
);
1388 Editor
.SendMessage(SCI_UNDO
);
1391 Editor
.SendMessage(SCI_REDO
);
1394 Editor
.SendMessage(SCI_SELECTALL
);
1401 /********************************************************************
1408 ********************************************************************/
1409 CManager::CManager(){
1412 CManager::~CManager(){
1415 void CManager::OpenFileDialog(void){
1416 CFileItem
* file
= new CFileItem
;
1418 /* Show the "Open file" dialog */
1419 winApp
.FileDlg
.Reset();
1420 winApp
.FileDlg
.SetInitialDir(winApp
.openFilesDir
);
1422 if(!winApp
.FileDlg
.Open(&winApp
, file
->szFileName
, MAX_PATH
, SRC_FILE
)){
1424 return; // canceled by user
1427 /* Get file information */
1428 file
->nFileExtension
= winApp
.FileDlg
.GetFileExtension();
1429 file
->nFileOffset
= winApp
.FileDlg
.GetFileOffset();
1431 // Copy file directory.
1432 strncpy(winApp
.openFilesDir
, file
->szFileName
, (file
->nFileOffset
- 1));
1433 winApp
.openFilesDir
[file
->nFileOffset
-1] = '\0';
1436 if(!OpenFile(file
)){
1438 MsgBox
.DisplayString("This file is already opened.");
1442 bool CManager::OpenFile(CFileItem
* file
){
1446 if (!file
->isInProject
){
1447 if (!FilesView
.OpenFile(file
))
1450 if (!ProjectView
.OpenFile(file
))
1456 bool CManager::NewProjectDialog(void){
1457 if(IDYES
== Project
.CloseDecision())
1460 char fileName
[MAX_PATH
];
1465 if (!winApp
.FileDlg
.Save(&winApp
, fileName
, MAX_PATH
, PRJ_FILE
)){
1466 return false; // canceled by user
1468 // Copy prj file's directory.
1469 fileOffset
= winApp
.FileDlg
.GetFileOffset();
1471 ProjectView
.CreateRoot("Project");
1472 if (!Project
.New(fileName
, fileOffset
)){
1473 ProjectView
.DestroyRoot();
1474 ProjectView
.DestroyList();
1480 bool CManager::OpenProjectDialog(void){
1481 if(IDYES
== Project
.CloseDecision())
1484 char fileName
[MAX_PATH
];
1488 // Load default values.
1489 winApp
.FileDlg
.Reset();
1490 winApp
.FileDlg
.SetInitialDir(winApp
.projectDir
);
1492 if (!winApp
.FileDlg
.Open(&winApp
, fileName
, MAX_PATH
, PRJ_FILE
)){
1493 return false; // canceled by user
1495 // Copy project file's directory.
1496 offset
= winApp
.FileDlg
.GetFileOffset();
1498 // Initialize project tree view.
1499 ProjectView
.CreateRoot(fileName
+offset
);
1501 if (!Project
.Open(fileName
, offset
)){
1502 ProjectView
.DestroyRoot();
1503 ProjectView
.DestroyList();
1509 bool CManager::CloseProject(void){
1510 return ProjectView
.Close();
1513 void CManager::RemoveProjectFile(void){
1514 ProjectView
.RemoveFile();
1517 void CManager::RemoveProjectModule(void){
1518 ProjectView
.RemoveModule();
1521 int CManager::SaveProjectFiles(int decision
){
1522 return ProjectView
.SaveAll(decision
);
1525 int CManager::SaveAll(int decision
){
1526 /* Save open files ? */
1527 decision
= FilesView
.SaveAll(decision
);
1528 /* Save project files ? */
1529 decision
= ProjectView
.SaveAll(decision
);
1533 void CManager::CreateImageList(void){
1534 // Create an empty image list.
1535 ImgList
.Create(16, 16, ILC_COLORDDB
|ILC_MASK
, 8, 1);
1537 // Load treeview bmp and add it to the image list.
1539 tvBitmap
.Load(this, IDB_TREEVIEW
);
1540 ImgList
.AddMasked(&tvBitmap
, RGB(255,0,255));
1542 // We no longer need treeview bmp.
1546 void CManager::Create(CWindow
* pParent
){
1547 // Create the Tab Control.
1551 WS_CHILD
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
1552 | TCS_BOTTOM
| TCS_FOCUSNEVER
);
1554 // Give it the default font, create tabs, select first one and show the control.
1555 SendMessage(WM_SETFONT
, (long) GetStockObject(DEFAULT_GUI_FONT
), 0);
1557 InsertItem(FILES_TAB
, TCIF_TEXT
, 0, 0, "Files", 16, 0, 0);
1558 InsertItem(PROJECT_TAB
, TCIF_TEXT
, 0, 0, "Project", 16, 0, 0);
1561 // Create an Image list and then the Project TreeView.
1563 ProjectView
.Create(this, &ImgList
);
1564 SetItem_Param(PROJECT_TAB
, (long) &ProjectView
);
1565 FilesView
.Create(this, &ImgList
);
1566 SetItem_Param(FILES_TAB
, (long) &FilesView
);
1569 bool CManager::SetPosition(HWND
, int x
, int y
, int width
, int height
, UINT
){
1570 /* Overwrites CTabCtrl::SetPosition() so that all child windows are also resized */
1573 ::SetWindowPos(_hWnd
, 0,
1581 ::GetClientRect(_hWnd
, &Rect
);
1582 ProjectView
.SetPosition(0, Rect
.top
+5, Rect
.left
+5,
1583 Rect
.right
-10, Rect
.bottom
-30, 0);
1585 FilesView
.SetPosition(0, Rect
.top
+5, Rect
.left
+5,
1586 Rect
.right
-10, Rect
.bottom
-30, 0);
1590 BOOL
CManager::OnNotify(int, LPNMHDR notify
){
1591 // Dispatch messages.
1592 switch (notify
->code
){
1594 case TCN_SELCHANGING
:
1595 OnSelChanging(notify
);
1599 OnSelChange(notify
);
1603 case TVN_SELCHANGED
:
1604 Tv_OnSelchanged((LPNMTREEVIEW
) notify
);
1610 void CManager::OnSelChanging(LPNMHDR notify
){
1611 if (_hWnd
== notify
->hwndFrom
){
1612 CTreeView
* pTreeView
= (CTreeView
*) GetItem_Param(GetCurSel());
1619 void CManager::OnSelChange(LPNMHDR notify
){
1620 if (_hWnd
== notify
->hwndFrom
){
1621 CTreeView
* pTreeView
= (CTreeView
*) GetItem_Param(GetCurSel());
1628 void CManager::Tv_OnSelchanged(LPNMTREEVIEW notify
){
1629 // Get lParam of current tree item.
1630 CFileItem
* file
= (CFileItem
*) notify
->itemNew
.lParam
;
1633 CChildView
* pMdiChild
= (CChildView
*) file
->pMdiChild
;
1636 // An editor, focus it.
1637 ::SetFocus((HWND
) pMdiChild
->_hWnd
);
1639 // No editor, the item is part of a project.
1640 Project
.SwitchCurrentDir();
1641 winApp
.CreateChild(file
->szFileName
, file
);
1647 /********************************************************************
1648 * Class: CFilesView.
1650 * Purpose: Open files TreeView.
1654 ********************************************************************/
1655 CFilesView::CFilesView(){
1659 CFilesView::~CFilesView(){
1662 void CFilesView::New(void){
1663 CFileItem
* file
= new CFileItem
;
1664 if(!winApp
.Manager
.OpenFile(file
)){
1666 MsgBox
.DisplayString("Untitled file already exist.");
1670 bool CFilesView::OpenFile(CFileItem
* file
){
1675 char * fileName
= file
->szFileName
+ file
->nFileOffset
;
1677 /* Untitled file ? */
1678 if (file
->nFileOffset
== 0){
1679 //@@TODO add a counter to get Untitled01, 02, etc...
1680 strcpy(file
->szFileName
, "Untitled");
1683 /* Check if this file is already opened */
1684 listAction
= InsertSorted_New(file
);
1686 if (listAction
== FILE_FOUND
){
1687 /* Focus the editor window */
1688 CFileItem
* currentFile
= (CFileItem
*) GetCurrent();
1690 CMDIChild
* pMdiChild
= currentFile
->pMdiChild
;
1692 pMdiChild
->SetFocus();
1697 /* Create the editor window */
1698 if (!winApp
.CreateChild(file
->szFileName
, file
)){
1699 MsgBox
.DisplayFatal("Can't create child window");
1702 // Note: A WM_SETFOCUS message will be send to the child window.
1704 /* Append the file to the list */
1707 /* Create a Tree View item */
1708 file
->_hItem
= CreateItem(
1709 hRoot
, //@@ use a GetRootItem() ?
1715 file
->pTreeView
= this;
1719 void CFilesView::CloseFile(CFileItem
* file
){
1720 SendMessage(TVM_DELETEITEM
, 0, (LPARAM
) file
->_hItem
);
1724 int CFilesView::SaveAll(int decision
){
1725 if (decision
== IDNO
|| decision
== IDCANCEL
)
1727 CFileItem
* file
= (CFileItem
*) First();
1729 if (file
->pMdiChild
){
1730 CChildView
* childView
= (CChildView
*) file
->pMdiChild
;
1732 if (childView
->modified
){
1734 if (decision
== IDASK
){
1735 decision
= MsgBox
.AskToSave(true); // Cancel button.
1736 if (decision
!= IDYES
)
1737 return decision
; // IDNO or IDCANCEL.
1739 childView
->CmdSave();
1742 file
= (CFileItem
*) Next();
1747 HWND
CFilesView::Create(CWindow
* pParent
, CImageList
* imgList
){
1752 WS_VISIBLE
| WS_CHILD
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
1753 | TVS_EDITLABELS
| TVS_HASLINES
| TVS_HASBUTTONS
,
1757 // Assign the image list to the treeview control.
1758 SendMessage(TVM_SETIMAGELIST
, (long)TVSIL_NORMAL
, (long) imgList
->GetId());
1759 hRoot
= CreateItem(TVI_ROOT
, TVI_LAST
, WORKSPACE
, "Workspace", 0);
1764 /********************************************************************
1765 * Class: CProjectView.
1767 * Purpose: Project TreeView.
1771 ********************************************************************/
1772 CProjectView::CProjectView(){
1776 CProjectView::~CProjectView(){
1779 CFileItem
* CProjectView::NewFile(char * name
){
1780 CFileItem
* current
= (CFileItem
*) GetCurrent();
1781 CFileItem
* srcFile
= new CFileItem
;
1783 // Copy directory name.
1785 strncpy(srcFile
->szFileName
, current
->szFileName
, current
->nFileOffset
);
1786 srcFile
->nFileOffset
= current
->nFileOffset
;
1788 // No files in the project yet, use makefile directory.
1789 strcpy(srcFile
->szFileName
, Project
.Makefile
.mkfDir
);
1790 srcFile
->nFileOffset
= strlen(srcFile
->szFileName
)+1;
1793 srcFile
->szFileName
[srcFile
->nFileOffset
- 1] = '\\';
1795 // Append file name.
1796 strcpy(&srcFile
->szFileName
[srcFile
->nFileOffset
], name
);
1797 //MsgBox.DisplayString(srcFile->szFileName);
1799 if (::CheckFile(srcFile
)){
1800 ::GetFileType(srcFile
);
1801 srcFile
->isInProject
= true;
1803 hFile
= ::CreateFile(srcFile
->szFileName
,
1808 FILE_ATTRIBUTE_ARCHIVE
,
1811 if (hFile
!= INVALID_HANDLE_VALUE
){
1813 // Try to add new file to the project.
1814 if(OpenFile(srcFile
)){
1815 Project
.modified
= true;
1824 bool CProjectView::OpenFile(CFileItem
* file
){
1829 char * fileName
= file
->szFileName
+ file
->nFileOffset
;
1831 /* Check if this file is already opened */
1832 listAction
= InsertSorted_New(file
);
1834 if (listAction
== FILE_FOUND
){
1835 /* Focus the editor window */
1836 CFileItem
* currentFile
= (CFileItem
*) GetCurrent();
1838 CMDIChild
* pMdiChild
= currentFile
->pMdiChild
;
1840 /* Create a child window */
1841 Project
.SwitchCurrentDir();
1842 winApp
.CreateChild(file
->szFileName
, file
);
1844 pMdiChild
->SetFocus();
1850 file
->_hDirItem
= hRoot
;
1851 CreateSubDirItem(file
);
1853 if (listAction
== EMPTY_LIST
){
1855 }else if (listAction
== INSERT_FIRST
){
1857 }else if (listAction
== INSERT_LAST
){
1859 }else if (listAction
== INSERT_BEFORE
){
1861 }else if (listAction
== INSERT_AFTER
){
1865 /* Create the file icon */
1866 file
->_hItem
= CreateItem(
1873 file
->pTreeView
= this;
1875 /* Create an editor view */
1877 winApp
.CreateChild(file
->szFileName
, file
);
1882 bool CProjectView::Close(){
1883 if (Project
.NoProject())
1886 int decision
= IDASK
;
1887 decision
= SaveAll(decision
);
1888 if (decision
== IDCANCEL
)
1891 // Parse the list while there's a next node.
1892 CFileItem
* srcFile
= (CFileItem
*) First();
1894 DestroyFile(srcFile
, decision
);
1895 srcFile
= (CFileItem
*) Next();
1897 Project
.loaded
= false;
1901 winApp
.Report
.Clear();
1905 void CProjectView::RemoveFile(void){
1906 if (Project
.NoProject())
1909 CFileItem
* srcFile
= (CFileItem
*) GetSelectedItemParam();
1912 if (srcFile
->pMdiChild
)
1913 DestroyFile(srcFile
);
1914 TreeView_DeleteItem(_hWnd
, srcFile
->_hItem
);
1915 if (!TreeView_GetChild(_hWnd
, srcFile
->_hDirItem
))
1916 TreeView_DeleteItem(_hWnd
, srcFile
->_hDirItem
);
1918 TreeView_SelectItem(_hWnd, srcFile->_hDirItem);*/
1921 // we need to save prj file before exit.
1922 //@@ Project.CloseFile, modified & buildMakefile should be private.
1923 Project
.modified
= true;
1924 Project
.buildMakefile
= true;
1926 MsgBox
.DisplayWarning("No project file selected");
1930 void CProjectView::RemoveModule(void){
1931 if (Project
.NoProject())
1934 CFileItem
* srcFile
= (CFileItem
*) GetSelectedItemParam();
1935 CFileItem
* otherFile
;
1939 otherFile
= (CFileItem
*) srcFile
->prev
;
1940 if (otherFile
->nFileExtension
!= 0){
1941 if (0 == strnicmp(srcFile
->szFileName
, otherFile
->szFileName
, otherFile
->nFileExtension
)){
1942 if (otherFile
->pMdiChild
)
1943 DestroyFile(otherFile
);
1944 TreeView_DeleteItem(_hWnd
, otherFile
->_hItem
);
1950 otherFile
= (CFileItem
*) srcFile
->next
;
1951 if (otherFile
->nFileExtension
!= 0){
1952 if (0 == strnicmp(srcFile
->szFileName
, otherFile
->szFileName
, otherFile
->nFileExtension
)){
1953 if (otherFile
->pMdiChild
)
1954 DestroyFile(otherFile
);
1955 TreeView_DeleteItem(_hWnd
, otherFile
->_hItem
);
1960 if (srcFile
->pMdiChild
)
1961 DestroyFile(srcFile
);
1962 TreeView_DeleteItem(_hWnd
, srcFile
->_hItem
);
1965 // we need to save prj file before exit.
1966 //@@ Project.CloseFile, modified & buildMakefile should be private.
1967 Project
.modified
= true;
1968 Project
.buildMakefile
= true;
1970 MsgBox
.DisplayWarning("No project file selected");
1974 int CProjectView::DestroyFile(CFileItem
* file
, int decision
){
1975 if (file
&& file
->pMdiChild
){
1976 CChildView
* pMdiChild
= (CChildView
*) file
->pMdiChild
;
1978 if (pMdiChild
->modified
&& decision
!= IDNO
){
1980 if (decision
== IDASK
){
1981 decision
= MsgBox
.AskToSave(true); // (Cancel button)
1982 if (decision
== IDCANCEL
)
1985 pMdiChild
->CmdSave();
1988 if (pMdiChild
->_hWnd
) // have an editor window, so destroy it.
1989 winApp
.MdiClient
.SendMessage(WM_MDIDESTROY
, (WPARAM
)pMdiChild
->_hWnd
, 0);
1994 int CProjectView::SaveAll(int decision
){
1995 if (!Project
.loaded
)
1998 if (decision
== IDNO
|| decision
== IDCANCEL
)
2001 CFileItem
* file
= (CFileItem
*) First();
2003 if (file
->pMdiChild
){
2004 CChildView
* childView
= (CChildView
*) file
->pMdiChild
;
2006 if (childView
->modified
){
2008 if (decision
== IDASK
){
2009 decision
= MsgBox
.AskToSave(true); // Cancel button.
2010 if (decision
!= IDYES
)
2011 return decision
; // IDNO or IDCANCEL.
2013 childView
->CmdSave();
2016 file
= (CFileItem
*) Next();
2019 if (Project
.modified
)
2020 return Project
.SavePrjFile(decision
);
2024 bool CProjectView::CreateSubDirItem(CFileItem
* file
){
2025 /* Initialize _hDirItem and get a pointer to current file */
2026 file
->_hDirItem
= hRoot
;
2027 CFileItem
* currentFile
= (CFileItem
*) GetCurrent();
2029 /* See if our new file is in the same directory than current file */
2031 // There's some files in the list.
2032 if (file
->nFileOffset
== currentFile
->nFileOffset
){
2033 // Same directory length, we may have found the directory.
2034 if (0 == strnicmp(file
->szFileName
, currentFile
->szFileName
, currentFile
->nFileOffset
)){
2035 /* We have found the directory, then copy _hDirItem */
2036 file
->_hDirItem
= currentFile
->_hDirItem
;
2042 /* We need to parse the tree view and create directory icons */
2043 char * parse
= file
->szFileName
;
2044 if (*parse
== '.' && *(parse
+1) == '\\'){
2045 /* This is a valid relative path */
2047 strcpy(dir
, file
->szFileName
);
2050 HTREEITEM hParent
= hRoot
;
2054 /* Found each backslash */
2056 parse
= strchr(parse
, '\\');
2058 break; // No more backslash.
2059 else if (parse
== dirStart
)
2060 return false; // Avoids an endless loop.
2063 /* Find the directory */
2064 hFound
= FindDirItem(hParent
, dirStart
);
2066 /* Append a new directory icon */
2067 hParent
= CreateDirItem(hParent
, dirStart
);
2072 file
->_hDirItem
= hParent
;
2077 HTREEITEM
CProjectView::FindDirItem(HTREEITEM hItem
, char * dir
){
2078 char buffer
[_MAX_DIR
];
2079 HTREEITEM hNext
= TreeView_GetChild(_hWnd
, hItem
);
2081 _TvItem
.hItem
= hNext
;
2082 _TvItem
.mask
= TVIF_HANDLE
| TVIF_TEXT
;
2083 _TvItem
.pszText
= buffer
;
2084 _TvItem
.cchTextMax
= _MAX_DIR
;
2085 if (TreeView_GetItem(_hWnd
, &_TvItem
)){
2086 if (!stricmp(dir
, buffer
))
2089 hNext
= TreeView_GetNextSibling(_hWnd
, hNext
);
2094 HWND
CProjectView::Create(CWindow
* pParent
, CImageList
* imgList
){
2099 WS_CHILD
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
2100 | TVS_EDITLABELS
| TVS_HASLINES
| TVS_HASBUTTONS
);
2102 // Assign the image list to the treeview control.
2103 SendMessage(TVM_SETIMAGELIST
, (long)TVSIL_NORMAL
, (long) imgList
->GetId());
2107 void CProjectView::CreateRoot(char * projectName
){
2109 _pParent
->SendMessage(TCM_SETCURFOCUS
, 1, 0);
2111 // Create Root Item.
2112 hRoot
= CreateItem(TVI_ROOT
, TVI_LAST
, PROJECT
, projectName
, 0);
2113 SendMessage(TVM_EXPAND
, (long) TVE_EXPAND
, (long) hRoot
);
2116 void CProjectView::DestroyRoot(void){
2117 TreeView_DeleteItem(_hWnd
, hRoot
);
2120 _pParent
->SendMessage(TCM_SETCURFOCUS
, 0, 0);
2123 HTREEITEM
CProjectView::CreateDirItem(HTREEITEM hParent
, char * dir
){
2124 return CreateItem(hParent
, TVI_SORT
, DIR, dir
, 0);
2127 CFileItem
* CProjectView::FindFile(char * szFileName
){
2128 if (!szFileName
|| !*szFileName
)
2132 bool stripDir
= true;
2133 if (*szFileName
== '.')
2135 // Get the current node.
2136 CFileItem
* currentNode
= (CFileItem
*) GetCurrent();
2139 return NULL
; // The list is empty.
2141 currentFile
= GetFileName(currentNode
, stripDir
);
2142 int cmpResult
= stricmp(szFileName
, currentFile
);
2143 // Compare names to know if we must parse Up
2144 // or Down from current node.
2145 if (cmpResult
== 0){
2146 return currentNode
; // Found !
2148 // Search Up -----------------------------------------------------------------
2149 else if (cmpResult
== -1){
2150 // Parse the list while there's a previous node.
2152 currentNode
= (CFileItem
*) GetCurrent();
2153 currentFile
= GetFileName(currentNode
, stripDir
);
2154 if(!stricmp(szFileName
, currentFile
))
2155 return currentNode
; // Found !
2158 // Search Down --------------------------------------------------------------
2159 else if (cmpResult
== 1){
2160 // Parse the list while there's a next node.
2162 currentNode
= (CFileItem
*) GetCurrent();
2163 currentFile
= GetFileName(currentNode
, stripDir
);
2164 if(!stricmp(szFileName
, currentFile
))
2165 return currentNode
; // Found !
2171 char * CProjectView::GetFileName(CFileItem
* currentNode
, bool flag
){
2172 char * fileName
= currentNode
->szFileName
;
2174 fileName
+= currentNode
->nFileOffset
;
2180 /********************************************************************
2187 ********************************************************************/
2191 CReport::~CReport(){
2194 void CReport::Create(CWindow
* pParent
){
2195 // Create the Tab Control.
2199 WS_CHILD
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
2200 /*| TCS_BOTTOM*/ | TCS_MULTILINE
| TCS_VERTICAL
2203 // Give it a smart font, create tabs, select first one and show the control.
2204 SendMessage(WM_SETFONT
, (long) GetStockObject(DEFAULT_GUI_FONT
), 0);
2206 InsertItem(REPORT_MAIN_TAB
, TCIF_TEXT
, 0, 0, "Main", 16, 0, 0);
2207 InsertItem(REPORT_LOG_TAB
, TCIF_TEXT
, 0, 0, "Log", 16, 0, 0);
2210 // Create an Image list and then the Project TreeView.
2211 MainList
.Create(this);
2212 SetItem_Param(REPORT_MAIN_TAB
, (long) &MainList
);
2213 LogList
.Create(this);
2214 SetItem_Param(REPORT_LOG_TAB
, (long) &LogList
);
2217 bool CReport::SetPosition(HWND
, int x
, int y
, int width
, int height
, UINT
){
2218 /* Overwrites CTabCtrl::SetPosition() so that all child windows are also resized */
2221 ::SetWindowPos(_hWnd
, 0,
2228 // Get tab's display area.
2233 area
.bottom
= height
;
2234 ::SendMessage(_hWnd
, TCM_ADJUSTRECT
, FALSE
, (LPARAM
) &area
);
2235 area
.right
-= area
.left
;
2236 area
.bottom
-= area
.top
;
2237 /* WS_EX_CLIENTEDGE correction */
2247 MainList
.SetPosition(0, area
.left
, area
.top
,
2248 area
.right
, area
.bottom
, 0);
2249 LogList
.SetPosition(0, area
.left
, area
.top
,
2250 area
.right
, area
.bottom
, 0);
2254 BOOL
CReport::OnNotify(int, LPNMHDR notify
){
2255 // Dispatch messages.
2256 switch (notify
->code
){
2258 case TCN_SELCHANGING
:
2259 OnSelChanging(notify
);
2263 OnSelChange(notify
);
2268 MainList
.Lv_OnDbClick((LPNMLISTVIEW
) notify
);
2274 void CReport::OnSelChanging(LPNMHDR notify
){
2275 if (_hWnd
== notify
->hwndFrom
){
2276 CWindow
* pWindow
= (CWindow
*) GetItem_Param(GetCurSel());
2283 void CReport::OnSelChange(LPNMHDR notify
){
2284 if (_hWnd
== notify
->hwndFrom
){
2285 CWindow
* pWindow
= (CWindow
*) GetItem_Param(GetCurSel());
2292 void CReport::Clear(void){
2297 bool CReport::Append(char * line
, WORD outputFlag
){
2298 LogList
.Append(line
, outputFlag
);
2299 MainList
.Append(line
, outputFlag
);
2304 /********************************************************************
2311 ********************************************************************/
2312 CMainList::CMainList(){
2315 CMainList::~CMainList(){
2318 void CMainList::Create(CWindow
* pParent
){
2322 WS_VISIBLE
| WS_CHILD
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
2325 SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE
,
2326 LVS_EX_GRIDLINES
, LVS_EX_GRIDLINES
);
2327 SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE
,
2328 LVS_EX_FULLROWSELECT
, LVS_EX_FULLROWSELECT
);
2332 lvc
.mask
= LVCF_FMT
| LVCF_WIDTH
| LVCF_TEXT
| LVCF_SUBITEM
;
2333 lvc
.fmt
= LVCFMT_LEFT
;
2337 lvc
.pszText
= "Line";
2338 SendMessage(LVM_INSERTCOLUMN
, 0, (LPARAM
) &lvc
);
2342 lvc
.pszText
= "Unit";
2343 SendMessage(LVM_INSERTCOLUMN
, 1, (LPARAM
) &lvc
);
2347 lvc
.pszText
= "Message";
2348 SendMessage(LVM_INSERTCOLUMN
, 2, (LPARAM
) &lvc
);
2351 void CMainList::Lv_OnDbClick(LPNMLISTVIEW lpnmlv
){
2352 if (_hWnd
== lpnmlv
->hdr
.hwndFrom
){
2355 char * c
= lineBuff
;
2357 lvi
.mask
= LVIF_TEXT
;
2358 lvi
.iItem
= lpnmlv
->iItem
;
2360 lvi
.pszText
= lineBuff
;
2361 lvi
.cchTextMax
= 256;
2363 if (!SendMessage(LVM_GETITEMTEXT
, lpnmlv
->iItem
, (long) &lvi
))
2370 int line
= atoi(lineBuff
);
2372 //MsgBox.DisplayLong((long) line);
2375 if (!SendMessage(LVM_GETITEMTEXT
, lpnmlv
->iItem
, (long) &lvi
))
2377 CFileItem
* item
= winApp
.Manager
.ProjectView
.FindFile(lineBuff
);
2378 if (item
&& item
->isInProject
){
2379 CChildView
* pMdiChild
= (CChildView
*) item
->pMdiChild
;
2382 // An editor, focus it.
2383 ::SetFocus((HWND
) pMdiChild
->_hWnd
);
2385 // No editor, the item is part of a project.
2386 Project
.SwitchCurrentDir();
2387 winApp
.CreateChild(item
->szFileName
, item
);
2389 pMdiChild
= (CChildView
*) item
->pMdiChild
;
2391 pMdiChild
->Editor
.GotoLine(line
-1);
2396 bool CMainList::Append(char * line
, WORD outputFlag
){
2403 if (outputFlag
== LVOUT_ERROR
){
2404 if (!SplitErrorLine(line
))
2406 }else if (outputFlag
== LVOUT_NORMAL
){
2407 strcpy (szMsg
, line
);
2409 strcpy (szMsg
, "Unrecognized outputFlag");
2412 // Fill in List View columns, first is column 0.
2414 lvi
.mask
= LVIF_TEXT
; // | LVIF_PARAM;
2417 lvi
.pszText
= szLine
;
2418 lvi
.cchTextMax
= strlen(lvi
.pszText
)+1;
2421 row
= SendMessage(LVM_INSERTITEM
, 0, (LPARAM
) &lvi
);
2423 // Continue with column 1.
2425 lvi
.pszText
= szUnit
;
2426 lvi
.cchTextMax
= strlen(lvi
.pszText
)+1;
2427 SendMessage(LVM_SETITEMTEXT
, (WPARAM
)row
, (LPARAM
)&lvi
);
2429 // Continue with column 2.
2431 lvi
.pszText
= szMsg
;
2432 lvi
.cchTextMax
= strlen(lvi
.pszText
)+1;
2433 SendMessage(LVM_SETITEMTEXT
, (WPARAM
)row
, (LPARAM
)&lvi
);
2435 // Save last row position
2441 bool CMainList::SplitErrorLine(char * line
){
2444 // line => [unit]:[line_n°]: [error message]
2445 // or => [unit]: [error message]
2454 /* Not an error line */
2455 //strcpy(szMsg, szUnit);
2458 }else if (*chr
== ':'){
2459 if (*(chr
+1) == '\\'){
2477 if (*chr
&& isdigit(*chr
)){ //@@ *chr=0 ?
2478 while (*chr
&& *chr
!= ':'){
2507 /********************************************************************
2514 ********************************************************************/
2515 CLogList::CLogList(){
2518 CLogList::~CLogList(){
2521 void CLogList::Create(CWindow
* pParent
){
2525 WS_CHILD
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
| LVS_REPORT
2526 | LVS_NOCOLUMNHEADER
);
2528 SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE
,
2529 LVS_EX_FULLROWSELECT
, LVS_EX_FULLROWSELECT
);
2533 lvc
.mask
= LVCF_FMT
| LVCF_WIDTH
| LVCF_TEXT
| LVCF_SUBITEM
;
2534 lvc
.fmt
= LVCFMT_LEFT
;
2538 lvc
.pszText
= "Message";
2539 SendMessage(LVM_INSERTCOLUMN
, 0, (LPARAM
) &lvc
);
2542 bool CLogList::SetPosition(HWND hInsertAfter
, int x
, int y
, int width
, int height
, UINT uFlags
){
2543 ::SendMessage(_hWnd
, WM_SETREDRAW
, FALSE
, 0);
2544 ::SetWindowPos(_hWnd
, hInsertAfter
, x
, y
, width
, height
, uFlags
);
2545 ::SendMessage(_hWnd
, LVM_SETCOLUMNWIDTH
, 0, MAKELPARAM((int) width
-22, 0));
2546 ::SendMessage(_hWnd
, WM_SETREDRAW
, TRUE
, 0);
2550 bool CLogList::Append(char * line
, WORD
/*outputFlag*/){
2555 /* if (outputFlag != LVOUT_ERROR)
2558 // Fill in List View columns, first is column 0.
2560 lvi
.mask
= LVIF_TEXT
; // | LVIF_PARAM;
2564 lvi
.cchTextMax
= strlen(lvi
.pszText
)+1;
2567 row
= SendMessage(LVM_INSERTITEM
, 0, (LPARAM
) &lvi
);
2569 // Save last row position
2576 /********************************************************************
2579 * Purpose: Linked List Node for file parameters.
2583 ********************************************************************/
2584 CFileItem::CFileItem(){
2588 szFileName
[MAX_PATH
- 1] = '\0'; // security.
2598 isInProject
= false;
2601 CFileItem::~CFileItem(){
2605 /********************************************************************
2608 * Purpose: A CList with a dedicated Compare() procedure.
2612 ********************************************************************/
2613 CFileList::CFileList(){
2616 CFileList::~CFileList(){
2619 int CFileList::Compare(CNode
*node1
, CNode
*node2
){
2620 return stricmp(((CFileItem
*)node1
)->szFileName
, ((CFileItem
*)node2
)->szFileName
);