mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
2623 lines
60 KiB
C++
2623 lines
60 KiB
C++
|
/********************************************************************
|
|||
|
* Module: main.cpp. This is part of Visual-MinGW.
|
|||
|
*
|
|||
|
* Purpose: Main module.
|
|||
|
*
|
|||
|
* Authors: Manu B.
|
|||
|
*
|
|||
|
* License: Visual-MinGW is a C/C++ Integrated Development Environment.
|
|||
|
* Copyright (C) 2001 Manu.
|
|||
|
*
|
|||
|
* This program is free software; you can redistribute it and/or modify
|
|||
|
* it under the terms of the GNU General Public License as published by
|
|||
|
* the Free Software Foundation; either version 2 of the License, or
|
|||
|
* (at your option) any later version.
|
|||
|
*
|
|||
|
* This program is distributed in the hope that it will be useful,
|
|||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
|
* GNU General Public License for more details.
|
|||
|
*
|
|||
|
* You should have received a copy of the GNU General Public License
|
|||
|
* along with this program; if not, write to the Free Software
|
|||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|||
|
* USA.
|
|||
|
*
|
|||
|
* (See license.htm for more details.)
|
|||
|
*
|
|||
|
* Revisions:
|
|||
|
* Manu B. 12/15/01 CFileList created.
|
|||
|
*
|
|||
|
********************************************************************/
|
|||
|
#include <windows.h>
|
|||
|
#include <commctrl.h>
|
|||
|
#include <stdio.h>
|
|||
|
#include <ctype.h>
|
|||
|
#include "process.h"
|
|||
|
#include "project.h"
|
|||
|
#include "main.h"
|
|||
|
#include "rsrc.h"
|
|||
|
|
|||
|
#define MSG_MODIFIED "Modified"
|
|||
|
|
|||
|
CCriticalSection CriticalSection;
|
|||
|
extern CMessageBox MsgBox;
|
|||
|
CFindReplaceDlg EditorDlg;
|
|||
|
void Main_CmdTest(HWND hwnd);
|
|||
|
|
|||
|
/* Globals */
|
|||
|
char * g_env_path = NULL;
|
|||
|
char * g_vm_path = NULL;
|
|||
|
CWinApp winApp;
|
|||
|
CProject Project;
|
|||
|
CChrono Chrono;
|
|||
|
|
|||
|
// File filters & flags.
|
|||
|
DWORD singleFileOpen = OFN_EXPLORER | OFN_FILEMUSTEXIST;
|
|||
|
DWORD multipleFileOpen = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT;
|
|||
|
DWORD fileSave = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY |
|
|||
|
OFN_OVERWRITEPROMPT;
|
|||
|
|
|||
|
char * defFilter = "All Sources\0*.c;*.cpp;*.cxx;*.h;*.hpp;*.hxx;*.rc;*.mingw;*.prj\0"
|
|||
|
"C Files\0*.c;*.cpp;*.cxx;*.rc\0"
|
|||
|
"Headers\0*.h;*.hpp;*.hxx\0"
|
|||
|
"Ini file\0*.ini\0"
|
|||
|
"All Files (*.*)\0*.*\0\0";
|
|||
|
|
|||
|
char * prjFilter = "Project Files (*.prj)\0*.prj\0All Files (*.*)\0*.*\0\0";
|
|||
|
char * prjDefExt = "prj";
|
|||
|
|
|||
|
char * srcFilter = "All Sources\0*.c;*.cpp;*.cxx;*.h;*.hpp;*.hxx;*.rc\0"
|
|||
|
"C Files\0*.c;*.cpp;*.cxx;*.rc\0"
|
|||
|
"Headers\0*.h;*.hpp;*.hxx\0"
|
|||
|
"All Files (*.*)\0*.*\0\0";
|
|||
|
char * srcDefExt = "cpp";
|
|||
|
|
|||
|
/* For tests */
|
|||
|
CChooseFontDlg CChooseFont;
|
|||
|
void Main_CmdTest(HWND){
|
|||
|
winApp.Process.AddTask(
|
|||
|
"sh.exe",
|
|||
|
IN_PIPE || OUTERR_PIPE,
|
|||
|
LVOUT_ERROR);
|
|||
|
winApp.Process.Run();
|
|||
|
/* CChooseFont.Create(&winApp);*/
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/********************************************************************
|
|||
|
* Class: CFileDlg.
|
|||
|
*
|
|||
|
* Purpose: A CFileDlgBase for Open/Save dlg boxes.
|
|||
|
*
|
|||
|
* Revisions:
|
|||
|
*
|
|||
|
********************************************************************/
|
|||
|
CFileDlg::CFileDlg(){
|
|||
|
}
|
|||
|
|
|||
|
CFileDlg::~CFileDlg(){
|
|||
|
}
|
|||
|
|
|||
|
bool CFileDlg::Open(CWindow * pWindow, char * pszFileName, DWORD nMaxFile, int fileflag){
|
|||
|
|
|||
|
switch(fileflag){
|
|||
|
// Project file.
|
|||
|
case PRJ_FILE:
|
|||
|
SetData(prjFilter, prjDefExt, singleFileOpen);
|
|||
|
break;
|
|||
|
|
|||
|
// Add multiple files to project.
|
|||
|
case ADD_SRC_FILE:
|
|||
|
Reset();
|
|||
|
SetTitle("Add files to project");
|
|||
|
nMaxFile = 2048;
|
|||
|
SetFilterIndex(1);
|
|||
|
SetData(srcFilter, srcDefExt, multipleFileOpen);
|
|||
|
break;
|
|||
|
|
|||
|
default: // SRC_FILE
|
|||
|
SetData(defFilter, srcDefExt, singleFileOpen);
|
|||
|
SetFilterIndex(1);
|
|||
|
break;
|
|||
|
}
|
|||
|
return OpenFileName(pWindow, pszFileName, nMaxFile);
|
|||
|
}
|
|||
|
|
|||
|
bool CFileDlg::Save(CWindow * pWindow, char * pszFileName, DWORD nMaxFile, int fileflag){
|
|||
|
Reset();
|
|||
|
|
|||
|
switch(fileflag){
|
|||
|
case SRC_FILE:
|
|||
|
SetData(defFilter, srcDefExt, fileSave);
|
|||
|
SetFilterIndex(1);
|
|||
|
break;
|
|||
|
|
|||
|
default: // PRJ_FILE
|
|||
|
SetData(prjFilter, prjDefExt, fileSave);
|
|||
|
break;
|
|||
|
}
|
|||
|
return SaveFileName(pWindow, pszFileName, nMaxFile);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/********************************************************************
|
|||
|
* Class: CPreferencesDlg.
|
|||
|
*
|
|||
|
* Purpose:
|
|||
|
*
|
|||
|
* Revisions:
|
|||
|
*
|
|||
|
********************************************************************/
|
|||
|
CPreferencesDlg::CPreferencesDlg(){
|
|||
|
}
|
|||
|
|
|||
|
CPreferencesDlg::~CPreferencesDlg(){
|
|||
|
}
|
|||
|
|
|||
|
int CPreferencesDlg::Create(void){
|
|||
|
return CreateModal(&winApp, IDD_PREFERENCES, (LPARAM) this);
|
|||
|
}
|
|||
|
|
|||
|
LRESULT CALLBACK CPreferencesDlg::CDlgProc(UINT Message, WPARAM wParam, LPARAM lParam){
|
|||
|
switch(Message){
|
|||
|
case WM_INITDIALOG:
|
|||
|
return OnInitDialog((HWND) wParam, lParam);
|
|||
|
|
|||
|
case WM_NOTIFY:
|
|||
|
OnNotify((int) wParam, (LPNMHDR) lParam);
|
|||
|
break;
|
|||
|
|
|||
|
case WM_COMMAND:
|
|||
|
OnCommand(HIWORD(wParam), LOWORD(wParam), (HWND) lParam);
|
|||
|
break;
|
|||
|
|
|||
|
case WM_CLOSE:
|
|||
|
EndDlg(0);
|
|||
|
break;
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CPreferencesDlg::OnInitDialog(HWND, LPARAM){
|
|||
|
// Tab control handle and TCITEM.
|
|||
|
_hWndTab = ::GetDlgItem(_hWnd, IDC_PREF_TABS);
|
|||
|
tcitem.mask = TCIF_TEXT | TCIF_PARAM;
|
|||
|
|
|||
|
// Insert tabs.
|
|||
|
HWND hwndChild = EnvDlg.Create(this, IDD_ENVIRON, NULL, (long) NULL);
|
|||
|
tcitem.pszText = "Environment";
|
|||
|
tcitem.lParam = (long) &EnvDlg;
|
|||
|
::SendMessage(_hWndTab, TCM_INSERTITEM, 0, (LPARAM)&tcitem);
|
|||
|
SetChildPosition(hwndChild);
|
|||
|
|
|||
|
/* tcitem.pszText = "General";
|
|||
|
tcitem.lParam = (long) NULL;
|
|||
|
::SendMessage(_hWndTab, TCM_INSERTITEM, 1, (LPARAM)&tcitem);
|
|||
|
|
|||
|
tcitem.pszText = "Find in files";
|
|||
|
tcitem.lParam = (long) NULL;
|
|||
|
::SendMessage(_hWndTab, TCM_INSERTITEM, 2, (LPARAM)&tcitem);*/
|
|||
|
|
|||
|
// Show the dialog and default pane.
|
|||
|
Show();
|
|||
|
EnvDlg.Show();
|
|||
|
EnvDlg.SetFocus();
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CPreferencesDlg::OnCommand(WORD, WORD wID, HWND){
|
|||
|
switch (wID){
|
|||
|
case IDOK:
|
|||
|
EnvDlg.OnCommand(0, wID, 0);
|
|||
|
EndDlg(IDOK);
|
|||
|
return TRUE;
|
|||
|
|
|||
|
case IDCANCEL:
|
|||
|
EndDlg(IDCANCEL);
|
|||
|
return FALSE;
|
|||
|
|
|||
|
case IDAPPLY:
|
|||
|
EnvDlg.OnCommand(0, wID, 0);
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CPreferencesDlg::EndDlg(int nResult){
|
|||
|
EnvDlg.EndDlg(0);
|
|||
|
EnvDlg.bIsVisible = false;
|
|||
|
if (_hWnd){
|
|||
|
BOOL result = ::EndDialog(_hWnd, nResult);
|
|||
|
_hWnd = 0;
|
|||
|
return result;
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/********************************************************************
|
|||
|
* Class: CEnvDlg.
|
|||
|
*
|
|||
|
* Purpose:
|
|||
|
*
|
|||
|
* Revisions:
|
|||
|
*
|
|||
|
********************************************************************/
|
|||
|
CEnvDlg::CEnvDlg(){
|
|||
|
}
|
|||
|
|
|||
|
CEnvDlg::~CEnvDlg(){
|
|||
|
}
|
|||
|
|
|||
|
LRESULT CALLBACK CEnvDlg::CDlgProc(UINT Message, WPARAM wParam, LPARAM lParam){
|
|||
|
switch(Message){
|
|||
|
case WM_INITDIALOG:
|
|||
|
return OnInitDialog((HWND) wParam, lParam);
|
|||
|
|
|||
|
case WM_COMMAND:
|
|||
|
OnCommand(HIWORD(wParam), LOWORD(wParam), (HWND) lParam);
|
|||
|
break;
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CEnvDlg::OnInitDialog(HWND, LPARAM){
|
|||
|
bIsVisible = false;
|
|||
|
bModified = false;
|
|||
|
/* Get control handles */
|
|||
|
hApply = ::GetDlgItem(_pParent->_hWnd, IDAPPLY);
|
|||
|
hSetCcBin = GetItem(IDC_SET_CCBIN);
|
|||
|
hCcBinDir = GetItem(IDC_CCBIN);
|
|||
|
hBrowseCc = GetItem(IDC_BROWSE_CC);
|
|||
|
hSetCmdBin = GetItem(IDC_SET_CMDBIN);
|
|||
|
hCmdBinDir = GetItem(IDC_CMDBIN);
|
|||
|
hBrowseCmd = GetItem(IDC_BROWSE_CMD);
|
|||
|
hAutoexec = GetItem(IDC_AUTOEXEC);
|
|||
|
hEnvView = GetItem(IDC_ENV_VIEW);
|
|||
|
|
|||
|
if (winApp.bSetCcEnv)
|
|||
|
::SendMessage(hSetCcBin, BM_SETCHECK, BST_CHECKED, 0);
|
|||
|
if (winApp.bSetCmdEnv)
|
|||
|
::SendMessage(hSetCmdBin, BM_SETCHECK, BST_CHECKED, 0);
|
|||
|
if (winApp.bSetDefEnv)
|
|||
|
::SendMessage(hAutoexec, BM_SETCHECK, BST_CHECKED, 0);
|
|||
|
|
|||
|
SetItemText(hCcBinDir, winApp.szCcBinDir);
|
|||
|
SetItemText(hCmdBinDir, winApp.szCmdBinDir);
|
|||
|
SetEnvText();
|
|||
|
/* hCcIncDir = GetItem(IDC_CC_INCDIR);
|
|||
|
|
|||
|
SetItemText(hCcIncDir, winApp.includeDir);*/
|
|||
|
bIsVisible = true;
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CEnvDlg::OnCommand(WORD wNotifyCode, WORD wID, HWND){
|
|||
|
char directory[MAX_PATH];
|
|||
|
|
|||
|
switch (wID){
|
|||
|
case IDC_BROWSE_CC:
|
|||
|
if (winApp.ShellDlg.BrowseForFolder(&winApp, directory, "Browse",
|
|||
|
BIF_RETURNONLYFSDIRS)){
|
|||
|
SetItemText(hCcBinDir, directory);
|
|||
|
}
|
|||
|
return TRUE;
|
|||
|
|
|||
|
case IDC_BROWSE_CMD:
|
|||
|
if (winApp.ShellDlg.BrowseForFolder(&winApp, directory, "Browse",
|
|||
|
BIF_RETURNONLYFSDIRS)){
|
|||
|
SetItemText(hCmdBinDir, directory);
|
|||
|
}
|
|||
|
return TRUE;
|
|||
|
|
|||
|
case IDOK:
|
|||
|
winApp.bSetCcEnv =
|
|||
|
(BST_CHECKED==::SendMessage(hSetCcBin, BM_GETCHECK, 0, 0));
|
|||
|
winApp.bSetCmdEnv =
|
|||
|
(BST_CHECKED==::SendMessage(hSetCmdBin, BM_GETCHECK, 0, 0));
|
|||
|
winApp.bSetDefEnv =
|
|||
|
(BST_CHECKED==::SendMessage(hAutoexec, BM_GETCHECK, 0, 0));
|
|||
|
|
|||
|
GetItemText(hCcBinDir, winApp.szCcBinDir, MAX_PATH);
|
|||
|
GetItemText(hCmdBinDir, winApp.szCmdBinDir, MAX_PATH);
|
|||
|
// GetItemText(hCcIncDir, winApp.includeDir, MAX_PATH);
|
|||
|
if (bModified)
|
|||
|
winApp.SetEnv();
|
|||
|
return TRUE;
|
|||
|
|
|||
|
case IDCANCEL:
|
|||
|
return FALSE;
|
|||
|
|
|||
|
case IDAPPLY:
|
|||
|
if (bModified){
|
|||
|
winApp.bSetCcEnv =
|
|||
|
(BST_CHECKED==::SendMessage(hSetCcBin, BM_GETCHECK, 0, 0));
|
|||
|
winApp.bSetCmdEnv =
|
|||
|
(BST_CHECKED==::SendMessage(hSetCmdBin, BM_GETCHECK, 0, 0));
|
|||
|
winApp.bSetDefEnv =
|
|||
|
(BST_CHECKED==::SendMessage(hAutoexec, BM_GETCHECK, 0, 0));
|
|||
|
|
|||
|
GetItemText(hCcBinDir, winApp.szCcBinDir, MAX_PATH);
|
|||
|
GetItemText(hCmdBinDir, winApp.szCmdBinDir, MAX_PATH);
|
|||
|
winApp.SetEnv();
|
|||
|
SetEnvText();
|
|||
|
bModified = false;
|
|||
|
::EnableWindow(hApply, false);
|
|||
|
}
|
|||
|
return TRUE;
|
|||
|
|
|||
|
default:
|
|||
|
if (bIsVisible && !bModified){
|
|||
|
switch(wNotifyCode){
|
|||
|
case EN_CHANGE:
|
|||
|
case BN_CLICKED:
|
|||
|
bModified = true;
|
|||
|
::EnableWindow(hApply, true);
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
void CEnvDlg::SetEnvText(void){
|
|||
|
if (g_vm_path){
|
|||
|
char * text = (char *) malloc(strlen(g_vm_path)+20); // 10 lines max.
|
|||
|
char * start = text;
|
|||
|
char * parse = g_vm_path;
|
|||
|
while (*parse){
|
|||
|
if (*parse == ';'){
|
|||
|
// Change ';' into CR/LF.
|
|||
|
*text = '\r';
|
|||
|
text++;
|
|||
|
*text = '\n';
|
|||
|
text++;
|
|||
|
parse++;
|
|||
|
}else if (*parse == '='){
|
|||
|
// Rewind buffer.
|
|||
|
text = start;
|
|||
|
parse++;
|
|||
|
}else{
|
|||
|
// Copy one char.
|
|||
|
*text = *parse;
|
|||
|
text++;
|
|||
|
parse++;
|
|||
|
}
|
|||
|
}
|
|||
|
*text = '\0';
|
|||
|
SetItemText(hEnvView, start);
|
|||
|
free(start);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/********************************************************************
|
|||
|
* Class: CGrepDlg.
|
|||
|
*
|
|||
|
* Purpose:
|
|||
|
*
|
|||
|
* Revisions:
|
|||
|
*
|
|||
|
********************************************************************/
|
|||
|
CGrepDlg::CGrepDlg(){
|
|||
|
*findWhat = '\0';
|
|||
|
*gDir = '\0';
|
|||
|
}
|
|||
|
|
|||
|
CGrepDlg::~CGrepDlg(){
|
|||
|
}
|
|||
|
|
|||
|
int CGrepDlg::Create(void){
|
|||
|
return CreateModal(&winApp, IDD_GREP, (LPARAM) this);
|
|||
|
}
|
|||
|
|
|||
|
LRESULT CALLBACK CGrepDlg::CDlgProc(UINT Message, WPARAM wParam, LPARAM lParam){
|
|||
|
switch(Message){
|
|||
|
case WM_INITDIALOG:
|
|||
|
return OnInitDialog((HWND) wParam, lParam);
|
|||
|
|
|||
|
case WM_COMMAND:
|
|||
|
OnCommand(HIWORD(wParam), LOWORD(wParam), (HWND) lParam);
|
|||
|
break;
|
|||
|
|
|||
|
case WM_CLOSE:
|
|||
|
EndDlg(0);
|
|||
|
break;
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CGrepDlg::OnInitDialog(HWND, LPARAM){
|
|||
|
hFindWhat = GetItem(IDC_FINDWHAT);
|
|||
|
hgDir = GetItem(IDC_GFILTER);
|
|||
|
|
|||
|
SetItemText(hFindWhat, findWhat);
|
|||
|
SetItemText(hgDir, gDir);
|
|||
|
// Show the dialog and default pane.
|
|||
|
Show();
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CGrepDlg::OnCommand(WORD, WORD wID, HWND){
|
|||
|
switch (wID){
|
|||
|
case IDOK:
|
|||
|
GetItemText(hFindWhat, findWhat, sizeof(findWhat));
|
|||
|
GetItemText(hgDir, gDir, sizeof(gDir));
|
|||
|
FindInFiles(findWhat, gDir);
|
|||
|
return TRUE;
|
|||
|
|
|||
|
case IDCANCEL:
|
|||
|
EndDlg(IDCANCEL);
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
void CGrepDlg::FindInFiles(char * findWhat, char * fileFilter){
|
|||
|
if (!findWhat || !fileFilter || winApp.Process.isRunning())
|
|||
|
return;
|
|||
|
|
|||
|
winApp.Report.Clear();
|
|||
|
winApp.Report.Append("Grep search...", LVOUT_NORMAL);
|
|||
|
|
|||
|
winApp.Process.AddTask("grep -G -n -H ", OUTERR_PIPE, LVOUT_ERROR);
|
|||
|
winApp.Process.CmdCat(findWhat);
|
|||
|
winApp.Process.CmdCat(" ");
|
|||
|
winApp.Process.CmdCat(fileFilter);
|
|||
|
|
|||
|
winApp.Process.Run();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/********************************************************************
|
|||
|
* Functions: WinMain procedure.
|
|||
|
*
|
|||
|
* Purpose: Runs the application.
|
|||
|
*
|
|||
|
* Revisions:
|
|||
|
*
|
|||
|
********************************************************************/
|
|||
|
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
|
|||
|
return winApp.Run(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/********************************************************************
|
|||
|
* Class: CWinApp.
|
|||
|
*
|
|||
|
* Purpose: Manages the all application.
|
|||
|
*
|
|||
|
* Revisions:
|
|||
|
*
|
|||
|
********************************************************************/
|
|||
|
CWinApp::CWinApp(){
|
|||
|
*iniFileName = '\0';
|
|||
|
hmod = NULL;
|
|||
|
*openFilesDir ='\0';
|
|||
|
*projectDir = '\0';
|
|||
|
*includeDir = '\0';
|
|||
|
bSetCcEnv = false;
|
|||
|
bSetCmdEnv = false;
|
|||
|
bSetDefEnv = false;
|
|||
|
*szCcBinDir = '\0';
|
|||
|
*szCmdBinDir = '\0';
|
|||
|
|
|||
|
firstRun = false;
|
|||
|
// Child windows dimensions.
|
|||
|
deltaY = 0;
|
|||
|
tbarHeight = 26;
|
|||
|
sbarHeight = 20;
|
|||
|
tvWidth = 140;
|
|||
|
lvHeight = 120;
|
|||
|
|
|||
|
hSplitter = 4;
|
|||
|
vSplitter = 4;
|
|||
|
}
|
|||
|
|
|||
|
CWinApp::~CWinApp(){
|
|||
|
}
|
|||
|
|
|||
|
bool CWinApp::CustomInit(void){
|
|||
|
/* Get PATH environment variable */
|
|||
|
char * env_path = getenv("PATH");
|
|||
|
if (env_path)
|
|||
|
g_env_path = strdup(env_path);
|
|||
|
|
|||
|
SetName("Visual MinGW", APP_VERSION);
|
|||
|
MsgBox.SetCaption("Visual MinGW");
|
|||
|
IsWinNT();
|
|||
|
ReadIniFile("visual-mingw.ini");
|
|||
|
|
|||
|
hAccel = LoadAccelerators(_hInst, "ACCELS");
|
|||
|
hmod = LoadLibrary("SciLexer.DLL");
|
|||
|
if (!hmod){
|
|||
|
MsgBox.DisplayFatal("Unable to load SciLexer.DLL");
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool CWinApp::Release(void){
|
|||
|
WriteIniFile();
|
|||
|
if (hmod)
|
|||
|
FreeLibrary(hmod);
|
|||
|
if (g_env_path)
|
|||
|
free(g_env_path);
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool CWinApp::ReadIniFile(char * fileName){
|
|||
|
ParseCmdLine(iniFileName);
|
|||
|
strcat(iniFileName, fileName);
|
|||
|
|
|||
|
if (!IniFile.Load(iniFileName)){
|
|||
|
/* Create an empty file and fill it */
|
|||
|
firstRun = true;
|
|||
|
MsgBox.DisplayWarning("Visual-MinGW first run !\n"
|
|||
|
"Step 1: User interface initialization.\n"
|
|||
|
"Please report bugs to Visual-MinGW home page.\n"
|
|||
|
"See the Readme text for more information.");
|
|||
|
FILE * file = fopen(iniFileName, "wb");
|
|||
|
if (!file)
|
|||
|
return false;
|
|||
|
SaveIniFile(file);
|
|||
|
fclose(file);
|
|||
|
return false;
|
|||
|
}
|
|||
|
// [General] section
|
|||
|
IniFile.GetString(openFilesDir, "FilesDirectory", "General" );
|
|||
|
IniFile.GetString(projectDir, "ProjectDirectory" );
|
|||
|
bSetDefEnv = IniFile.GetInt( "SetDefEnv" );
|
|||
|
bSetCmdEnv = IniFile.GetInt( "SetBinDir" );
|
|||
|
IniFile.GetString(szCmdBinDir, "BinDir" );
|
|||
|
// [Compiler] section
|
|||
|
IniFile.GetString(includeDir, "IncludeDir", "Compiler" );
|
|||
|
bSetCcEnv = IniFile.GetInt( "SetBinDir" );
|
|||
|
IniFile.GetString(szCcBinDir, "BinDir" );
|
|||
|
|
|||
|
SetEnv();
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
void CWinApp::SaveIniFile(FILE * file){
|
|||
|
// [General]
|
|||
|
fprintf (file, "\t; Generated automatically by Visual-MinGW.\n");
|
|||
|
fprintf (file, "\t ; http://visual-mingw.sourceforge.net/\n");
|
|||
|
fprintf (file, "[General]\nSignature = 40");
|
|||
|
fprintf (file, "\nFilesDirectory = %s", openFilesDir);
|
|||
|
fprintf (file, "\nProjectDirectory = %s", projectDir);
|
|||
|
fprintf (file, "\nTvWidth = %d", tvWidth);
|
|||
|
fprintf (file, "\nLvHeight = %d", lvHeight);
|
|||
|
fprintf (file, "\nSetDefEnv = %d", bSetDefEnv);
|
|||
|
fprintf (file, "\nSetBinDir = %d", bSetCmdEnv);
|
|||
|
fprintf (file, "\nBinDir = %s", szCmdBinDir);
|
|||
|
// [Compiler]
|
|||
|
fprintf (file, "\n\n[Compiler]\nIncludeDir = %s", includeDir);
|
|||
|
fprintf (file, "\nSetBinDir = %d", bSetCcEnv);
|
|||
|
fprintf (file, "\nBinDir = %s", szCcBinDir);
|
|||
|
}
|
|||
|
|
|||
|
bool CWinApp::WriteIniFile(void){
|
|||
|
if (*iniFileName == '\0')
|
|||
|
return false;
|
|||
|
FILE * file = fopen(iniFileName, "wb");
|
|||
|
if (!file)
|
|||
|
return false;
|
|||
|
SaveIniFile(file);
|
|||
|
fclose(file);
|
|||
|
IniFile.Close();
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool CWinApp::SetEnv(void){
|
|||
|
// Free previous variable.
|
|||
|
//getenv("PATH=");
|
|||
|
// Malloc a buffer.
|
|||
|
int len = 0;
|
|||
|
if (bSetCcEnv)
|
|||
|
len += strlen(winApp.szCcBinDir);
|
|||
|
if (bSetCmdEnv)
|
|||
|
len += strlen(winApp.szCmdBinDir);
|
|||
|
if (bSetDefEnv && g_env_path)
|
|||
|
len += strlen(g_env_path);
|
|||
|
g_vm_path = (char *) malloc(len+8);
|
|||
|
|
|||
|
// Copy the environment variable.
|
|||
|
strcpy(g_vm_path, "PATH=");
|
|||
|
if (bSetCcEnv && *winApp.szCcBinDir){
|
|||
|
strcat(g_vm_path, winApp.szCcBinDir);
|
|||
|
strcat(g_vm_path, ";");
|
|||
|
}
|
|||
|
if (bSetCmdEnv && *winApp.szCmdBinDir){
|
|||
|
strcat(g_vm_path, winApp.szCmdBinDir);
|
|||
|
strcat(g_vm_path, ";");
|
|||
|
}
|
|||
|
if (bSetDefEnv && g_env_path)
|
|||
|
strcat(g_vm_path, g_env_path);
|
|||
|
|
|||
|
len = strlen(g_vm_path) - 1;
|
|||
|
if (g_vm_path[len] == ';')
|
|||
|
g_vm_path[len] = '\0';
|
|||
|
if (putenv(g_vm_path) == -1){
|
|||
|
free(g_vm_path);
|
|||
|
g_vm_path = NULL;
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/********************************************************************
|
|||
|
* CWinApp: Create each application's window.
|
|||
|
********************************************************************/
|
|||
|
bool CWinApp::CreateUI(void){
|
|||
|
|
|||
|
InitCommonControls();
|
|||
|
|
|||
|
// Custom values.
|
|||
|
wc.style = 0;
|
|||
|
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
|||
|
wc.hCursor = NULL;
|
|||
|
wc.hbrBackground = //NULL;
|
|||
|
(HBRUSH)(COLOR_INACTIVEBORDER + 1);
|
|||
|
wc.lpszMenuName = MAKEINTRESOURCE(ID_MENU);
|
|||
|
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
|
|||
|
|
|||
|
if(!MainRegisterEx("main_class")) {
|
|||
|
MsgBox.DisplayFatal("Can't Register Main Window");
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// Custom values.
|
|||
|
wc.hbrBackground = NULL;
|
|||
|
wc.lpszMenuName = 0;
|
|||
|
|
|||
|
if(!ChildRegisterEx("child_class")) {
|
|||
|
MsgBox.DisplayFatal("Can't Register MDI Class");
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// Use a CreateWindowEx like procedure.
|
|||
|
HWND hwnd = CreateEx(
|
|||
|
this, // Owner class.
|
|||
|
0,
|
|||
|
mainClass,
|
|||
|
appName,
|
|||
|
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
|
|||
|
CW_USEDEFAULT,
|
|||
|
CW_USEDEFAULT,
|
|||
|
CW_USEDEFAULT,
|
|||
|
CW_USEDEFAULT,
|
|||
|
0,
|
|||
|
NULL);
|
|||
|
|
|||
|
if(!hwnd) {
|
|||
|
MsgBox.DisplayFatal("Can't create Main window");
|
|||
|
return false;
|
|||
|
}
|
|||
|
MsgBox.SetParent(hwnd);
|
|||
|
|
|||
|
// SW_SHOWMAXIMIZED.
|
|||
|
::ShowWindow(hwnd, SW_SHOWMAXIMIZED);
|
|||
|
::UpdateWindow(hwnd);
|
|||
|
if (firstRun)
|
|||
|
FirstRunTest();
|
|||
|
firstRun = false;
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
void CWinApp::FirstRunTest(void){
|
|||
|
MsgBox.DisplayWarning("Visual-MinGW first run !\n"
|
|||
|
"Step 2: You will now set your environment variables.\n"
|
|||
|
"\"Use default environment variables\" should be checked.\n"
|
|||
|
"Then Visual-MinGW will try to launch the compiler.");
|
|||
|
PreferencesDlg.Create();
|
|||
|
MsgBox.DisplayWarning("Visual-MinGW first run !\n"
|
|||
|
"Step 3: Installation checking.\n"
|
|||
|
"Try to launch rm and gcc.\n"
|
|||
|
"See \"Main\" or \"Log\" report views for results.\n");
|
|||
|
winApp.Report.Clear();
|
|||
|
winApp.Report.Append("Testing for first run...", LVOUT_NORMAL);
|
|||
|
|
|||
|
// Put the command line and the run flag in the command stack.
|
|||
|
winApp.Process.AddTask("gcc -v", OUTERR_PIPE, LVOUT_NORMAL);
|
|||
|
winApp.Process.AddTask("rm --version", OUTERR_PIPE, LVOUT_NORMAL);
|
|||
|
winApp.Process.Run();
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
void CWinApp::CreateToolbar(void){
|
|||
|
Toolbar.CreateEx(
|
|||
|
this,
|
|||
|
0,
|
|||
|
WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
|
|||
|
|TBSTYLE_FLAT | TBSTYLE_TOOLTIPS
|
|||
|
| CCS_NORESIZE);
|
|||
|
|
|||
|
Toolbar.AddBitmap(IDB_TOOLBAR, 15);
|
|||
|
|
|||
|
TBBUTTON tbButtons [] =
|
|||
|
{ { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0, 0}, 0, 0},
|
|||
|
{ 0, IDM_NEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0},
|
|||
|
{ 1, IDM_OPEN, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0},
|
|||
|
{ 2, IDM_SAVE, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0},
|
|||
|
{ 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0, 0}, 0, 0},
|
|||
|
{ 3, IDM_CUT, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0},
|
|||
|
{ 4, IDM_COPY, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0},
|
|||
|
{ 5, IDM_PASTE, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0},
|
|||
|
{ 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0, 0}, 0, 0},
|
|||
|
{ 6, IDM_UNDO, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0},
|
|||
|
{ 7, IDM_REDO, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0} };
|
|||
|
|
|||
|
int numbutton = sizeof tbButtons/sizeof tbButtons[0];
|
|||
|
|
|||
|
Toolbar.AddButtons(&tbButtons[0], numbutton);
|
|||
|
}
|
|||
|
|
|||
|
void CWinApp::CreateSplitter(void){
|
|||
|
MainSplitter.Init(&ChildSplitter, &Report, SPLSTYLE_HORZ, lvHeight, SPLMODE_2);
|
|||
|
ChildSplitter.Init(&Manager, &MdiClient, SPLSTYLE_VERT, tvWidth, SPLMODE_1);
|
|||
|
|
|||
|
// File Manager.
|
|||
|
Manager.Create(this);
|
|||
|
// MDI client.
|
|||
|
CreateMDI();
|
|||
|
// ListView.
|
|||
|
Report.Create(this);
|
|||
|
}
|
|||
|
|
|||
|
void CWinApp::CreateMDI(void){
|
|||
|
MdiClient.Init(3, ID_FIRSTCHILD);
|
|||
|
MdiClient.CreateEx(
|
|||
|
this,
|
|||
|
WS_EX_CLIENTEDGE,
|
|||
|
WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
|
|||
|
| WS_VSCROLL | WS_HSCROLL
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
HWND CWinApp::CreateChild(char * caption, LPVOID lParam){
|
|||
|
|
|||
|
CChildView * mdiChild = new CChildView;
|
|||
|
|
|||
|
HWND hwnd = mdiChild->CreateEx(
|
|||
|
&MdiClient, // MUST be an MdiClient *.
|
|||
|
WS_EX_MDICHILD,
|
|||
|
MDIS_ALLCHILDSTYLES | WS_CHILD | WS_SYSMENU | WS_CAPTION
|
|||
|
| WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX
|
|||
|
| WS_MAXIMIZE,
|
|||
|
caption,
|
|||
|
0,
|
|||
|
lParam);
|
|||
|
|
|||
|
if (!hwnd)
|
|||
|
delete mdiChild;
|
|||
|
return hwnd;
|
|||
|
}
|
|||
|
|
|||
|
void CWinApp::CreateStatusBar(void){
|
|||
|
Sbar.CreateEx(
|
|||
|
this,
|
|||
|
0,
|
|||
|
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | SBARS_SIZEGRIP);
|
|||
|
|
|||
|
int sbWidths[] = {60, 120, -1};
|
|||
|
|
|||
|
int numparts = sizeof sbWidths/sizeof sbWidths[0];
|
|||
|
|
|||
|
Sbar.SetParts(numparts, &sbWidths[0]);
|
|||
|
}
|
|||
|
|
|||
|
void CWinApp::SendCaretPos(int caretPos) {
|
|||
|
// To display the "Line : xxxx" message, we use our standard msgBuf[256].
|
|||
|
sprintf(msgBuf, "Line : %d", caretPos);
|
|||
|
Sbar.SendMessage(SB_SETTEXT, 0, (LPARAM) msgBuf);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/********************************************************************
|
|||
|
* CWinApp: Message handling procedures.
|
|||
|
********************************************************************/
|
|||
|
LRESULT CALLBACK CWinApp::CMainWndProc(UINT Message, WPARAM wParam, LPARAM lParam){
|
|||
|
switch(Message){
|
|||
|
case WM_CREATE:
|
|||
|
return OnCreate((LPCREATESTRUCT) lParam);
|
|||
|
|
|||
|
case WM_PAINT:
|
|||
|
return OnPaint((HDC) wParam);
|
|||
|
|
|||
|
case WM_SIZE:
|
|||
|
return OnSize(wParam, LOWORD(lParam), HIWORD(lParam));
|
|||
|
|
|||
|
case WM_DESTROY:
|
|||
|
return OnDestroy();
|
|||
|
|
|||
|
case WM_COMMAND:
|
|||
|
return OnCommand(wParam, lParam);
|
|||
|
|
|||
|
case WM_CLOSE:
|
|||
|
return OnClose();
|
|||
|
|
|||
|
case WM_NOTIFY:
|
|||
|
return OnNotify((int) wParam, (LPNMHDR) lParam);
|
|||
|
|
|||
|
case WM_LBUTTONDOWN:
|
|||
|
return OnLButtonDown((short) LOWORD(lParam), (short) HIWORD(lParam), wParam);
|
|||
|
|
|||
|
case WM_MOUSEMOVE:
|
|||
|
return OnMouseMove((short) LOWORD(lParam), (short) HIWORD(lParam), wParam);
|
|||
|
|
|||
|
case WM_LBUTTONUP:
|
|||
|
return OnLButtonUp((short) LOWORD(lParam), (short) HIWORD(lParam), wParam);
|
|||
|
|
|||
|
case WM_SETCURSOR:
|
|||
|
OnSetCursor((HWND) wParam, (UINT) LOWORD(lParam), (UINT) HIWORD(lParam));
|
|||
|
return DefWindowProc(_hWnd, Message, wParam, lParam);
|
|||
|
|
|||
|
default:
|
|||
|
return DefFrameProc(_hWnd, MdiClient.GetId(), Message, wParam, lParam);
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CWinApp::OnCreate(LPCREATESTRUCT){
|
|||
|
// Toolbar.
|
|||
|
CreateToolbar();
|
|||
|
// Splitter.
|
|||
|
CreateSplitter();
|
|||
|
// Statusbar.
|
|||
|
CreateStatusBar();
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CWinApp::OnPaint(HDC){
|
|||
|
PAINTSTRUCT ps;
|
|||
|
BeginPaint(_hWnd, &ps);
|
|||
|
EndPaint(_hWnd, &ps);
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CWinApp::OnSize(UINT, int width, int height){
|
|||
|
// TreeView and MDI Client delta-height.
|
|||
|
deltaY = height-sbarHeight-lvHeight-vSplitter-tbarHeight;
|
|||
|
|
|||
|
if (deltaY>3){
|
|||
|
Toolbar.SetPosition(0,
|
|||
|
0, 0,
|
|||
|
width, tbarHeight,
|
|||
|
0);
|
|||
|
|
|||
|
MainSplitter.SetPosition(0,
|
|||
|
0, tbarHeight,
|
|||
|
width, height-tbarHeight-sbarHeight,
|
|||
|
0);
|
|||
|
|
|||
|
Sbar.SetPosition(0,
|
|||
|
0, height-sbarHeight,
|
|||
|
width, sbarHeight,
|
|||
|
0);
|
|||
|
}
|
|||
|
InvalidateRect(_hWnd, NULL, false);
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CWinApp::OnDestroy(void){
|
|||
|
PostQuitMessage(0);
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CWinApp::OnClose(void){
|
|||
|
if (IDCANCEL == Manager.SaveAll(IDASK)) // Ask to save.
|
|||
|
return TRUE; // Cancelled by user.
|
|||
|
::DestroyWindow(_hWnd);
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CWinApp::OnNotify(int idCtrl, LPNMHDR notify){
|
|||
|
Manager.OnNotify(idCtrl, notify);
|
|||
|
Report.OnNotify(idCtrl, notify);
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CWinApp::OnLButtonDown(short xPos, short yPos, UINT){
|
|||
|
MainSplitter.OnLButtonDown(_hWnd, xPos, yPos);
|
|||
|
ChildSplitter.OnLButtonDown(_hWnd, xPos, yPos);
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CWinApp::OnMouseMove(short xPos, short yPos, UINT){
|
|||
|
MainSplitter.OnMouseMove(_hWnd, xPos, yPos);
|
|||
|
ChildSplitter.OnMouseMove(_hWnd, xPos, yPos);
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CWinApp::OnLButtonUp(short xPos, short yPos, UINT){
|
|||
|
MainSplitter.OnLButtonUp(_hWnd, xPos, yPos);
|
|||
|
ChildSplitter.OnLButtonUp(_hWnd, xPos, yPos);
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CWinApp::OnSetCursor(HWND, UINT nHittest, UINT){
|
|||
|
if (nHittest == HTCLIENT) {
|
|||
|
if (MainSplitter.OnSetCursor(_hWnd, 0)){
|
|||
|
return 0;
|
|||
|
}else if (ChildSplitter.OnSetCursor(_hWnd, 0)){
|
|||
|
return 0;
|
|||
|
}else{
|
|||
|
::SetCursor(::LoadCursor(NULL, IDC_ARROW));
|
|||
|
}
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/********************************************************************
|
|||
|
* CWinApp: Dispatch command messages.
|
|||
|
********************************************************************/
|
|||
|
BOOL CWinApp::OnCommand(WPARAM wParam, LPARAM lParam){
|
|||
|
int wID = LOWORD(wParam);
|
|||
|
|
|||
|
switch (wID){
|
|||
|
/* File Menu */
|
|||
|
case IDM_NEW:
|
|||
|
Manager.FilesView.New();
|
|||
|
break;
|
|||
|
|
|||
|
case IDM_OPEN:
|
|||
|
Manager.OpenFileDialog();
|
|||
|
break;
|
|||
|
|
|||
|
case IDM_NEW_PROJECT:
|
|||
|
Manager.NewProjectDialog();
|
|||
|
break;
|
|||
|
|
|||
|
case IDM_OPEN_PROJECT:
|
|||
|
Manager.OpenProjectDialog();
|
|||
|
break;
|
|||
|
|
|||
|
case IDM_SAVE_PROJECT:
|
|||
|
Manager.SaveProjectFiles(IDYES);
|
|||
|
break;
|
|||
|
|
|||
|
case IDM_CLOSE_PROJECT:
|
|||
|
Manager.CloseProject();
|
|||
|
break;
|
|||
|
|
|||
|
case IDM_PREFERENCES:
|
|||
|
PreferencesDlg.Create();
|
|||
|
break;
|
|||
|
|
|||
|
case IDM_QUIT:
|
|||
|
PostMessage(_hWnd, WM_CLOSE, 0, 0);
|
|||
|
break;
|
|||
|
|
|||
|
/* Find Menu */
|
|||
|
case IDM_GREP:
|
|||
|
GrepDlg.Create();
|
|||
|
break;
|
|||
|
|
|||
|
/* Window Menu */
|
|||
|
case IDM_CASCADE:
|
|||
|
PostMessage(MdiClient.GetId(), WM_MDICASCADE, 0, 0);
|
|||
|
break;
|
|||
|
case IDM_TILEHORZ:
|
|||
|
PostMessage(MdiClient.GetId(), WM_MDITILE, MDITILE_HORIZONTAL, 0);
|
|||
|
break;
|
|||
|
case IDM_TILEVERT:
|
|||
|
PostMessage(MdiClient.GetId(), WM_MDITILE, MDITILE_VERTICAL, 0);
|
|||
|
break;
|
|||
|
case IDM_ARRANGE:
|
|||
|
PostMessage(MdiClient.GetId(), WM_MDIICONARRANGE, 0, 0);
|
|||
|
break;
|
|||
|
|
|||
|
/* Project Menu */
|
|||
|
case IDM_NEW_MODULE:
|
|||
|
Project.NewModuleDlg();
|
|||
|
break;
|
|||
|
|
|||
|
case IDM_ADD:
|
|||
|
Project.AddFiles();
|
|||
|
break;
|
|||
|
|
|||
|
case IDM_REMOVE_FILE:
|
|||
|
Manager.RemoveProjectFile();
|
|||
|
break;
|
|||
|
|
|||
|
case IDM_REMOVE_MODULE:
|
|||
|
Manager.RemoveProjectModule();
|
|||
|
break;
|
|||
|
|
|||
|
case IDM_OPTION:
|
|||
|
Project.OptionsDlg();
|
|||
|
break;
|
|||
|
|
|||
|
case IDM_ZIP_SRCS:
|
|||
|
Project.ZipSrcs();
|
|||
|
break;
|
|||
|
|
|||
|
case IDM_EXPLORE:
|
|||
|
Project.Explore(_hWnd);
|
|||
|
break;
|
|||
|
|
|||
|
/* Build Menu */
|
|||
|
case IDM_BUILD:
|
|||
|
Project.Build();
|
|||
|
break;
|
|||
|
|
|||
|
case IDM_REBUILDALL:
|
|||
|
Project.RebuildAll();
|
|||
|
break;
|
|||
|
|
|||
|
case IDM_RUN_TARGET:
|
|||
|
Project.RunTarget();
|
|||
|
break;
|
|||
|
|
|||
|
case IDM_MKCLEAN:
|
|||
|
Project.MakeClean();
|
|||
|
break;
|
|||
|
|
|||
|
case IDM_MKF_BUILD:
|
|||
|
Project.BuildMakefile();
|
|||
|
break;
|
|||
|
|
|||
|
case IDM_RUN_CMD:
|
|||
|
winApp.Process.CommandDlg.Create();
|
|||
|
break;
|
|||
|
|
|||
|
case IDM_TEST:
|
|||
|
Main_CmdTest(_hWnd);
|
|||
|
break;
|
|||
|
|
|||
|
default:{
|
|||
|
if (wID >= ID_FIRSTCHILD){
|
|||
|
DefFrameProc(_hWnd, MdiClient.GetId(), WM_COMMAND, wParam, lParam);
|
|||
|
}else{
|
|||
|
HWND hChildWindow = (HWND) MdiClient.SendMessage(WM_MDIGETACTIVE);
|
|||
|
|
|||
|
if (hChildWindow)
|
|||
|
::SendMessage(hChildWindow, WM_COMMAND, wParam, lParam);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/********************************************************************
|
|||
|
* CWinApp: Handles child messages.
|
|||
|
********************************************************************/
|
|||
|
LRESULT CALLBACK CWinApp::CChildWndProc(CWindow * pWnd, UINT Message, WPARAM wParam, LPARAM lParam){
|
|||
|
|
|||
|
CChildView * childView = (CChildView *) pWnd;
|
|||
|
HWND hwndChild = childView->_hWnd;
|
|||
|
|
|||
|
switch(Message){
|
|||
|
case WM_CREATE:
|
|||
|
childView->OnCreate((LPCREATESTRUCT) lParam);
|
|||
|
break;
|
|||
|
|
|||
|
case WM_SIZE:
|
|||
|
childView->OnSize(wParam, LOWORD(lParam), HIWORD(lParam));
|
|||
|
break;
|
|||
|
|
|||
|
case WM_COMMAND:
|
|||
|
childView->OnCommand(wParam, lParam);
|
|||
|
break;
|
|||
|
|
|||
|
case WM_DESTROY:
|
|||
|
childView->OnDestroy();
|
|||
|
break;
|
|||
|
|
|||
|
case WM_CLOSE:
|
|||
|
if (childView->OnClose()){
|
|||
|
MdiClient.SendMessage(WM_MDIDESTROY,(WPARAM) hwndChild, 0);
|
|||
|
}
|
|||
|
return true;
|
|||
|
|
|||
|
case WM_NOTIFY:
|
|||
|
childView->OnNotify((int) wParam, (LPNMHDR) lParam);
|
|||
|
break;
|
|||
|
|
|||
|
case WM_SETFOCUS:
|
|||
|
childView->OnSetFocus((HWND) wParam);
|
|||
|
break;
|
|||
|
|
|||
|
case WM_MDIACTIVATE:
|
|||
|
childView->OnActivate((HWND) wParam, (HWND) lParam);
|
|||
|
break;
|
|||
|
}
|
|||
|
return DefMDIChildProc(hwndChild, Message, wParam, lParam);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/********************************************************************
|
|||
|
* Class: CChildView.
|
|||
|
*
|
|||
|
* Purpose: MDI child window class.
|
|||
|
*
|
|||
|
* Revisions:
|
|||
|
*
|
|||
|
********************************************************************/
|
|||
|
CChildView::CChildView(){
|
|||
|
modified = false;
|
|||
|
}
|
|||
|
|
|||
|
CChildView::~CChildView(){
|
|||
|
}
|
|||
|
|
|||
|
bool CChildView::OnCreate(LPCREATESTRUCT){
|
|||
|
CFileItem * file = (CFileItem *) GetLong(GWL_USERDATA);
|
|||
|
|
|||
|
// Create Scintilla Editor Control.
|
|||
|
HWND hwnd = Editor.CreateEx(
|
|||
|
this,
|
|||
|
0,
|
|||
|
WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
|
|||
|
| WS_VSCROLL | WS_HSCROLL);
|
|||
|
|
|||
|
if (!hwnd)
|
|||
|
return false; // @@TODO need to manage creation failure.
|
|||
|
|
|||
|
// Set window handles
|
|||
|
file->pMdiChild = this;
|
|||
|
|
|||
|
// Load a file if there is one to load.
|
|||
|
Editor.LoadFile(file);
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool CChildView::OnSize(UINT wParam, int width, int height){
|
|||
|
if(wParam != SIZE_MINIMIZED){
|
|||
|
Editor.SetPosition(0,
|
|||
|
0,
|
|||
|
0,
|
|||
|
width,
|
|||
|
height,
|
|||
|
0);
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CChildView::OnClose(void){
|
|||
|
if (modified){
|
|||
|
int decision = MsgBox.AskToSave(true);
|
|||
|
switch (decision){
|
|||
|
case IDCANCEL:
|
|||
|
return FALSE;
|
|||
|
|
|||
|
case IDYES:
|
|||
|
CmdSave();
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CChildView::OnDestroy(void){
|
|||
|
CFileItem * file = (CFileItem*) GetLong(GWL_USERDATA);
|
|||
|
|
|||
|
if (file){
|
|||
|
if (!file->isInProject){
|
|||
|
// A simple file.
|
|||
|
winApp.Manager.FilesView.CloseFile(file);
|
|||
|
}else{
|
|||
|
// A project one.
|
|||
|
file->pMdiChild = NULL;
|
|||
|
//modified = false;
|
|||
|
}
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CChildView::OnNotify(int, LPNMHDR notify){
|
|||
|
SCNotification * notification = (SCNotification *) notify;
|
|||
|
|
|||
|
// Notify Message from Current Editor Control.
|
|||
|
if (notify->hwndFrom == Editor._hWnd){
|
|||
|
switch (notify->code){
|
|||
|
case SCN_UPDATEUI:
|
|||
|
Editor.GetCurrentPos();
|
|||
|
winApp.SendCaretPos(Editor.caretPos);
|
|||
|
break;
|
|||
|
|
|||
|
case SCN_SAVEPOINTREACHED:
|
|||
|
modified = false;
|
|||
|
winApp.Sbar.WriteString("", 1);
|
|||
|
break;
|
|||
|
|
|||
|
case SCN_SAVEPOINTLEFT:
|
|||
|
modified = true;
|
|||
|
winApp.Sbar.WriteString(MSG_MODIFIED, 1);
|
|||
|
break;
|
|||
|
|
|||
|
case SCN_MARGINCLICK:
|
|||
|
if (notification->margin == 2)
|
|||
|
Editor.MarginClick(notification->position, notification->modifiers);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CChildView::OnSetFocus(HWND){
|
|||
|
CFileItem * file = (CFileItem*) GetLong(GWL_USERDATA);
|
|||
|
if (!file)
|
|||
|
return false;
|
|||
|
// Select corresponding TreeView item.
|
|||
|
CTreeView * pTreeView = file->pTreeView;
|
|||
|
|
|||
|
if(!pTreeView)
|
|||
|
return false;
|
|||
|
|
|||
|
pTreeView->SendMessage(TVM_SELECTITEM, (WPARAM)TVGN_CARET, (LPARAM)file->_hItem);
|
|||
|
|
|||
|
// Set Focus on Editor Control.
|
|||
|
Editor.SetFocus();
|
|||
|
|
|||
|
// Display "Modified" message or nothing in the Status Bar.
|
|||
|
winApp.SendCaretPos(Editor.caretPos);
|
|||
|
|
|||
|
if(modified)
|
|||
|
winApp.Sbar.SendMessage(SB_SETTEXT, 1, (LPARAM) MSG_MODIFIED);
|
|||
|
else
|
|||
|
winApp.Sbar.SendMessage(SB_SETTEXT, 1, (LPARAM) "");
|
|||
|
|
|||
|
int selectedTab = winApp.Manager.SendMessage(TCM_GETCURSEL);
|
|||
|
|
|||
|
if (file->isInProject == true && selectedTab != PROJECT_TAB){
|
|||
|
winApp.Manager.SendMessage(TCM_SETCURFOCUS, PROJECT_TAB);
|
|||
|
}else if (file->isInProject == false && selectedTab != FILES_TAB){
|
|||
|
winApp.Manager.SendMessage(TCM_SETCURFOCUS, FILES_TAB);
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CChildView::OnActivate(HWND, HWND hwndChildAct){
|
|||
|
HMENU hMenu;
|
|||
|
HMENU hFileMenu;
|
|||
|
BOOL EnableFlag;
|
|||
|
HWND hwndMain = winApp._hWnd;
|
|||
|
|
|||
|
hMenu = GetMenu(hwndMain);
|
|||
|
|
|||
|
if(_hWnd == hwndChildAct){
|
|||
|
EnableFlag = TRUE; //being activated
|
|||
|
}else{
|
|||
|
EnableFlag = FALSE; //being de-activated
|
|||
|
}
|
|||
|
// Menu items.
|
|||
|
EnableMenuItem(hMenu, 1, MF_BYPOSITION | (EnableFlag ? MF_ENABLED : MF_GRAYED));
|
|||
|
EnableMenuItem(hMenu, 3, MF_BYPOSITION | (EnableFlag ? MF_ENABLED : MF_GRAYED));
|
|||
|
|
|||
|
// Sub-menu items.
|
|||
|
hFileMenu = GetSubMenu(hMenu, 0);
|
|||
|
EnableMenuItem(hFileMenu, IDM_SAVE, MF_BYCOMMAND | (EnableFlag ? MF_ENABLED : MF_GRAYED));
|
|||
|
EnableMenuItem(hFileMenu, IDM_SAVEAS, MF_BYCOMMAND | (EnableFlag ? MF_ENABLED : MF_GRAYED));
|
|||
|
hFileMenu = GetSubMenu(hMenu, 2);
|
|||
|
EnableMenuItem(hFileMenu, IDM_FIND, MF_BYCOMMAND | (EnableFlag ? MF_ENABLED : MF_GRAYED));
|
|||
|
EnableMenuItem(hFileMenu, IDM_REPLACE, MF_BYCOMMAND | (EnableFlag ? MF_ENABLED : MF_GRAYED));
|
|||
|
DrawMenuBar(hwndMain);
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
void CChildView::CmdSave(void){
|
|||
|
CFileItem * file = (CFileItem*) GetLong(GWL_USERDATA);
|
|||
|
|
|||
|
if (!file)
|
|||
|
return;
|
|||
|
/* Untitled file ? */
|
|||
|
if (file->nFileOffset == 0){
|
|||
|
CmdSaveAs();
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (!file->isInProject){
|
|||
|
// A simple file.
|
|||
|
Editor.SaveFile(file->szFileName);
|
|||
|
}else{
|
|||
|
// A project one.
|
|||
|
Project.szDirBuffer[Project.nFileOffset - 1] = '\\';
|
|||
|
strcpy(&Project.szDirBuffer[Project.nFileOffset], file->szFileName);
|
|||
|
Editor.SaveFile(Project.szDirBuffer);
|
|||
|
Project.szDirBuffer[Project.nFileOffset - 1] = '\0';
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void CChildView::CmdSaveAs(void){
|
|||
|
CFileItem * file = (CFileItem*) GetLong(GWL_USERDATA);
|
|||
|
if (!file)
|
|||
|
return;
|
|||
|
|
|||
|
char fileName[MAX_PATH];
|
|||
|
if (!winApp.FileDlg.Save(&winApp, fileName, MAX_PATH, SRC_FILE)) //@@
|
|||
|
return; // canceled by user
|
|||
|
|
|||
|
::SetWindowText(_hWnd, fileName);
|
|||
|
strcpy(file->szFileName, fileName);
|
|||
|
|
|||
|
Editor.SaveFile(file->szFileName);
|
|||
|
//@@ TODO we need to check for errors
|
|||
|
}
|
|||
|
|
|||
|
BOOL CChildView::OnCommand(WPARAM wParam, LPARAM){
|
|||
|
CFileItem * file = (CFileItem*) GetLong(GWL_USERDATA);
|
|||
|
|
|||
|
if(!file)
|
|||
|
return false;
|
|||
|
|
|||
|
switch (LOWORD(wParam)){
|
|||
|
case IDM_SAVE:
|
|||
|
CmdSave();
|
|||
|
break;
|
|||
|
|
|||
|
case IDM_SAVEAS:
|
|||
|
CmdSaveAs();
|
|||
|
break;
|
|||
|
|
|||
|
case IDM_SAVEALL:
|
|||
|
winApp.Manager.SaveAll(IDYES); // Silent.
|
|||
|
break;
|
|||
|
|
|||
|
/* case IDM_CLOSE:
|
|||
|
PostMessage(pWnd, WM_CLOSE, 0, 0);
|
|||
|
break;
|
|||
|
*/
|
|||
|
// To Scintilla control.
|
|||
|
case IDM_FIND:
|
|||
|
EditorDlg.Find(&Editor);
|
|||
|
break;
|
|||
|
|
|||
|
case IDM_REPLACE:
|
|||
|
EditorDlg.Replace(&Editor);
|
|||
|
break;
|
|||
|
|
|||
|
case IDM_CUT:
|
|||
|
Editor.SendMessage(SCI_CUT);
|
|||
|
break;
|
|||
|
case IDM_COPY:
|
|||
|
Editor.SendMessage(SCI_COPY);
|
|||
|
break;
|
|||
|
case IDM_PASTE:
|
|||
|
Editor.SendMessage(SCI_PASTE);
|
|||
|
break;
|
|||
|
case IDM_UNDO:
|
|||
|
Editor.SendMessage(SCI_UNDO);
|
|||
|
break;
|
|||
|
case IDM_REDO:
|
|||
|
Editor.SendMessage(SCI_REDO);
|
|||
|
break;
|
|||
|
case IDM_SELECTALL:
|
|||
|
Editor.SendMessage(SCI_SELECTALL);
|
|||
|
break;
|
|||
|
}
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/********************************************************************
|
|||
|
* Class: CManager.
|
|||
|
*
|
|||
|
* Purpose:
|
|||
|
*
|
|||
|
* Revisions:
|
|||
|
*
|
|||
|
********************************************************************/
|
|||
|
CManager::CManager(){
|
|||
|
}
|
|||
|
|
|||
|
CManager::~CManager(){
|
|||
|
}
|
|||
|
|
|||
|
void CManager::OpenFileDialog(void){
|
|||
|
CFileItem * file = new CFileItem;
|
|||
|
|
|||
|
/* Show the "Open file" dialog */
|
|||
|
winApp.FileDlg.Reset();
|
|||
|
winApp.FileDlg.SetInitialDir(winApp.openFilesDir);
|
|||
|
|
|||
|
if(!winApp.FileDlg.Open(&winApp, file->szFileName, MAX_PATH, SRC_FILE)){
|
|||
|
delete file;
|
|||
|
return; // canceled by user
|
|||
|
}
|
|||
|
|
|||
|
/* Get file information */
|
|||
|
file->nFileExtension = winApp.FileDlg.GetFileExtension();
|
|||
|
file->nFileOffset = winApp.FileDlg.GetFileOffset();
|
|||
|
GetFileType(file);
|
|||
|
// Copy file directory.
|
|||
|
strncpy(winApp.openFilesDir, file->szFileName, (file->nFileOffset - 1));
|
|||
|
winApp.openFilesDir[file->nFileOffset-1] = '\0';
|
|||
|
|
|||
|
/* Load the file */
|
|||
|
if(!OpenFile(file)){
|
|||
|
delete file;
|
|||
|
MsgBox.DisplayString("This file is already opened.");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
bool CManager::OpenFile(CFileItem * file){
|
|||
|
if (!file)
|
|||
|
return false;
|
|||
|
|
|||
|
if (!file->isInProject){
|
|||
|
if (!FilesView.OpenFile(file))
|
|||
|
return false;
|
|||
|
}else{
|
|||
|
if (!ProjectView.OpenFile(file))
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool CManager::NewProjectDialog(void){
|
|||
|
if(IDYES == Project.CloseDecision())
|
|||
|
CloseProject();
|
|||
|
|
|||
|
char fileName[MAX_PATH];
|
|||
|
WORD fileOffset;
|
|||
|
*fileName = '\0';
|
|||
|
|
|||
|
|
|||
|
if (!winApp.FileDlg.Save(&winApp, fileName, MAX_PATH, PRJ_FILE)){
|
|||
|
return false; // canceled by user
|
|||
|
}
|
|||
|
// Copy prj file's directory.
|
|||
|
fileOffset = winApp.FileDlg.GetFileOffset();
|
|||
|
|
|||
|
ProjectView.CreateRoot("Project");
|
|||
|
if (!Project.New(fileName, fileOffset)){
|
|||
|
ProjectView.DestroyRoot();
|
|||
|
ProjectView.DestroyList();
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool CManager::OpenProjectDialog(void){
|
|||
|
if(IDYES == Project.CloseDecision())
|
|||
|
CloseProject();
|
|||
|
|
|||
|
char fileName[MAX_PATH];
|
|||
|
WORD offset;
|
|||
|
*fileName = '\0';
|
|||
|
|
|||
|
// Load default values.
|
|||
|
winApp.FileDlg.Reset();
|
|||
|
winApp.FileDlg.SetInitialDir(winApp.projectDir);
|
|||
|
|
|||
|
if (!winApp.FileDlg.Open(&winApp, fileName, MAX_PATH, PRJ_FILE)){
|
|||
|
return false; // canceled by user
|
|||
|
}
|
|||
|
// Copy project file's directory.
|
|||
|
offset = winApp.FileDlg.GetFileOffset();
|
|||
|
|
|||
|
// Initialize project tree view.
|
|||
|
ProjectView.CreateRoot(fileName+offset);
|
|||
|
|
|||
|
if (!Project.Open(fileName, offset)){
|
|||
|
ProjectView.DestroyRoot();
|
|||
|
ProjectView.DestroyList();
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool CManager::CloseProject(void){
|
|||
|
return ProjectView.Close();
|
|||
|
}
|
|||
|
|
|||
|
void CManager::RemoveProjectFile(void){
|
|||
|
ProjectView.RemoveFile();
|
|||
|
}
|
|||
|
|
|||
|
void CManager::RemoveProjectModule(void){
|
|||
|
ProjectView.RemoveModule();
|
|||
|
}
|
|||
|
|
|||
|
int CManager::SaveProjectFiles(int decision){
|
|||
|
return ProjectView.SaveAll(decision);
|
|||
|
}
|
|||
|
|
|||
|
int CManager::SaveAll(int decision){
|
|||
|
/* Save open files ? */
|
|||
|
decision = FilesView.SaveAll(decision);
|
|||
|
/* Save project files ? */
|
|||
|
decision = ProjectView.SaveAll(decision);
|
|||
|
return decision;
|
|||
|
}
|
|||
|
|
|||
|
void CManager::CreateImageList(void){
|
|||
|
// Create an empty image list.
|
|||
|
ImgList.Create(16, 16, ILC_COLORDDB|ILC_MASK, 8, 1);
|
|||
|
|
|||
|
// Load treeview bmp and add it to the image list.
|
|||
|
CBitmap tvBitmap;
|
|||
|
tvBitmap.Load(this, IDB_TREEVIEW);
|
|||
|
ImgList.AddMasked(&tvBitmap, RGB(255,0,255));
|
|||
|
|
|||
|
// We no longer need treeview bmp.
|
|||
|
tvBitmap.Destroy();
|
|||
|
}
|
|||
|
|
|||
|
void CManager::Create(CWindow * pParent){
|
|||
|
// Create the Tab Control.
|
|||
|
CreateEx(
|
|||
|
pParent,
|
|||
|
WS_EX_CLIENTEDGE,
|
|||
|
WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
|
|||
|
| TCS_BOTTOM | TCS_FOCUSNEVER);
|
|||
|
|
|||
|
// Give it the default font, create tabs, select first one and show the control.
|
|||
|
SendMessage(WM_SETFONT, (long) GetStockObject(DEFAULT_GUI_FONT), 0);
|
|||
|
|
|||
|
InsertItem(FILES_TAB, TCIF_TEXT, 0, 0, "Files", 16, 0, 0);
|
|||
|
InsertItem(PROJECT_TAB, TCIF_TEXT, 0, 0, "Project", 16, 0, 0);
|
|||
|
Show();
|
|||
|
|
|||
|
// Create an Image list and then the Project TreeView.
|
|||
|
CreateImageList();
|
|||
|
ProjectView.Create(this, &ImgList);
|
|||
|
SetItem_Param(PROJECT_TAB, (long) &ProjectView);
|
|||
|
FilesView.Create(this, &ImgList);
|
|||
|
SetItem_Param(FILES_TAB, (long) &FilesView);
|
|||
|
}
|
|||
|
|
|||
|
bool CManager::SetPosition(HWND, int x, int y, int width, int height, UINT){
|
|||
|
/* Overwrites CTabCtrl::SetPosition() so that all child windows are also resized */
|
|||
|
|
|||
|
// Tab Control.
|
|||
|
::SetWindowPos(_hWnd, 0,
|
|||
|
x,
|
|||
|
y,
|
|||
|
width,
|
|||
|
height,
|
|||
|
0);
|
|||
|
// Child windows.
|
|||
|
RECT Rect;
|
|||
|
::GetClientRect(_hWnd, &Rect);
|
|||
|
ProjectView.SetPosition(0, Rect.top +5, Rect.left +5,
|
|||
|
Rect.right-10, Rect.bottom-30, 0);
|
|||
|
|
|||
|
FilesView.SetPosition(0, Rect.top +5, Rect.left +5,
|
|||
|
Rect.right-10, Rect.bottom-30, 0);
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CManager::OnNotify(int, LPNMHDR notify){
|
|||
|
// Dispatch messages.
|
|||
|
switch (notify->code){
|
|||
|
// Tab Control.
|
|||
|
case TCN_SELCHANGING:
|
|||
|
OnSelChanging(notify);
|
|||
|
break;
|
|||
|
|
|||
|
case TCN_SELCHANGE:
|
|||
|
OnSelChange(notify);
|
|||
|
break;
|
|||
|
|
|||
|
// TreeView.
|
|||
|
case TVN_SELCHANGED:
|
|||
|
Tv_OnSelchanged((LPNMTREEVIEW) notify);
|
|||
|
break;
|
|||
|
}
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
void CManager::OnSelChanging(LPNMHDR notify){
|
|||
|
if (_hWnd == notify->hwndFrom){
|
|||
|
CTreeView * pTreeView = (CTreeView *) GetItem_Param(GetCurSel());
|
|||
|
if (pTreeView){
|
|||
|
pTreeView->Hide();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void CManager::OnSelChange(LPNMHDR notify){
|
|||
|
if (_hWnd == notify->hwndFrom){
|
|||
|
CTreeView * pTreeView = (CTreeView *) GetItem_Param(GetCurSel());
|
|||
|
if (pTreeView){
|
|||
|
pTreeView->Show();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void CManager::Tv_OnSelchanged(LPNMTREEVIEW notify){
|
|||
|
// Get lParam of current tree item.
|
|||
|
CFileItem * file = (CFileItem *) notify->itemNew.lParam;
|
|||
|
|
|||
|
if (file){
|
|||
|
CChildView * pMdiChild = (CChildView *) file->pMdiChild;
|
|||
|
|
|||
|
if(pMdiChild){
|
|||
|
// An editor, focus it.
|
|||
|
::SetFocus((HWND) pMdiChild->_hWnd);
|
|||
|
}else{
|
|||
|
// No editor, the item is part of a project.
|
|||
|
Project.SwitchCurrentDir();
|
|||
|
winApp.CreateChild(file->szFileName, file);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/********************************************************************
|
|||
|
* Class: CFilesView.
|
|||
|
*
|
|||
|
* Purpose: Open files TreeView.
|
|||
|
*
|
|||
|
* Revisions:
|
|||
|
*
|
|||
|
********************************************************************/
|
|||
|
CFilesView::CFilesView(){
|
|||
|
hRoot = NULL;
|
|||
|
}
|
|||
|
|
|||
|
CFilesView::~CFilesView(){
|
|||
|
}
|
|||
|
|
|||
|
void CFilesView::New(void){
|
|||
|
CFileItem * file = new CFileItem;
|
|||
|
if(!winApp.Manager.OpenFile(file)){
|
|||
|
delete file;
|
|||
|
MsgBox.DisplayString("Untitled file already exist.");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
bool CFilesView::OpenFile(CFileItem * file){
|
|||
|
if (!file)
|
|||
|
return false;
|
|||
|
|
|||
|
int listAction;
|
|||
|
char * fileName = file->szFileName + file->nFileOffset;
|
|||
|
|
|||
|
/* Untitled file ? */
|
|||
|
if (file->nFileOffset == 0){
|
|||
|
//@@TODO add a counter to get Untitled01, 02, etc...
|
|||
|
strcpy(file->szFileName, "Untitled");
|
|||
|
}
|
|||
|
|
|||
|
/* Check if this file is already opened */
|
|||
|
listAction = InsertSorted_New(file);
|
|||
|
|
|||
|
if (listAction == FILE_FOUND){
|
|||
|
/* Focus the editor window */
|
|||
|
CFileItem * currentFile = (CFileItem *) GetCurrent();
|
|||
|
if (currentFile){
|
|||
|
CMDIChild * pMdiChild = currentFile->pMdiChild;
|
|||
|
if (pMdiChild)
|
|||
|
pMdiChild->SetFocus();
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
/* Create the editor window */
|
|||
|
if (!winApp.CreateChild(file->szFileName, file)){
|
|||
|
MsgBox.DisplayFatal("Can't create child window");
|
|||
|
return false;
|
|||
|
}
|
|||
|
// Note: A WM_SETFOCUS message will be send to the child window.
|
|||
|
|
|||
|
/* Append the file to the list */
|
|||
|
InsertLast(file);
|
|||
|
|
|||
|
/* Create a Tree View item */
|
|||
|
file->_hItem = CreateItem(
|
|||
|
hRoot, //@@ use a GetRootItem() ?
|
|||
|
TVI_LAST,
|
|||
|
file->type,
|
|||
|
fileName,
|
|||
|
(LPARAM) file);
|
|||
|
|
|||
|
file->pTreeView = this;
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
void CFilesView::CloseFile(CFileItem * file){
|
|||
|
SendMessage(TVM_DELETEITEM, 0, (LPARAM) file->_hItem);
|
|||
|
Destroy(file);
|
|||
|
}
|
|||
|
|
|||
|
int CFilesView::SaveAll(int decision){
|
|||
|
if (decision == IDNO || decision == IDCANCEL)
|
|||
|
return decision;
|
|||
|
CFileItem * file = (CFileItem*) First();
|
|||
|
while (file){
|
|||
|
if (file->pMdiChild){
|
|||
|
CChildView * childView = (CChildView *) file->pMdiChild;
|
|||
|
/* Modified ? */
|
|||
|
if (childView->modified){
|
|||
|
/* Ask ? */
|
|||
|
if (decision == IDASK){
|
|||
|
decision = MsgBox.AskToSave(true); // Cancel button.
|
|||
|
if (decision != IDYES)
|
|||
|
return decision; // IDNO or IDCANCEL.
|
|||
|
}
|
|||
|
childView->CmdSave();
|
|||
|
}
|
|||
|
}
|
|||
|
file = (CFileItem*) Next();
|
|||
|
}
|
|||
|
return decision;
|
|||
|
}
|
|||
|
|
|||
|
HWND CFilesView::Create(CWindow * pParent, CImageList * imgList){
|
|||
|
// Create TreeView.
|
|||
|
CreateEx(
|
|||
|
pParent,
|
|||
|
WS_EX_CLIENTEDGE,
|
|||
|
WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
|
|||
|
| TVS_EDITLABELS | TVS_HASLINES | TVS_HASBUTTONS,
|
|||
|
0,
|
|||
|
(void*) 12);
|
|||
|
|
|||
|
// Assign the image list to the treeview control.
|
|||
|
SendMessage(TVM_SETIMAGELIST, (long)TVSIL_NORMAL, (long) imgList->GetId());
|
|||
|
hRoot = CreateItem(TVI_ROOT, TVI_LAST, WORKSPACE, "Workspace", 0);
|
|||
|
return _hWnd;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/********************************************************************
|
|||
|
* Class: CProjectView.
|
|||
|
*
|
|||
|
* Purpose: Project TreeView.
|
|||
|
*
|
|||
|
* Revisions:
|
|||
|
*
|
|||
|
********************************************************************/
|
|||
|
CProjectView::CProjectView(){
|
|||
|
hRoot = NULL;
|
|||
|
}
|
|||
|
|
|||
|
CProjectView::~CProjectView(){
|
|||
|
}
|
|||
|
|
|||
|
CFileItem * CProjectView::NewFile(char * name){
|
|||
|
CFileItem * current = (CFileItem *) GetCurrent();
|
|||
|
CFileItem * srcFile = new CFileItem;
|
|||
|
|
|||
|
// Copy directory name.
|
|||
|
if (current){
|
|||
|
strncpy(srcFile->szFileName, current->szFileName, current->nFileOffset);
|
|||
|
srcFile->nFileOffset = current->nFileOffset;
|
|||
|
}else{
|
|||
|
// No files in the project yet, use makefile directory.
|
|||
|
strcpy(srcFile->szFileName, Project.Makefile.mkfDir);
|
|||
|
srcFile->nFileOffset = strlen(srcFile->szFileName)+1;
|
|||
|
}
|
|||
|
|
|||
|
srcFile->szFileName[srcFile->nFileOffset - 1] = '\\';
|
|||
|
|
|||
|
// Append file name.
|
|||
|
strcpy(&srcFile->szFileName[srcFile->nFileOffset], name);
|
|||
|
//MsgBox.DisplayString(srcFile->szFileName);
|
|||
|
|
|||
|
if (::CheckFile(srcFile)){
|
|||
|
::GetFileType(srcFile);
|
|||
|
srcFile->isInProject = true;
|
|||
|
HANDLE hFile;
|
|||
|
hFile = ::CreateFile(srcFile->szFileName,
|
|||
|
0,
|
|||
|
0,
|
|||
|
NULL,
|
|||
|
CREATE_NEW,
|
|||
|
FILE_ATTRIBUTE_ARCHIVE,
|
|||
|
NULL);
|
|||
|
|
|||
|
if (hFile != INVALID_HANDLE_VALUE){
|
|||
|
CloseHandle(hFile);
|
|||
|
// Try to add new file to the project.
|
|||
|
if(OpenFile(srcFile)){
|
|||
|
Project.modified = true;
|
|||
|
return srcFile;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
delete srcFile;
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
bool CProjectView::OpenFile(CFileItem * file){
|
|||
|
if (!file)
|
|||
|
return false;
|
|||
|
|
|||
|
int listAction;
|
|||
|
char * fileName = file->szFileName + file->nFileOffset;
|
|||
|
|
|||
|
/* Check if this file is already opened */
|
|||
|
listAction = InsertSorted_New(file);
|
|||
|
|
|||
|
if (listAction == FILE_FOUND){
|
|||
|
/* Focus the editor window */
|
|||
|
CFileItem * currentFile = (CFileItem *) GetCurrent();
|
|||
|
if (currentFile){
|
|||
|
CMDIChild * pMdiChild = currentFile->pMdiChild;
|
|||
|
if (!pMdiChild){
|
|||
|
/* Create a child window */
|
|||
|
Project.SwitchCurrentDir();
|
|||
|
winApp.CreateChild(file->szFileName, file);
|
|||
|
}else{
|
|||
|
pMdiChild->SetFocus();
|
|||
|
}
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
file->_hDirItem = hRoot;
|
|||
|
CreateSubDirItem(file);
|
|||
|
|
|||
|
if (listAction == EMPTY_LIST){
|
|||
|
InsertFirst(file);
|
|||
|
}else if (listAction == INSERT_FIRST){
|
|||
|
InsertFirst(file);
|
|||
|
}else if (listAction == INSERT_LAST){
|
|||
|
InsertLast(file);
|
|||
|
}else if (listAction == INSERT_BEFORE){
|
|||
|
InsertBefore(file);
|
|||
|
}else if (listAction == INSERT_AFTER){
|
|||
|
InsertAfter(file);
|
|||
|
}
|
|||
|
|
|||
|
/* Create the file icon */
|
|||
|
file->_hItem = CreateItem(
|
|||
|
file->_hDirItem,
|
|||
|
TVI_SORT,
|
|||
|
file->type,
|
|||
|
fileName,
|
|||
|
(LPARAM) file);
|
|||
|
|
|||
|
file->pTreeView = this;
|
|||
|
|
|||
|
/* Create an editor view */
|
|||
|
if (file->show){
|
|||
|
winApp.CreateChild(file->szFileName, file);
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool CProjectView::Close(){
|
|||
|
if (Project.NoProject())
|
|||
|
return false;
|
|||
|
|
|||
|
int decision = IDASK;
|
|||
|
decision = SaveAll(decision);
|
|||
|
if (decision == IDCANCEL)
|
|||
|
return false;
|
|||
|
|
|||
|
// Parse the list while there's a next node.
|
|||
|
CFileItem * srcFile = (CFileItem *) First();
|
|||
|
while(srcFile){
|
|||
|
DestroyFile(srcFile, decision);
|
|||
|
srcFile = (CFileItem *) Next();
|
|||
|
}
|
|||
|
Project.loaded = false;
|
|||
|
|
|||
|
DestroyRoot();
|
|||
|
DestroyList();
|
|||
|
winApp.Report.Clear();
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
void CProjectView::RemoveFile(void){
|
|||
|
if (Project.NoProject())
|
|||
|
return;
|
|||
|
|
|||
|
CFileItem * srcFile = (CFileItem *) GetSelectedItemParam();
|
|||
|
|
|||
|
if (srcFile){
|
|||
|
if (srcFile->pMdiChild)
|
|||
|
DestroyFile(srcFile);
|
|||
|
TreeView_DeleteItem(_hWnd, srcFile->_hItem);
|
|||
|
if (!TreeView_GetChild(_hWnd, srcFile->_hDirItem))
|
|||
|
TreeView_DeleteItem(_hWnd, srcFile->_hDirItem);
|
|||
|
/* else
|
|||
|
TreeView_SelectItem(_hWnd, srcFile->_hDirItem);*/
|
|||
|
Destroy(srcFile);
|
|||
|
|
|||
|
// we need to save prj file before exit.
|
|||
|
//@@ Project.CloseFile, modified & buildMakefile should be private.
|
|||
|
Project.modified = true;
|
|||
|
Project.buildMakefile = true;
|
|||
|
}else{
|
|||
|
MsgBox.DisplayWarning("No project file selected");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void CProjectView::RemoveModule(void){
|
|||
|
if (Project.NoProject())
|
|||
|
return;
|
|||
|
|
|||
|
CFileItem * srcFile = (CFileItem *) GetSelectedItemParam();
|
|||
|
CFileItem * otherFile;
|
|||
|
|
|||
|
if (srcFile){
|
|||
|
if (srcFile->prev){
|
|||
|
otherFile = (CFileItem *) srcFile->prev;
|
|||
|
if (otherFile->nFileExtension != 0){
|
|||
|
if (0 == strnicmp(srcFile->szFileName, otherFile->szFileName, otherFile->nFileExtension)){
|
|||
|
if (otherFile->pMdiChild)
|
|||
|
DestroyFile(otherFile);
|
|||
|
TreeView_DeleteItem(_hWnd, otherFile->_hItem);
|
|||
|
Destroy(otherFile);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if (srcFile->next){
|
|||
|
otherFile = (CFileItem *) srcFile->next;
|
|||
|
if (otherFile->nFileExtension != 0){
|
|||
|
if (0 == strnicmp(srcFile->szFileName, otherFile->szFileName, otherFile->nFileExtension)){
|
|||
|
if (otherFile->pMdiChild)
|
|||
|
DestroyFile(otherFile);
|
|||
|
TreeView_DeleteItem(_hWnd, otherFile->_hItem);
|
|||
|
Destroy(otherFile);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if (srcFile->pMdiChild)
|
|||
|
DestroyFile(srcFile);
|
|||
|
TreeView_DeleteItem(_hWnd, srcFile->_hItem);
|
|||
|
Destroy(srcFile);
|
|||
|
|
|||
|
// we need to save prj file before exit.
|
|||
|
//@@ Project.CloseFile, modified & buildMakefile should be private.
|
|||
|
Project.modified = true;
|
|||
|
Project.buildMakefile = true;
|
|||
|
}else{
|
|||
|
MsgBox.DisplayWarning("No project file selected");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
int CProjectView::DestroyFile(CFileItem * file, int decision){
|
|||
|
if (file && file->pMdiChild){
|
|||
|
CChildView * pMdiChild = (CChildView *) file->pMdiChild;
|
|||
|
|
|||
|
if (pMdiChild->modified && decision != IDNO){
|
|||
|
// Ask ?
|
|||
|
if (decision == IDASK){
|
|||
|
decision = MsgBox.AskToSave(true); // (Cancel button)
|
|||
|
if (decision == IDCANCEL)
|
|||
|
return decision;
|
|||
|
}
|
|||
|
pMdiChild->CmdSave();
|
|||
|
}
|
|||
|
|
|||
|
if (pMdiChild->_hWnd) // have an editor window, so destroy it.
|
|||
|
winApp.MdiClient.SendMessage(WM_MDIDESTROY, (WPARAM)pMdiChild->_hWnd, 0);
|
|||
|
}
|
|||
|
return decision;
|
|||
|
}
|
|||
|
|
|||
|
int CProjectView::SaveAll(int decision){
|
|||
|
if (!Project.loaded)
|
|||
|
return 0;
|
|||
|
|
|||
|
if (decision == IDNO || decision == IDCANCEL)
|
|||
|
return decision;
|
|||
|
|
|||
|
CFileItem * file = (CFileItem*) First();
|
|||
|
while (file){
|
|||
|
if (file->pMdiChild){
|
|||
|
CChildView * childView = (CChildView *) file->pMdiChild;
|
|||
|
/* Modified ? */
|
|||
|
if (childView->modified){
|
|||
|
/* Ask ? */
|
|||
|
if (decision == IDASK){
|
|||
|
decision = MsgBox.AskToSave(true); // Cancel button.
|
|||
|
if (decision != IDYES)
|
|||
|
return decision; // IDNO or IDCANCEL.
|
|||
|
}
|
|||
|
childView->CmdSave();
|
|||
|
}
|
|||
|
}
|
|||
|
file = (CFileItem*) Next();
|
|||
|
}
|
|||
|
|
|||
|
if (Project.modified)
|
|||
|
return Project.SavePrjFile(decision);
|
|||
|
return decision;
|
|||
|
}
|
|||
|
|
|||
|
bool CProjectView::CreateSubDirItem(CFileItem * file){
|
|||
|
/* Initialize _hDirItem and get a pointer to current file */
|
|||
|
file->_hDirItem = hRoot;
|
|||
|
CFileItem * currentFile = (CFileItem *) GetCurrent();
|
|||
|
|
|||
|
/* See if our new file is in the same directory than current file */
|
|||
|
if (currentFile){
|
|||
|
// There's some files in the list.
|
|||
|
if (file->nFileOffset == currentFile->nFileOffset){
|
|||
|
// Same directory length, we may have found the directory.
|
|||
|
if (0 == strnicmp(file->szFileName, currentFile->szFileName, currentFile->nFileOffset)){
|
|||
|
/* We have found the directory, then copy _hDirItem */
|
|||
|
file->_hDirItem = currentFile->_hDirItem;
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* We need to parse the tree view and create directory icons */
|
|||
|
char * parse = file->szFileName;
|
|||
|
if (*parse == '.' && *(parse+1) == '\\'){
|
|||
|
/* This is a valid relative path */
|
|||
|
char dir[MAX_PATH];
|
|||
|
strcpy(dir, file->szFileName);
|
|||
|
parse = dir+2;
|
|||
|
char * dirStart;
|
|||
|
HTREEITEM hParent = hRoot;
|
|||
|
HTREEITEM hFound;
|
|||
|
if (*parse){
|
|||
|
for ( ; ; ){
|
|||
|
/* Found each backslash */
|
|||
|
dirStart = parse;
|
|||
|
parse = strchr(parse, '\\');
|
|||
|
if (!parse)
|
|||
|
break; // No more backslash.
|
|||
|
else if (parse == dirStart)
|
|||
|
return false; // Avoids an endless loop.
|
|||
|
*parse = '\0';
|
|||
|
|
|||
|
/* Find the directory */
|
|||
|
hFound = FindDirItem(hParent, dirStart);
|
|||
|
if (!hFound){
|
|||
|
/* Append a new directory icon */
|
|||
|
hParent = CreateDirItem(hParent, dirStart);
|
|||
|
}
|
|||
|
parse++;
|
|||
|
}
|
|||
|
}
|
|||
|
file->_hDirItem = hParent;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
HTREEITEM CProjectView::FindDirItem(HTREEITEM hItem, char * dir){
|
|||
|
char buffer[_MAX_DIR];
|
|||
|
HTREEITEM hNext = TreeView_GetChild(_hWnd, hItem);
|
|||
|
while (hNext){
|
|||
|
_TvItem.hItem = hNext;
|
|||
|
_TvItem.mask = TVIF_HANDLE | TVIF_TEXT;
|
|||
|
_TvItem.pszText = buffer;
|
|||
|
_TvItem.cchTextMax = _MAX_DIR;
|
|||
|
if (TreeView_GetItem(_hWnd, &_TvItem)){
|
|||
|
if (!stricmp(dir, buffer))
|
|||
|
return hNext;
|
|||
|
}
|
|||
|
hNext = TreeView_GetNextSibling(_hWnd, hNext);
|
|||
|
}
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
HWND CProjectView::Create(CWindow * pParent, CImageList * imgList){
|
|||
|
// Create TreeView.
|
|||
|
CreateEx(
|
|||
|
pParent,
|
|||
|
WS_EX_CLIENTEDGE,
|
|||
|
WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
|
|||
|
| TVS_EDITLABELS | TVS_HASLINES | TVS_HASBUTTONS);
|
|||
|
|
|||
|
// Assign the image list to the treeview control.
|
|||
|
SendMessage(TVM_SETIMAGELIST, (long)TVSIL_NORMAL, (long) imgList->GetId());
|
|||
|
return _hWnd;
|
|||
|
}
|
|||
|
|
|||
|
void CProjectView::CreateRoot(char * projectName){
|
|||
|
|
|||
|
_pParent->SendMessage(TCM_SETCURFOCUS, 1, 0);
|
|||
|
|
|||
|
// Create Root Item.
|
|||
|
hRoot = CreateItem(TVI_ROOT, TVI_LAST, PROJECT, projectName, 0);
|
|||
|
SendMessage(TVM_EXPAND, (long) TVE_EXPAND, (long) hRoot);
|
|||
|
}
|
|||
|
|
|||
|
void CProjectView::DestroyRoot(void){
|
|||
|
TreeView_DeleteItem(_hWnd, hRoot);
|
|||
|
hRoot = 0;
|
|||
|
|
|||
|
_pParent->SendMessage(TCM_SETCURFOCUS, 0, 0);
|
|||
|
}
|
|||
|
|
|||
|
HTREEITEM CProjectView::CreateDirItem(HTREEITEM hParent, char * dir){
|
|||
|
return CreateItem(hParent, TVI_SORT, DIR, dir, 0);
|
|||
|
}
|
|||
|
|
|||
|
CFileItem * CProjectView::FindFile(char * szFileName){
|
|||
|
if (!szFileName || !*szFileName)
|
|||
|
return NULL;
|
|||
|
|
|||
|
char * currentFile;
|
|||
|
bool stripDir = true;
|
|||
|
if (*szFileName == '.')
|
|||
|
stripDir = false;
|
|||
|
// Get the current node.
|
|||
|
CFileItem * currentNode = (CFileItem *) GetCurrent();
|
|||
|
|
|||
|
if(!currentNode)
|
|||
|
return NULL; // The list is empty.
|
|||
|
|
|||
|
currentFile = GetFileName(currentNode, stripDir);
|
|||
|
int cmpResult = stricmp(szFileName, currentFile);
|
|||
|
// Compare names to know if we must parse Up
|
|||
|
// or Down from current node.
|
|||
|
if (cmpResult == 0){
|
|||
|
return currentNode; // Found !
|
|||
|
}
|
|||
|
// Search Up -----------------------------------------------------------------
|
|||
|
else if (cmpResult == -1){
|
|||
|
// Parse the list while there's a previous node.
|
|||
|
while (Prev()){
|
|||
|
currentNode = (CFileItem *) GetCurrent();
|
|||
|
currentFile = GetFileName(currentNode, stripDir);
|
|||
|
if(!stricmp(szFileName, currentFile))
|
|||
|
return currentNode; // Found !
|
|||
|
}
|
|||
|
}
|
|||
|
// Search Down --------------------------------------------------------------
|
|||
|
else if (cmpResult == 1){
|
|||
|
// Parse the list while there's a next node.
|
|||
|
while (Next()){
|
|||
|
currentNode = (CFileItem *) GetCurrent();
|
|||
|
currentFile = GetFileName(currentNode, stripDir);
|
|||
|
if(!stricmp(szFileName, currentFile))
|
|||
|
return currentNode; // Found !
|
|||
|
}
|
|||
|
}
|
|||
|
return NULL;
|
|||
|
}
|
|||
|
|
|||
|
char * CProjectView::GetFileName(CFileItem * currentNode, bool flag){
|
|||
|
char * fileName = currentNode->szFileName;
|
|||
|
if (flag == true){
|
|||
|
fileName += currentNode->nFileOffset;
|
|||
|
}
|
|||
|
return fileName;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/********************************************************************
|
|||
|
* Class: CReport.
|
|||
|
*
|
|||
|
* Purpose:
|
|||
|
*
|
|||
|
* Revisions:
|
|||
|
*
|
|||
|
********************************************************************/
|
|||
|
CReport::CReport(){
|
|||
|
}
|
|||
|
|
|||
|
CReport::~CReport(){
|
|||
|
}
|
|||
|
|
|||
|
void CReport::Create(CWindow * pParent){
|
|||
|
// Create the Tab Control.
|
|||
|
CreateEx(
|
|||
|
pParent,
|
|||
|
WS_EX_CLIENTEDGE,
|
|||
|
WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
|
|||
|
/*| TCS_BOTTOM*/ | TCS_MULTILINE | TCS_VERTICAL
|
|||
|
| TCS_FOCUSNEVER);
|
|||
|
|
|||
|
// Give it a smart font, create tabs, select first one and show the control.
|
|||
|
SendMessage(WM_SETFONT, (long) GetStockObject(DEFAULT_GUI_FONT), 0);
|
|||
|
|
|||
|
InsertItem(REPORT_MAIN_TAB, TCIF_TEXT, 0, 0, "Main", 16, 0, 0);
|
|||
|
InsertItem(REPORT_LOG_TAB, TCIF_TEXT, 0, 0, "Log", 16, 0, 0);
|
|||
|
Show();
|
|||
|
|
|||
|
// Create an Image list and then the Project TreeView.
|
|||
|
MainList.Create(this);
|
|||
|
SetItem_Param(REPORT_MAIN_TAB, (long) &MainList);
|
|||
|
LogList.Create(this);
|
|||
|
SetItem_Param(REPORT_LOG_TAB, (long) &LogList);
|
|||
|
}
|
|||
|
|
|||
|
bool CReport::SetPosition(HWND, int x, int y, int width, int height, UINT){
|
|||
|
/* Overwrites CTabCtrl::SetPosition() so that all child windows are also resized */
|
|||
|
|
|||
|
// Tab Control.
|
|||
|
::SetWindowPos(_hWnd, 0,
|
|||
|
x,
|
|||
|
y,
|
|||
|
width,
|
|||
|
height,
|
|||
|
0);
|
|||
|
|
|||
|
// Get tab's display area.
|
|||
|
RECT area;
|
|||
|
area.left = 0;
|
|||
|
area.top = 0;
|
|||
|
area.right = width;
|
|||
|
area.bottom = height;
|
|||
|
::SendMessage(_hWnd, TCM_ADJUSTRECT, FALSE, (LPARAM) &area);
|
|||
|
area.right -= area.left;
|
|||
|
area.bottom -= area.top;
|
|||
|
/* WS_EX_CLIENTEDGE correction */
|
|||
|
area.top -= 2;
|
|||
|
area.right -= 2;
|
|||
|
// Borders.
|
|||
|
area.left += 3;
|
|||
|
area.top += 3;
|
|||
|
area.right -= 6;
|
|||
|
area.bottom -= 6;
|
|||
|
|
|||
|
// Child windows.
|
|||
|
MainList.SetPosition(0, area.left, area.top,
|
|||
|
area.right, area.bottom, 0);
|
|||
|
LogList.SetPosition(0, area.left, area.top,
|
|||
|
area.right, area.bottom, 0);
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
BOOL CReport::OnNotify(int, LPNMHDR notify){
|
|||
|
// Dispatch messages.
|
|||
|
switch (notify->code){
|
|||
|
// Tab Control.
|
|||
|
case TCN_SELCHANGING:
|
|||
|
OnSelChanging(notify);
|
|||
|
break;
|
|||
|
|
|||
|
case TCN_SELCHANGE:
|
|||
|
OnSelChange(notify);
|
|||
|
break;
|
|||
|
|
|||
|
// Main list.
|
|||
|
case NM_DBLCLK:
|
|||
|
MainList.Lv_OnDbClick((LPNMLISTVIEW) notify);
|
|||
|
break;
|
|||
|
}
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
void CReport::OnSelChanging(LPNMHDR notify){
|
|||
|
if (_hWnd == notify->hwndFrom){
|
|||
|
CWindow * pWindow = (CWindow *) GetItem_Param(GetCurSel());
|
|||
|
if (pWindow){
|
|||
|
pWindow->Hide();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void CReport::OnSelChange(LPNMHDR notify){
|
|||
|
if (_hWnd == notify->hwndFrom){
|
|||
|
CWindow * pWindow = (CWindow *) GetItem_Param(GetCurSel());
|
|||
|
if (pWindow){
|
|||
|
pWindow->Show();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void CReport::Clear(void){
|
|||
|
MainList.Clear();
|
|||
|
LogList.Clear();
|
|||
|
}
|
|||
|
|
|||
|
bool CReport::Append(char * line, WORD outputFlag){
|
|||
|
LogList.Append(line, outputFlag);
|
|||
|
MainList.Append(line, outputFlag);
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/********************************************************************
|
|||
|
* Class: CMainList.
|
|||
|
*
|
|||
|
* Purpose:
|
|||
|
*
|
|||
|
* Revisions:
|
|||
|
*
|
|||
|
********************************************************************/
|
|||
|
CMainList::CMainList(){
|
|||
|
}
|
|||
|
|
|||
|
CMainList::~CMainList(){
|
|||
|
}
|
|||
|
|
|||
|
void CMainList::Create(CWindow * pParent){
|
|||
|
CreateEx(
|
|||
|
pParent,
|
|||
|
WS_EX_CLIENTEDGE,
|
|||
|
WS_VISIBLE | WS_CHILD| WS_CLIPCHILDREN | WS_CLIPSIBLINGS
|
|||
|
| LVS_REPORT);
|
|||
|
|
|||
|
SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE,
|
|||
|
LVS_EX_GRIDLINES, LVS_EX_GRIDLINES);
|
|||
|
SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE,
|
|||
|
LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
|
|||
|
|
|||
|
// Insert columns.
|
|||
|
LVCOLUMN lvc;
|
|||
|
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
|||
|
lvc.fmt = LVCFMT_LEFT;
|
|||
|
|
|||
|
lvc.iSubItem = 0;
|
|||
|
lvc.cx = 35;
|
|||
|
lvc.pszText = "Line";
|
|||
|
SendMessage(LVM_INSERTCOLUMN, 0, (LPARAM) &lvc);
|
|||
|
|
|||
|
lvc.iSubItem = 1;
|
|||
|
lvc.cx = 70;
|
|||
|
lvc.pszText = "Unit";
|
|||
|
SendMessage(LVM_INSERTCOLUMN, 1, (LPARAM) &lvc);
|
|||
|
|
|||
|
lvc.iSubItem = 2;
|
|||
|
lvc.cx = 640;
|
|||
|
lvc.pszText = "Message";
|
|||
|
SendMessage(LVM_INSERTCOLUMN, 2, (LPARAM) &lvc);
|
|||
|
}
|
|||
|
|
|||
|
void CMainList::Lv_OnDbClick(LPNMLISTVIEW lpnmlv){
|
|||
|
if (_hWnd == lpnmlv->hdr.hwndFrom){
|
|||
|
char lineBuff[256];
|
|||
|
*lineBuff = '\0';
|
|||
|
char * c = lineBuff;
|
|||
|
LV_ITEM lvi;
|
|||
|
lvi.mask = LVIF_TEXT;
|
|||
|
lvi.iItem = lpnmlv->iItem;
|
|||
|
lvi.iSubItem = 0;
|
|||
|
lvi.pszText = lineBuff;
|
|||
|
lvi.cchTextMax = 256;
|
|||
|
lvi.lParam = 0;
|
|||
|
if (!SendMessage(LVM_GETITEMTEXT, lpnmlv->iItem, (long) &lvi))
|
|||
|
return;
|
|||
|
while(*c){
|
|||
|
if (!isdigit(*c))
|
|||
|
return;
|
|||
|
c++;
|
|||
|
}
|
|||
|
int line = atoi(lineBuff);
|
|||
|
|
|||
|
//MsgBox.DisplayLong((long) line);
|
|||
|
|
|||
|
lvi.iSubItem = 1;
|
|||
|
if (!SendMessage(LVM_GETITEMTEXT, lpnmlv->iItem, (long) &lvi))
|
|||
|
return;
|
|||
|
CFileItem * item = winApp.Manager.ProjectView.FindFile(lineBuff);
|
|||
|
if (item && item->isInProject){
|
|||
|
CChildView * pMdiChild = (CChildView *) item->pMdiChild;
|
|||
|
|
|||
|
if(pMdiChild){
|
|||
|
// An editor, focus it.
|
|||
|
::SetFocus((HWND) pMdiChild->_hWnd);
|
|||
|
}else{
|
|||
|
// No editor, the item is part of a project.
|
|||
|
Project.SwitchCurrentDir();
|
|||
|
winApp.CreateChild(item->szFileName, item);
|
|||
|
}
|
|||
|
pMdiChild = (CChildView *) item->pMdiChild;
|
|||
|
if (pMdiChild)
|
|||
|
pMdiChild->Editor.GotoLine(line-1);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
bool CMainList::Append(char * line, WORD outputFlag){
|
|||
|
int row;
|
|||
|
|
|||
|
*szLine = '\0';
|
|||
|
*szUnit = '\0';
|
|||
|
*szMsg = '\0';
|
|||
|
|
|||
|
if (outputFlag == LVOUT_ERROR){
|
|||
|
if (!SplitErrorLine(line))
|
|||
|
return false;
|
|||
|
}else if (outputFlag == LVOUT_NORMAL){
|
|||
|
strcpy (szMsg, line);
|
|||
|
}else{
|
|||
|
strcpy (szMsg, "Unrecognized outputFlag");
|
|||
|
}
|
|||
|
|
|||
|
// Fill in List View columns, first is column 0.
|
|||
|
LV_ITEM lvi;
|
|||
|
lvi.mask = LVIF_TEXT; // | LVIF_PARAM;
|
|||
|
lvi.iItem = 0x7FFF;
|
|||
|
lvi.iSubItem = 0;
|
|||
|
lvi.pszText = szLine;
|
|||
|
lvi.cchTextMax = strlen(lvi.pszText)+1;
|
|||
|
lvi.lParam = 0;
|
|||
|
|
|||
|
row = SendMessage(LVM_INSERTITEM, 0, (LPARAM) &lvi);
|
|||
|
|
|||
|
// Continue with column 1.
|
|||
|
lvi.iSubItem = 1;
|
|||
|
lvi.pszText = szUnit;
|
|||
|
lvi.cchTextMax = strlen(lvi.pszText)+1;
|
|||
|
SendMessage(LVM_SETITEMTEXT, (WPARAM)row, (LPARAM)&lvi);
|
|||
|
|
|||
|
// Continue with column 2.
|
|||
|
lvi.iSubItem = 2;
|
|||
|
lvi.pszText = szMsg;
|
|||
|
lvi.cchTextMax = strlen(lvi.pszText)+1;
|
|||
|
SendMessage(LVM_SETITEMTEXT, (WPARAM)row, (LPARAM)&lvi);
|
|||
|
|
|||
|
// Save last row position
|
|||
|
lastRow = row+1;
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool CMainList::SplitErrorLine(char * line){
|
|||
|
char * chr = line;
|
|||
|
char * col;
|
|||
|
// line => [unit]:[line_n<5F>]: [error message]
|
|||
|
// or => [unit]: [error message]
|
|||
|
|
|||
|
if (!*line)
|
|||
|
return false;
|
|||
|
|
|||
|
/* Unit */
|
|||
|
col = szUnit;
|
|||
|
for ( ; ; ){
|
|||
|
if (!*chr){
|
|||
|
/* Not an error line */
|
|||
|
//strcpy(szMsg, szUnit);
|
|||
|
*szUnit = '\0';
|
|||
|
return false;
|
|||
|
}else if (*chr == ':'){
|
|||
|
if (*(chr+1) == '\\'){
|
|||
|
*col = *chr;
|
|||
|
col++;
|
|||
|
chr++;
|
|||
|
continue;
|
|||
|
}else{
|
|||
|
chr++;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
*col = *chr;
|
|||
|
col++;
|
|||
|
chr++;
|
|||
|
}
|
|||
|
*col = '\0';
|
|||
|
|
|||
|
/* Line number ? */
|
|||
|
col = szLine;
|
|||
|
if (*chr && isdigit(*chr)){ //@@ *chr=0 ?
|
|||
|
while (*chr && *chr != ':'){
|
|||
|
*col = *chr;
|
|||
|
col++;
|
|||
|
chr++;
|
|||
|
}
|
|||
|
*col = '\0';
|
|||
|
chr++;
|
|||
|
}
|
|||
|
|
|||
|
/* Message */
|
|||
|
col = szMsg;
|
|||
|
if (isspace(*chr)){
|
|||
|
/**col = '>';
|
|||
|
col++;
|
|||
|
*col = ' ';
|
|||
|
col++;*/
|
|||
|
chr++;
|
|||
|
}
|
|||
|
|
|||
|
while (*chr){
|
|||
|
*col = *chr;
|
|||
|
col++;
|
|||
|
chr++;
|
|||
|
}
|
|||
|
*col = '\0';
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/********************************************************************
|
|||
|
* Class: CLogList.
|
|||
|
*
|
|||
|
* Purpose:
|
|||
|
*
|
|||
|
* Revisions:
|
|||
|
*
|
|||
|
********************************************************************/
|
|||
|
CLogList::CLogList(){
|
|||
|
}
|
|||
|
|
|||
|
CLogList::~CLogList(){
|
|||
|
}
|
|||
|
|
|||
|
void CLogList::Create(CWindow * pParent){
|
|||
|
CreateEx(
|
|||
|
pParent,
|
|||
|
WS_EX_CLIENTEDGE,
|
|||
|
WS_CHILD| WS_CLIPCHILDREN | WS_CLIPSIBLINGS | LVS_REPORT
|
|||
|
| LVS_NOCOLUMNHEADER);
|
|||
|
|
|||
|
SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE,
|
|||
|
LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
|
|||
|
|
|||
|
// Insert columns.
|
|||
|
LVCOLUMN lvc;
|
|||
|
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
|||
|
lvc.fmt = LVCFMT_LEFT;
|
|||
|
|
|||
|
lvc.iSubItem = 0;
|
|||
|
lvc.cx = 100;
|
|||
|
lvc.pszText = "Message";
|
|||
|
SendMessage(LVM_INSERTCOLUMN, 0, (LPARAM) &lvc);
|
|||
|
}
|
|||
|
|
|||
|
bool CLogList::SetPosition(HWND hInsertAfter, int x, int y, int width, int height, UINT uFlags){
|
|||
|
::SendMessage(_hWnd, WM_SETREDRAW, FALSE, 0);
|
|||
|
::SetWindowPos(_hWnd, hInsertAfter, x, y, width, height, uFlags);
|
|||
|
::SendMessage(_hWnd, LVM_SETCOLUMNWIDTH, 0, MAKELPARAM((int) width-22, 0));
|
|||
|
::SendMessage(_hWnd, WM_SETREDRAW, TRUE, 0);
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool CLogList::Append(char * line, WORD /*outputFlag*/){
|
|||
|
int row;
|
|||
|
|
|||
|
*szMsg = '\0';
|
|||
|
|
|||
|
/* if (outputFlag != LVOUT_ERROR)
|
|||
|
return false;
|
|||
|
*/
|
|||
|
// Fill in List View columns, first is column 0.
|
|||
|
LV_ITEM lvi;
|
|||
|
lvi.mask = LVIF_TEXT; // | LVIF_PARAM;
|
|||
|
lvi.iItem = 0x7FFF;
|
|||
|
lvi.iSubItem = 0;
|
|||
|
lvi.pszText = line;
|
|||
|
lvi.cchTextMax = strlen(lvi.pszText)+1;
|
|||
|
lvi.lParam = 0;
|
|||
|
|
|||
|
row = SendMessage(LVM_INSERTITEM, 0, (LPARAM) &lvi);
|
|||
|
|
|||
|
// Save last row position
|
|||
|
lastRow = row+1;
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/********************************************************************
|
|||
|
* Class: CFileItem.
|
|||
|
*
|
|||
|
* Purpose: Linked List Node for file parameters.
|
|||
|
*
|
|||
|
* Revisions:
|
|||
|
*
|
|||
|
********************************************************************/
|
|||
|
CFileItem::CFileItem(){
|
|||
|
type = U_FILE;
|
|||
|
|
|||
|
*szFileName = '\0';
|
|||
|
szFileName[MAX_PATH - 1] = '\0'; // security.
|
|||
|
nFileOffset = 0;
|
|||
|
nFileExtension = 0;
|
|||
|
|
|||
|
pTreeView = NULL;
|
|||
|
_hDirItem = 0;
|
|||
|
_hItem = 0;
|
|||
|
|
|||
|
pMdiChild = NULL;
|
|||
|
show = 0;
|
|||
|
isInProject = false;
|
|||
|
}
|
|||
|
|
|||
|
CFileItem::~CFileItem(){
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/********************************************************************
|
|||
|
* Class: CFileList.
|
|||
|
*
|
|||
|
* Purpose: A CList with a dedicated Compare() procedure.
|
|||
|
*
|
|||
|
* Revisions:
|
|||
|
*
|
|||
|
********************************************************************/
|
|||
|
CFileList::CFileList(){
|
|||
|
}
|
|||
|
|
|||
|
CFileList::~CFileList(){
|
|||
|
}
|
|||
|
|
|||
|
int CFileList::Compare(CNode *node1, CNode *node2){
|
|||
|
return stricmp(((CFileItem *)node1)->szFileName, ((CFileItem *)node2)->szFileName);
|
|||
|
}
|
|||
|
|