diff --git a/.hgignore b/.hgignore new file mode 100644 index 0000000..e69de29 diff --git a/AboutNaadDlg.cpp b/AboutNaadDlg.cpp new file mode 100644 index 0000000..76ace51 --- /dev/null +++ b/AboutNaadDlg.cpp @@ -0,0 +1,55 @@ +// AboutNaadDlg.cpp : implementation file +// + +#include "stdafx.h" +#include "Naadh.h" +#include "AboutNaadDlg.h" + + +// CAboutNaadDlg dialog + +IMPLEMENT_DYNAMIC(CAboutNaadDlg, CDialog) +CAboutNaadDlg::CAboutNaadDlg(CWnd* pParent /*=NULL*/) + : CDialog(CAboutNaadDlg::IDD, pParent) +{ +} + +CAboutNaadDlg::~CAboutNaadDlg() +{ +} + +void CAboutNaadDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_STATIC_ABT, m_zoomCtrl); +} + + +BEGIN_MESSAGE_MAP(CAboutNaadDlg, CDialog) +END_MESSAGE_MAP() + + +// CAboutNaadDlg message handlers +BOOL CAboutNaadDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + + m_AboutText.Format("%.1f", (float)VERSION/10.0); + m_AboutText = "Naad version " + m_AboutText + ", " + VERMONTH + " \r\n\r\n" + "By\r\nOormi Creations\r\nhttp://oormi.in\r\noormicreations@gmail.com"; + + m_AboutText += "\r\n\r\n\r\n\r\nCredits :\r\n* Multiline List Control\tCopyright(C) 2006 Dave Calkins (coder1024@gmail.com)\r\n"; + m_AboutText += "* UpdateCheck Class\tCopyright(C) 2003 Alexander Bischofberger (www.bluescreen.de)\r\n"; + m_AboutText += "* Image Support\tJim Dill (jim@jimdill.net) and Tobias Eiseler (tobias.eiseler@sisternicky.com)\r\n"; + m_AboutText += "* WaveBox Class\tZenith__"; + m_AboutText += "\r\n\r\nNaad is a freeware and open source software."; + + m_zoomCtrl.m_ImageName = m_AboutText; + m_zoomCtrl.m_About = true; + + if(!m_zoomCtrl.LoadFromFile(m_ImageFileName)) + { + //CDialog::OnCancel(); + } + + return TRUE; // return TRUE unless you set the focus to a control +} diff --git a/AboutNaadDlg.h b/AboutNaadDlg.h new file mode 100644 index 0000000..4a5b831 --- /dev/null +++ b/AboutNaadDlg.h @@ -0,0 +1,25 @@ +#pragma once +#include "zoomctrl.h" + + +// CAboutNaadDlg dialog + +class CAboutNaadDlg : public CDialog +{ + DECLARE_DYNAMIC(CAboutNaadDlg) + +public: + CAboutNaadDlg(CWnd* pParent = NULL); // standard constructor + virtual ~CAboutNaadDlg(); + +// Dialog Data + enum { IDD = IDD_DIALOG_ABT }; + CZoomCtrl m_zoomCtrl; + CString m_ImageFileName, m_AboutText; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + virtual BOOL OnInitDialog(); + + DECLARE_MESSAGE_MAP() +}; diff --git a/Bol.cpp b/Bol.cpp new file mode 100644 index 0000000..9e97737 --- /dev/null +++ b/Bol.cpp @@ -0,0 +1,71 @@ +#include "StdAfx.h" +#include ".\bol.h" + +CBol::CBol(void) +{ + m_BolId = BOL_NONE; + m_Status = BOL_NORMAL; + m_Species = 0; + m_Row = 0; + m_Col = 0; + m_Selected = FALSE; +} + +CBol::~CBol(void) +{ +} + +BOOL CBol::SetBolType(UINT id, UINT col, UINT row) +{ + if(id > BOL_NONE) return FALSE; + + CString bols[MAXBOLVARS*MAXBOLS] = BOLVARS; + + m_BolId = id; + m_Row = row; + m_Col = col; + m_Species = id/MAXBOLVARS; + + if(id == BOL_NONE) m_BolName = ""; + else if(id == BOL_SILENCE) m_BolName = "~ o ~"; + else m_BolName = bols[id]; + + return TRUE; +} + +BOOL CBol::SetBolType(UINT id) +{ + if(id > BOL_NONE) return FALSE; + + CString bols[MAXBOLVARS*MAXBOLS] = BOLVARS; + + m_BolId = id; + m_Species = id/MAXBOLVARS; + + //TRACE("%d\r\n",id); + if(id == BOL_NONE) m_BolName = ""; + else if(id == BOL_SILENCE) m_BolName = "~ o ~"; + else m_BolName = bols[id]; + + return TRUE; +} + + +BOOL CBol::SetBolStatus(UINT status) +{ + m_Status = status; + if(status7) + // { + // col = 0; + // row++; + // } + // } + //} + + + //for(UINT y=4; y m_Loop; +//---------------------------------------------------------------------------------------------------------------- + + BOOL AddLoop(UINT col, UINT row); + BOOL DeleteLoop(UINT nloop); + UINT GetLoop(UINT col, UINT row); + void DoLoopPropDlg(UINT nloop); + void DoCompositionPropDlg(void); + UINT GetRandValue(UINT min, UINT max); + void AutoCompose(void); + void SetBolSelection(UINT nloop, UINT col, UINT row, BOOL sel); + void SetLoopSelection(UINT col, UINT row, BOOL sel); + void DeSelectAll(void); + void Clear(void); +//---------------------------------------------------------------------------------------------------------------- +}; diff --git a/Loop.cpp b/Loop.cpp new file mode 100644 index 0000000..ec8faf5 --- /dev/null +++ b/Loop.cpp @@ -0,0 +1,96 @@ +#include "StdAfx.h" +#include "Naadh.h" +#include ".\loop.h" + +CLoop::CLoop(void) +{ + m_MaatraBol = 1; + m_RepeatCount = 1; //play once by default + m_BolCount = 0; + m_MatraCount = 0; + m_Row = 0; + m_Col = 0; + m_Accompaniment = 0; + m_Selected = FALSE; + //m_Delay = 0; + m_LoopBpm = DEFAULT_BPM; + //m_B2B = TRUE; + m_LoopName = "New Loop"; +} + +CLoop::~CLoop(void) +{ +} + +BOOL CLoop::AddBol(void) +{ + CBol bol; + m_Bol.push_back(bol); + m_BolCount ++; + + m_MatraCount = m_BolCount/m_MaatraBol; + + return TRUE; +} + +UINT CLoop::GetBol(UINT col, UINT row) +{ + for(UINT x=0; x + + +class CLoop +{ +public: + CLoop(void); + ~CLoop(void); +//------------------------------------------------------------------------------------------------------------ + CString m_LoopName, m_Note; + UINT m_MaatraBol, m_RepeatCount;//, m_Delay; //delay is in millisec + UINT m_BolCount, m_LoopBpm; + UINT m_Row, m_Col; + UINT m_Accompaniment; + BOOL m_Selected; + //BOOL m_B2B; //back to back play + std::vector< CBol > m_Bol; + +private: + UINT m_MatraCount; + +//------------------------------------------------------------------------------------------------------------ + +public: + BOOL AddBol(void); + BOOL DeleteBol(UINT nbol); + UINT GetBol(UINT col, UINT row); + CString GetMatraCount(void); + void DeSelectAll(void); + void Clone(CLoop srcloop); + +//------------------------------------------------------------------------------------------------------------ + +}; diff --git a/LoopPropDlg.cpp b/LoopPropDlg.cpp new file mode 100644 index 0000000..562809c --- /dev/null +++ b/LoopPropDlg.cpp @@ -0,0 +1,75 @@ +// LoopPropDlg.cpp : implementation file +// + +#include "stdafx.h" +#include "Naadh.h" +#include "LoopPropDlg.h" + + +// CLoopPropDlg dialog + +IMPLEMENT_DYNAMIC(CLoopPropDlg, CDialog) +CLoopPropDlg::CLoopPropDlg(CWnd* pParent /*=NULL*/) + : CDialog(CLoopPropDlg::IDD, pParent) + , m_Name(_T("")) + , m_Repeat(1) + , m_Bpm(DEFAULT_BPM) +{ +} + +CLoopPropDlg::~CLoopPropDlg() +{ +} + +void CLoopPropDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_COMBO_MATRA, m_ComboMatra); + DDX_Control(pDX, IDC_COMBO_ACC, m_ComboAcc); + DDX_Text(pDX, IDC_EDIT_REPEAT, m_Repeat); + DDX_Text(pDX, IDC_EDIT_LOOPNAME, m_Name); + DDX_Text(pDX, IDC_EDIT_LOOPNOTES, m_Note); + DDX_Text(pDX, IDC_EDIT_DELAY, m_Bpm); + //DDX_Check(pDX, IDC_CHECK_B2B, m_B2B); +} + + +BEGIN_MESSAGE_MAP(CLoopPropDlg, CDialog) + ON_CBN_SELCHANGE(IDC_COMBO_MATRA, OnCbnSelchangeComboMatra) + ON_CBN_SELCHANGE(IDC_COMBO_ACC, OnCbnSelchangeComboAcc) + ON_BN_CLICKED(IDC_CHECK_B2B, OnBnClickedCheckB2b) +END_MESSAGE_MAP() + + +// CLoopPropDlg message handlers +BOOL CLoopPropDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + + this->SetDlgItemTextA(IDC_EDIT_MAATRAS, m_MatraCountStr); + m_ComboMatra.SetCurSel(m_Matra-1); + m_ComboAcc.SetCurSel(m_Acc); + CButton * chk = (CButton*)this->GetDlgItem(IDC_CHECK_B2B); + //chk->SetCheck(m_B2B); + //OnBnClickedCheckB2b(); + return TRUE; +} +void CLoopPropDlg::OnCbnSelchangeComboMatra() +{ + m_Matra = m_ComboMatra.GetCurSel() + 1; +} + +void CLoopPropDlg::OnCbnSelchangeComboAcc() +{ + m_Acc = m_ComboAcc.GetCurSel(); +} + +void CLoopPropDlg::OnOK() +{ + CDialog::OnOK(); +} + +void CLoopPropDlg::OnBnClickedCheckB2b() +{ + //this->GetDlgItem(IDC_EDIT_DELAY)->EnableWindow(!this->IsDlgButtonChecked(IDC_CHECK_B2B)); +} diff --git a/LoopPropDlg.h b/LoopPropDlg.h new file mode 100644 index 0000000..9d6445e --- /dev/null +++ b/LoopPropDlg.h @@ -0,0 +1,35 @@ +#pragma once +#include "afxwin.h" +#include "Resource.h" + +// CLoopPropDlg dialog + +class CLoopPropDlg : public CDialog +{ + DECLARE_DYNAMIC(CLoopPropDlg) + +public: + CLoopPropDlg(CWnd* pParent = NULL); // standard constructor + virtual ~CLoopPropDlg(); + +// Dialog Data + enum { IDD = IDD_DIALOG_PROPLOOP }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + virtual BOOL OnInitDialog(); + virtual void OnOK(); + + DECLARE_MESSAGE_MAP() +public: +//---------------------------------------------------------------------------------------- + CString m_Name, m_Note, m_MatraCountStr; + CComboBox m_ComboMatra; + CComboBox m_ComboAcc; + UINT m_Repeat, m_Acc, m_Matra, m_Bpm; + +//---------------------------------------------------------------------------------------- + afx_msg void OnCbnSelchangeComboMatra(); + afx_msg void OnCbnSelchangeComboAcc(); + afx_msg void OnBnClickedCheckB2b(); +}; diff --git a/MultilineList.cpp b/MultilineList.cpp new file mode 100644 index 0000000..4dd2cc3 --- /dev/null +++ b/MultilineList.cpp @@ -0,0 +1,1607 @@ +/* + * CMultilineList custom control + * Copyright (C) 2006 Dave Calkins (coder1024@gmail.com) + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the + * + * Free Software Foundation, Inc. + * 59 Temple Place, Suite 330 + * Boston, MA 02111-1307 USA + * + */ + +#include "stdafx.h" +#include "MultilineList.h" + +using namespace std; + +// Win32 class name used for the window; if you're using the VS dialog editor you need +// to put this string in the Class property of the custom control +#define MULTILINELIST_CLASSNAME _T("CMultilineList") + +// width of the internal borders used between cells/cols/rows +#define GRID_WIDTH 1 + +// spacing inside cells between the text and the cell borders +#define INNER_PADDING 2 + +// control IDs for child controls +#define CHILD_ID_HEADERCTRL 101 +#define CHILD_ID_SCROLLBAR 102 +#define CHILD_ID_SCROLLBARHORZ 103 + +// header control height is set to be the font height plus the below +#define HEADERCTRL_HEIGHT_EXTRA 6 + +// # pixels to scroll horizontally when using arrows +#define HORZSCROLL_PIXELS 25 + +IMPLEMENT_DYNAMIC(CMultilineList, CWnd) +BEGIN_MESSAGE_MAP(CMultilineList, CWnd) + ON_WM_ERASEBKGND() + ON_WM_PAINT() + ON_WM_SIZE() + ON_WM_VSCROLL() + ON_WM_MOUSEWHEEL() + ON_WM_HSCROLL() + ON_WM_LBUTTONDOWN() +END_MESSAGE_MAP() + +//////////////////////////////////////////////////////////////////////////////// +// PUBLIC +//////////////////////////////////////////////////////////////////////////////// + +CMultilineList::CMultilineList() +: m_nCols(0), + m_nRows(0), + m_viewYPos(0), + m_viewXPos(0), + m_markYPos(0), + m_markXPos(0), + m_curSelRow(-1), + m_IsMarkable(false), + m_nHighlightedRow(0), + m_sel(false), + m_selcol(0), + m_selrow(0) +{ + RegisterWindowClass(); +} + +CMultilineList::~CMultilineList() +{ +} + +BOOL CMultilineList::Create(CWnd* pParentWnd, const RECT& rect, UINT nID, + DWORD dwStyle /*=WS_VISIBLE*/) +{ + return CWnd::Create(MULTILINELIST_CLASSNAME, _T(""), dwStyle, rect, + pParentWnd, nID); +} + +void CMultilineList::SetSize(int nCols, int nRows) +{ + ASSERT(nCols >= 0); + ASSERT(nRows >= 0); + + // if no change, do nothing + if ((nCols == m_nCols) && + (nRows == m_nRows)) + { + return; + } + + // if the # cols or # rows is being reduced + if ((nCols < m_nCols) || + (nRows < m_nRows)) + { + // walk through all cells + map,Cell>::iterator i; + for (i = m_cells.begin(); i != m_cells.end(); ) + { + int col = i->first.first; + int row = i->first.second; + + // remove any cells outside the new dimensions + if ((col >= nCols) || + (row >= nRows)) + { + i = m_cells.erase(i); + } + else + { + ++i; + } + } + } + + // if the # cols is being reduced + if (nCols < m_nCols) + { + // walk through all columns + map::iterator j; + for (j = m_columns.begin(); j != m_columns.end(); ) + { + int col = j->first; + + // remove any columns outside the new dimensions + if (col >= nCols) + { + j = m_columns.erase(j); + } + else + { + ++j; + } + } + + // invalidate all row heights + m_rowHeights.clear(); + } + + // if the # rows is being reduced but # cols is not being reduced + // (since if the # cols was reduced all row heights would have been + // invalidated anyway) + if ((nRows < m_nRows) && + (nCols >= m_nCols)) + { + // walk through the calculated row heights + map::iterator k; + for (k = m_rowHeights.begin(); k != m_rowHeights.end(); ) + { + int row = k->first; + + // remove (invalidate) calculated row heights corresponding to rows which are outside the new dimensions + if (row >= nRows) + { + k = m_rowHeights.erase(k); + } + else + { + ++k; + } + } + } + + // store new size + m_nCols = nCols; + m_nRows = nRows; + + // update + Invalidate(FALSE); + CalculateRowHeights(); + UpdateChildControls(); +} + +void CMultilineList::GetSize(int & nCols, int & nRows) +{ + // return current size of the list + nCols = m_nCols; + nRows = m_nRows; +} + +void CMultilineList::SetColHeading(int col, LPCTSTR heading) +{ + ASSERT(col >= 0); + ASSERT(col < m_nCols); + ASSERT(heading != NULL); + + // use existing column object (if there is one) or a new one + Column column; + map::iterator i = m_columns.find(col); + if (i != m_columns.end()) + { + column = i->second; + + // abort if no change + if (column.m_heading == CString(heading)) + return; + } + + // set column heading + column.m_heading = heading; + + // store the column object back in the map + m_columns[col] = column; + + // update + Invalidate(FALSE); + UpdateChildControls(); +} + +void CMultilineList::SetColWidth(int col, int width) +{ + ASSERT(col >= 0); + ASSERT(col < m_nCols); + ASSERT(width >= 0); + + // use existing column object (if there is one) or use default + Column column; + map::iterator i = m_columns.find(col); + if (i != m_columns.end()) + { + column = i->second; + + // abort if no change + if (column.m_width == width) + return; + } + + // set column width + column.m_width = width; + + // store the column object back in the map + m_columns[col] = column; + + // invalidate all row heights + m_rowHeights.clear(); + + // update + Invalidate(FALSE); + CalculateRowHeights(); + UpdateChildControls(); +} + +void CMultilineList::SetCellText(int col, int row, LPCTSTR text, int align, COLORREF color) +{ + ASSERT(col >= 0); + ASSERT(row >= 0); + ASSERT(col < m_nCols); + ASSERT(row < m_nRows); + ASSERT(text != NULL); + + // use existing cell object (if there is one) or a new one + Cell cell; + pair coord = make_pair(col,row); + map,Cell>::iterator i = m_cells.find(coord); + if (i != m_cells.end()) + { + cell = i->second; + + // abort if no change + if (cell.m_text == CString(text)) + return; + } + + //set color + cell.m_TextColor = color; + + // set cell text + cell.m_text = text; + cell.m_align = align; + + // store the cell object back in the map + m_cells[coord] = cell; + + // invalidate this row's height + m_rowHeights.erase(row); + + // update + Invalidate(FALSE); + CalculateRowHeights(); + UpdateChildControls(); +} + +void CMultilineList::SetCellMark(int col, int row, BOOL mark) +{ + ASSERT(col >= 0); + ASSERT(row >= 0); + ASSERT(col < m_nCols); + ASSERT(row < m_nRows); + // use existing cell object (if there is one) or a new one + Cell cell; + pair coord = make_pair(col,row); + map,Cell>::iterator i = m_cells.find(coord); + if (i != m_cells.end()) + { + cell = i->second; + if (cell.m_marked == mark) return; // abort if no change + } + // set cell mark + if(!cell.m_disabled) + { + cell.m_marked = mark; + m_cells[coord] = cell; // store the cell object back in the map + } + // update + Invalidate(FALSE); + CalculateRowHeights(); + UpdateChildControls(); +} + +void CMultilineList::SetCellBg(int col, int row, BOOL mark) +{ + ASSERT(col >= 0); + ASSERT(row >= 0); + ASSERT(col < m_nCols); + ASSERT(row < m_nRows); + // use existing cell object (if there is one) or a new one + Cell cell; + pair coord = make_pair(col,row); + map,Cell>::iterator i = m_cells.find(coord); + if (i != m_cells.end()) + { + cell = i->second; + if (cell.m_marked2 == mark) return; // abort if no change + } + // set cell mark + if(!cell.m_disabled) + { + cell.m_marked2 = mark; + m_cells[coord] = cell; // store the cell object back in the map + } + // update + //Invalidate(FALSE); + //CalculateRowHeights(); + //UpdateChildControls(); +} + +CString CMultilineList::GetCellText(int col, int row) +{ + ASSERT(col >= 0); + ASSERT(row >= 0); + ASSERT(col < m_nCols); + ASSERT(row < m_nRows); + + CString result; + + // use existing cell object (if there is one) or use default + Cell cell; + map,Cell>::iterator i = m_cells.find(make_pair(col,row)); + if (i != m_cells.end()) + { + cell = i->second; + } + + // return the cell text + result = cell.m_text; + + return result; +} + +void CMultilineList::SetSelRow(int row) +{ + ASSERT(row >= 0); + ASSERT(row < m_nRows); + + // force selected row to the specified value + m_curSelRow = row; + + // update + Invalidate(FALSE); + UpdateChildControls(); +} + +int CMultilineList::GetSelRow() +{ + // return currently selected row + return m_curSelRow; +} + +int CMultilineList::GetRowFromPoint(CPoint pt) +{ + int result = -1; + + CalculateRowHeights(); + + // ensure point is inside content area + CRect cr; + GetContentRect(cr); + if (cr.PtInRect(pt)) + { + // convert to list coords + int listYPos = m_viewYPos + (pt.y - cr.top); + + // walk through the rows until we find one at the specified vertical location + int row = 0; + for (int yPos = 0; row < m_nRows; row++) + { + int thisRowHeight = m_rowHeights[row]; + + if ((yPos + thisRowHeight) > listYPos) + { + break; + } + else + { + yPos += thisRowHeight; + } + } + + // did we find a row? + if (row < m_nRows) + { + result = row; + + // //find col-cafvt custom + //for (int col = 0; col < m_nCols; col++) + //{ + // Column column; + // std::map::iterator i = m_columns.find(col); + // if (i != m_columns.end()) column = i->second; + // if (pt.x > column.m_width) + // return result; + //} + + } + } + + return result; +} + +void CMultilineList::EnsureRowIsVisible(int row) +{ + ASSERT(row >= 0); + ASSERT(row < m_nRows); + + // ensure row heights are up to date + CalculateRowHeights(); + + // find top coord of specified row + int rowYPos = 0; + for (int _row = 0; _row < m_nRows; _row++) + { + if (_row == row) + { + break; + } + else + { + rowYPos += m_rowHeights[_row]; + } + } + + // height of specified row + int rowHeight = m_rowHeights[row]; + + // content rect + CRect cr; + GetContentRect(cr); + + // top of row is above visible area + if (rowYPos < m_viewYPos) + { + // scroll up so that top of view is the top of the row + m_viewYPos = rowYPos; + + // update + Invalidate(FALSE); + UpdateChildControls(); + } + // bottom of row is below visible area + else if ((rowYPos + rowHeight) > (m_viewYPos + cr.Height())) + { + // assuming row is smaller than the viewable area, + // scroll down so that bottom of view includes the bottom of the row + if (rowHeight < cr.Height()) + { + m_viewYPos += ((rowYPos + rowHeight) - (m_viewYPos + cr.Height())); + } + else + { + // if row is taller than the viewable area, then just scroll so + // the top of the view is at the top of the row + m_viewYPos = rowYPos; + } + + // update + Invalidate(FALSE); + UpdateChildControls(); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// PRIVATE +//////////////////////////////////////////////////////////////////////////////// + +BOOL CMultilineList::RegisterWindowClass() +{ + HINSTANCE hInst = AfxGetInstanceHandle(); + + WNDCLASS wndcls; + ZeroMemory(&wndcls,sizeof(WNDCLASS)); + + if (!(::GetClassInfo(hInst, MULTILINELIST_CLASSNAME, &wndcls))) + { + wndcls.style = CS_DBLCLKS; + wndcls.lpfnWndProc = ::DefWindowProc; + wndcls.cbClsExtra = 0; + wndcls.cbWndExtra = 0; + wndcls.hInstance = hInst; + wndcls.hIcon = NULL; + wndcls.hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW); + wndcls.hbrBackground = (HBRUSH) (COLOR_3DFACE + 1); + wndcls.lpszMenuName = NULL; + wndcls.lpszClassName = MULTILINELIST_CLASSNAME; + + if (!AfxRegisterClass(&wndcls)) + { + AfxThrowResourceException(); + return FALSE; + } + } + + return TRUE; +} + +void CMultilineList::PreSubclassWindow() +{ + // add a border + ModifyStyle(GetSafeHwnd(),0,WS_BORDER,0); + + // KLUDGE - after adding the border above + // this seems to be necessary to get the border + // to initially be drawn + CRect wr; + GetWindowRect(wr); + GetParent()->ScreenToClient(wr); + wr.right -= 1; + MoveWindow(wr); + wr.right += 1; + MoveWindow(wr); + ///////////////////// + + PrepareOffscreenSurface(); + + // create GDI objects used in rendering + m_gridPen.CreatePen(PS_SOLID,GRID_WIDTH,RGB(200,220,220));//GetSysColor(COLOR_WINDOWTEXT)); + //m_gridPen.CreatePen(PS_SOLID,GRID_WIDTH,GetSysColor(COLOR_WINDOWTEXT)); + + // create default font matching parent's font + LOGFONT lf; + GetParent()->GetFont()->GetLogFont(&lf); + //memset(&lf, 0x00, sizeof(lf)); + //memcpy(lf.lfFaceName, TEXT("Microsoft Sans Serif"), 24); + + //lf.lfWeight = FW_BOLD; + m_defaultFont.CreateFontIndirect(&lf); + m_headerFont.CreateFontIndirect(&lf); + + // initialize child controls + CreateChildControls(); + PositionChildControls(); + + CWnd::PreSubclassWindow(); +} + +void CMultilineList::OnSize(UINT nType, int cx, int cy) +{ + CWnd::OnSize(nType, cx, cy); + + PositionChildControls(); + UpdateChildControls(); +} + +BOOL CMultilineList::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) +{ + NMHDR * pNMHDR = (NMHDR*)lParam; + + // header control notifications + if (wParam == CHILD_ID_HEADERCTRL) + { + NMHEADER * pNMHEADER = (NMHEADER*)pNMHDR; + + // user is resizing a column + if (pNMHDR->code == HDN_TRACK) + { + // use existing column object (if there is one) or use default + Column column; + std::map::iterator i = m_columns.find(pNMHEADER->iItem); + if (i != m_columns.end()) + { + column = i->second; + } + + // update the width of the column object and store it back in the map + column.m_width = pNMHEADER->pitem->cxy; + m_columns[pNMHEADER->iItem] = column; + + // update + Invalidate(FALSE); + UpdateChildControls(); + } + + // user has finished resizing a column + if (pNMHDR->code == HDN_ENDTRACK) + { + // use existing column object (if there is one) or use default + Column column; + std::map::iterator i = m_columns.find(pNMHEADER->iItem); + if (i != m_columns.end()) + { + column = i->second; + } + + // update the width of the column object and store it back in the map + column.m_width = pNMHEADER->pitem->cxy; + m_columns[pNMHEADER->iItem] = column; + + // invalidate all row heights + m_rowHeights.clear(); + + // update + Invalidate(FALSE); + CalculateRowHeights(); + UpdateChildControls(); + } + } + + return CWnd::OnNotify(wParam, lParam, pResult); +} + +void CMultilineList::CreateChildControls() +{ + m_headerCtrl.Create( + CCS_TOP|WS_CHILD|WS_VISIBLE,CRect(0,0,0,0), + this,CHILD_ID_HEADERCTRL); + m_headerCtrl.SetFont(&m_headerFont); + + m_scrollBar.Create( + SBS_RIGHTALIGN|SBS_VERT|WS_CHILD|WS_VISIBLE, + CRect(0,0,0,0),this,CHILD_ID_SCROLLBAR); + + m_scrollBarHorz.Create( + SBS_BOTTOMALIGN|SBS_HORZ|WS_CHILD|WS_VISIBLE, + CRect(0,0,0,0),this,CHILD_ID_SCROLLBARHORZ); +} + +void CMultilineList::PositionChildControls() +{ + // ensure the child controls exist + if ((m_headerCtrl.GetSafeHwnd() == NULL) || + (m_scrollBar.GetSafeHwnd() == NULL) || + (m_scrollBarHorz.GetSafeHwnd() == NULL)) + return; + + CRect cr; + GetClientRect(cr); + + // get text height + CDC * pDC = GetDC(); + CFont * origFont = pDC->SelectObject(&m_headerFont); + TEXTMETRIC tm; + pDC->GetOutputTextMetrics(&tm); + pDC->SelectObject(origFont); + ReleaseDC(pDC); + + // header control + CRect hdrRect = cr; + hdrRect.bottom = hdrRect.top + tm.tmHeight + HEADERCTRL_HEIGHT_EXTRA; + m_headerCtrl.MoveWindow(hdrRect); + + // scrollbar + CRect sbRect = cr; + sbRect.left = sbRect.right - GetSystemMetrics(SM_CXVSCROLL); + sbRect.top = sbRect.top + GetSystemMetrics(SM_CYHSCROLL); + m_scrollBar.MoveWindow(sbRect); + + // horiz scrollbar + CRect sbRectHorz = cr; + sbRectHorz.top = sbRectHorz.bottom - GetSystemMetrics(SM_CYHSCROLL); + if (m_scrollBar.IsWindowVisible()) + { + sbRectHorz.right = sbRectHorz.right - GetSystemMetrics(SM_CXVSCROLL); + } + m_scrollBarHorz.MoveWindow(sbRectHorz); + + // adjust left edge of the header control to be at the left edge of the list + // this causes the header control to scroll horizontally with the content + if (m_viewXPos > 0) + { + CRect contentRect; + GetContentRect(contentRect); + + CRect hr; + m_headerCtrl.GetWindowRect(hr); + ScreenToClient(hr); + hr.left = contentRect.left - m_viewXPos; + m_headerCtrl.MoveWindow(hr); + } +} + +void CMultilineList::UpdateChildControls() +{ + // get content rect + CRect contentRect; + GetContentRect(contentRect); + + // remove excess header control items + while (m_headerCtrl.GetItemCount() > m_nCols) + { + if (!m_headerCtrl.DeleteItem(m_headerCtrl.GetItemCount()-1)) + break; + } + + // add header control items if needed + while (m_headerCtrl.GetItemCount() < m_nCols) + { + HDITEM hdi; + ZeroMemory(&hdi,sizeof(HDITEM)); + hdi.mask = HDI_TEXT | HDI_WIDTH | HDI_FORMAT; + hdi.cxy = DEFAULT_COLUMN_WIDTH; + hdi.fmt = HDF_STRING | HDF_CENTER; + hdi.pszText = _T(""); + hdi.cchTextMax = 0; + + + if (m_headerCtrl.InsertItem(m_headerCtrl.GetItemCount(),&hdi) < 0) + break; + } + + // adjust left edge of the header control to be at the left edge of the list + // this makes the header control scroll horizontally with the list content + CRect hr; + m_headerCtrl.GetWindowRect(hr); + ScreenToClient(hr); + hr.left = contentRect.left - m_viewXPos; + m_headerCtrl.MoveWindow(hr); + + // for each header control item + for (int col = 0; col < m_nCols; col++) + { + // use existing object (if there is one) or default + Column column; + map::iterator i = m_columns.find(col); + if (i != m_columns.end()) + { + column = i->second; + } + + HDITEM hdi; + ZeroMemory(&hdi,sizeof(HDITEM)); + hdi.mask = HDI_TEXT | HDI_WIDTH; + + // get current item attributes + if (m_headerCtrl.GetItem(col,&hdi)) + { + // if different, update header control item + CString curHeading(hdi.pszText); + if ((curHeading != column.m_heading) || + (hdi.cxy != column.m_width)) + { + hdi.pszText = (LPTSTR)((LPCTSTR)(column.m_heading)); + hdi.cchTextMax = column.m_heading.GetLength(); + hdi.cxy = column.m_width; + + m_headerCtrl.SetItem(col, &hdi); + } + } + } + + // compute height of the entire list + int totalHeight = 0; + map::iterator iRowHeights; + for (iRowHeights = m_rowHeights.begin(); iRowHeights != m_rowHeights.end(); ++iRowHeights) + { + totalHeight += iRowHeights->second; + } + + // should the vert scrollbar be enabled? + if (totalHeight <= contentRect.Height()) + { + // no, ensure its disabled + if (m_scrollBar.IsWindowEnabled()) + { + m_scrollBar.EnableWindow(FALSE); + m_scrollBar.ShowWindow(SW_HIDE); + } + } + else + { + // ensure its enabled + if (!m_scrollBar.IsWindowEnabled()) + { + m_scrollBar.EnableWindow(TRUE); + m_scrollBar.ShowWindow(SW_SHOW); + } + + // correct values for scrollbar + int nMin = 0; + int nMax = totalHeight; + int nPage = contentRect.Height(); + int nPos = m_viewYPos; + + // get current scrollbar values + SCROLLINFO si; + ZeroMemory(&si,sizeof(SCROLLINFO)); + si.cbSize = sizeof(SCROLLINFO); + si.fMask = SIF_ALL; + m_scrollBar.GetScrollInfo(&si); + + // if any of the values are different, update scrollbar + if ((nMin != si.nMin) || + (nMax != si.nMax) || + (nPage != si.nPage) || + (nPos != si.nPos)) + { + si.nMin = nMin; + si.nMax = nMax; + si.nPage = nPage; + si.nPos = nPos; + + m_scrollBar.SetScrollInfo(&si); + } + } + + // compute total width of the list + int totalWidth = 0; + for (int col = 0; col < m_nCols; col++) + { + // use existing object (if there is one) or default + Column column; + map::iterator iColumn = m_columns.find(col); + if (iColumn != m_columns.end()) + { + column = iColumn->second; + } + + totalWidth += column.m_width; + } + + // should horz scrollbar be enabled? + if (totalWidth <= contentRect.Width()) + { + // ensure its disabled and hidden + if (m_scrollBarHorz.IsWindowEnabled()) + { + m_scrollBarHorz.EnableWindow(FALSE); + m_scrollBarHorz.ShowWindow(SW_HIDE); + } + } + else + { + // ensure its enabled and visible + if (!m_scrollBarHorz.IsWindowEnabled()) + { + m_scrollBarHorz.EnableWindow(TRUE); + m_scrollBarHorz.ShowWindow(SW_SHOW); + } + + // correct values for scrollbar + int nMin = 0; + int nMax = totalWidth; + int nPage = contentRect.Width(); + int nPos = m_viewXPos; + + // get current scrollbar values + SCROLLINFO si; + ZeroMemory(&si,sizeof(SCROLLINFO)); + si.cbSize = sizeof(SCROLLINFO); + si.fMask = SIF_ALL; + m_scrollBarHorz.GetScrollInfo(&si); + + // if any of the values are different, update scrollbar + if ((nMin != si.nMin) || + (nMax != si.nMax) || + (nPage != si.nPage) || + (nPos != si.nPos)) + { + si.nMin = nMin; + si.nMax = nMax; + si.nPage = nPage; + si.nPos = nPos; + + m_scrollBarHorz.SetScrollInfo(&si); + } + } +} + +void CMultilineList::CalculateRowHeights() +{ + CFont * origFont = m_offscreenDC.SelectObject(&m_defaultFont); + CBitmap * origBitmap = m_offscreenDC.SelectObject(&m_offscreenBitmap); + + // for all rows + for (int row = 0; row < m_nRows; row++) + { + // if a row height is not already available for this row + map::iterator iRow = m_rowHeights.find(row); + if (iRow == m_rowHeights.end()) + { + int rowHeight = 0; + + // compute heights of each cell, finding the tallest one + for (int col = 0; col < m_nCols; col++) + { + // get column object (if one exists) or use the default + Column column; + std::map::iterator iCol = m_columns.find(col); + if (iCol != m_columns.end()) + { + column = iCol->second; + } + + // get cell object (if one exists) or use the default + Cell cell; + map,Cell>::iterator iCell = m_cells.find(make_pair(col,row)); + if (iCell != m_cells.end()) + { + cell = iCell->second; + } + + CRect textRect(0,0,column.m_width,0); + textRect.DeflateRect(INNER_PADDING,INNER_PADDING); + int origRight = textRect.right; + + // compute cell height + m_offscreenDC.DrawTextEx(cell.m_text,textRect, + DT_CALCRECT|DT_LEFT|DT_NOPREFIX|DT_TOP|DT_WORDBREAK, + NULL); + + textRect.right = origRight; + textRect.InflateRect(INNER_PADDING,INNER_PADDING); + textRect.bottom += GRID_WIDTH; + + if (textRect.bottom > rowHeight) + { + rowHeight = textRect.bottom; + } + } + + // store row height + m_rowHeights[row] = rowHeight; + } + } + + m_offscreenDC.SelectObject(origBitmap); + m_offscreenDC.SelectObject(origFont); +} + + +void CMultilineList::GetContentRect(CRect & r) +{ + // get geom of client area and child controls + CRect cr; + GetClientRect(cr); + CRect hdrRect; + m_headerCtrl.GetClientRect(hdrRect); + CRect sbRect; + m_scrollBar.GetClientRect(sbRect); + CRect sbRectHorz; + m_scrollBarHorz.GetClientRect(sbRectHorz); + + // shrink for child controls + r = cr; + r.top += hdrRect.Height(); + r.right -= sbRect.Width(); + r.bottom -= sbRectHorz.Height(); + + // vert scroll bar not visible; extend area to cover where it would be + if (!m_scrollBar.IsWindowVisible()) + { + r.right += sbRect.Width(); + } + + // horz scroll bar not visible; extend area to cover where it would be + if (!m_scrollBarHorz.IsWindowVisible()) + { + r.bottom += sbRectHorz.Height(); + } +} + +BOOL CMultilineList::OnEraseBkgnd(CDC* pDC) +{ + // do nothing; we don't want to erase the background because we + // use double-buffering and so overwrite the entire client area + // with every repaint + return TRUE; +} + +void CMultilineList::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) +{ + CWnd::OnVScroll(nSBCode, nPos, pScrollBar); + + CalculateRowHeights(); + + // get content rect + CRect cr; + GetContentRect(cr); + + if ((nSBCode == SB_THUMBPOSITION) || + (nSBCode == SB_THUMBTRACK)) + { + // set pos to specified absolute pos + m_viewYPos = nPos; + } + + else if (nSBCode == SB_PAGEUP) + { + // set pos up by 1 page + m_viewYPos -= cr.Height(); + } + + else if (nSBCode == SB_PAGEDOWN) + { + // compute height of the entire list + int totalHeight = 0; + map::iterator iRowHeights; + for (iRowHeights = m_rowHeights.begin(); iRowHeights != m_rowHeights.end(); ++iRowHeights) + { + totalHeight += iRowHeights->second; + } + + // move down by 1 page or to end if there's less + // than one page remaining outside the view + int remainingSpace = totalHeight - (m_viewYPos + cr.Height()); + if (remainingSpace < cr.Height()) + { + m_viewYPos += remainingSpace; + } + else + { + m_viewYPos += cr.Height(); + } + } + + else if ((nSBCode == SB_LINEUP) || (nSBCode == SB_LINEDOWN)) + { + // determine top visible row + int y1 = 0; + int row = 0; + for (int yPos = 0; row < m_nRows; row++) + { + int thisRowHeight = m_rowHeights[row]; + + if ((yPos + thisRowHeight) > m_viewYPos) + { + break; + } + else + { + yPos += thisRowHeight; + } + } + + // determine remaining height in list (including and after the top visible row) + int remainingHeight = 0; + for (int row2 = row; row2 < m_nRows; row2++) + { + remainingHeight += m_rowHeights[row2]; + } + + // for scrolling up, use one row above the top visible row + if (nSBCode == SB_LINEUP) + { + row--; + if (row < 0) + row = 0; + } + + // move by the height of the top row + int deltaY = m_rowHeights[row]; + if (nSBCode == SB_LINEUP) + { + deltaY *= -1; + } + + // assuming there's more to scroll (or if we're scrolling up) + if (remainingHeight > cr.Height() || (nSBCode == SB_LINEUP)) + { + m_viewYPos += deltaY; + + if (m_viewYPos < 0) + { + m_viewYPos = 0; + } + } + } + + // limit upward scrolling + if (m_viewYPos < 0) + { + m_viewYPos = 0; + } + + // update + Invalidate(TRUE); + UpdateChildControls(); +} + +void CMultilineList::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) +{ + CWnd::OnHScroll(nSBCode, nPos, pScrollBar); + + // compute total width of the list + int totalWidth = 0; + for (int col = 0; col < m_nCols; col++) + { + // use existing object (if there is one) or default + Column column; + map::iterator iColumn = m_columns.find(col); + if (iColumn != m_columns.end()) + { + column = iColumn->second; + } + + totalWidth += column.m_width; + } + + if ((nSBCode == SB_THUMBPOSITION) || + (nSBCode == SB_THUMBTRACK)) + { + // set pos to specified absolute pos + m_viewXPos = nPos; + } + + else if (nSBCode == SB_PAGELEFT) + { + CRect cr; + GetContentRect(cr); + + // set pos up by left 1 page + m_viewXPos -= cr.Width(); + } + + else if (nSBCode == SB_PAGERIGHT) + { + CRect cr; + GetContentRect(cr); + + // move right by 1 page or to end if there's less + // than one page remaining outside the view + int remainingSpace = totalWidth - (m_viewXPos + cr.Width()); + if (remainingSpace < cr.Width()) + { + m_viewXPos += remainingSpace; + } + else + { + m_viewXPos += cr.Width(); + } + } + + else if (nSBCode == SB_LINELEFT) + { + // set pos left by constant amount + m_viewXPos -= HORZSCROLL_PIXELS; + } + + else if (nSBCode == SB_LINERIGHT) + { + CRect cr; + GetContentRect(cr); + + // don't scroll right unless there's more to scroll to + if ((totalWidth - m_viewXPos) > cr.Width()) + { + // set pos right by constant amount + m_viewXPos += HORZSCROLL_PIXELS; + } + } + + // limit scrolling + if (m_viewXPos < 0) + { + m_viewXPos = 0; + } + + Invalidate(TRUE); + UpdateChildControls(); +} + +BOOL CMultilineList::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) +{ + // scroll up/down 1 line when mouse-wheel is used + if (zDelta < 0) + { + OnVScroll(SB_LINEDOWN,0,NULL); + } + else + { + OnVScroll(SB_LINEUP,0,NULL); + } + + return CWnd::OnMouseWheel(nFlags, zDelta, pt); +} + +void CMultilineList::OnLButtonDown(UINT nFlags, CPoint point) +{ + //cafvt custom + m_markXPos = point.x; + m_markYPos = point.y; + //reset view pos if scrolled + //m_viewXPos = 0; + //m_viewYPos = 0; + + // on click, select the row which was clicked on + m_curSelRow = GetRowFromPoint(point); + Invalidate(FALSE); + UpdateChildControls(); + + + // ensure the selected row is visible + if (m_curSelRow >= 0) + { + EnsureRowIsVisible(m_curSelRow); + } + + ClientToScreen(&point); + m_XPos = point.x; + m_YPos = point.y; + + // sent notification message to parent window + int thisCtrlID = GetDlgCtrlID(); + GetParent()->PostMessage(WM_COMMAND,MAKEWPARAM(thisCtrlID,LBN_SELCHANGE),(LPARAM)GetSafeHwnd()); +} + +void CMultilineList::OnPaint() +{ + CPaintDC dc(this); + + // ensure offscreen rendering surface is ready + if (!PrepareOffscreenSurface()) + return; + + // ensure GDI objects are ready and match current system preferences + + //LOGPEN lp; + //m_gridPen.GetLogPen(&lp); + //if (lp.lopnColor != GetSysColor(COLOR_WINDOWTEXT)) + //{ + // m_gridPen.DeleteObject(); + // m_gridPen.CreatePen(PS_SOLID,GRID_WIDTH,GetSysColor(COLOR_WINDOWTEXT)); + //} + + // ensure row height calculations are up to date + CalculateRowHeights(); + + // get content area (client area minus child controls) + CRect cr; + GetClientRect(cr); + + CFont * origFont = m_offscreenDC.SelectObject(&m_defaultFont); + CBitmap * origBitmap = m_offscreenDC.SelectObject(&m_offscreenBitmap); + + // render the content area + CRect renderRect; + GetContentRect(renderRect); + RenderContent(m_offscreenDC,renderRect); + + // blt the rendered content from the offscreen area to the window + dc.BitBlt(renderRect.left,renderRect.top, + renderRect.Width(),renderRect.Height(), + &m_offscreenDC, + renderRect.left,renderRect.top, + SRCCOPY); + + m_offscreenDC.SelectObject(origBitmap); + m_offscreenDC.SelectObject(origFont); +} + +BOOL CMultilineList::PrepareOffscreenSurface() +{ + CRect wr; + GetWindowRect(wr); + CSize ws = wr.Size(); + + // not yet created or the size has changed + if ((m_offscreenBitmap.GetSafeHandle() == NULL) || + (m_offscreenBitmapSize != ws)) + { + CDC * pDC = GetDC(); + + // create offscreen DC if necessary + if (m_offscreenDC.GetSafeHdc() == NULL) + { + if (!m_offscreenDC.CreateCompatibleDC(pDC)) + return FALSE; + } + + // delete existing bitmap (if there is one) + if (m_offscreenBitmap.GetSafeHandle() != NULL) + { + m_offscreenBitmap.DeleteObject(); + } + + // create new bitmap sized to the window + if (!m_offscreenBitmap.CreateCompatibleBitmap(pDC,ws.cx,ws.cy)) + return FALSE; + + // store the new size + m_offscreenBitmapSize = ws; + + ReleaseDC(pDC); + } + + return TRUE; +} + +void CMultilineList::RenderContent(CDC & dc, CRect & r) +{ + dc.FillRect(r,CBrush::FromHandle(GetSysColorBrush(COLOR_WINDOW))); + + dc.SetBkMode(TRANSPARENT); + dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT)); + + CPen * origPen = dc.SelectObject(&m_gridPen); + + int y1 = 0; + int row = 0; + + // determine top visible row and setup y1 to be the top of its rendering area + for (int yPos = 0; row < m_nRows; row++) + { + int thisRowHeight = m_rowHeights[row]; + + if ((yPos + thisRowHeight) > m_viewYPos) + { + y1 = r.top - (m_viewYPos - yPos); + break; + } + else + { + yPos += thisRowHeight; + } + } + + int firstRenderedRow = row; + + // for each row + for (; (row < m_nRows) && (y1 <= r.bottom); row++) + { + // start with zero height + int y2 = y1; + + // for each column + int x1 = r.left-m_viewXPos; + for (int col = 0/*, x1 = r.left-m_viewXPos*/; (col < m_nCols); col++) + { + // get the column object (if it exists) or use defaults + Column column; + std::map::iterator i = m_columns.find(col); + if (i != m_columns.end()) + { + column = i->second; + } + + // get the cell object (if it exists) or use defaults + Cell cell; + pair coord = make_pair(col,row); + map,Cell>::iterator j = m_cells.find(make_pair(col,row)); + if (j != m_cells.end()) + { + cell = j->second; + } + + // determine the required size of the text, given the column width + + int x2 = x1 + column.m_width; + + CRect textRect(x1,y1,x2,y1); + textRect.DeflateRect(INNER_PADDING,INNER_PADDING); + int origRight = textRect.right; + + dc.DrawTextEx(cell.m_text,textRect, + DT_CALCRECT|DT_LEFT|DT_NOPREFIX|DT_TOP|DT_WORDBREAK, + NULL); + + textRect.right = origRight; + //textRect.top += 2; + + // if this row is selected, fill in the background with the selection color and + // set the text color + //if (row == m_curSelRow)//cafvt custom + //if (row == m_nHighlightedRow) + //{ + // CRect bgRect(textRect); + // bgRect.InflateRect(INNER_PADDING,INNER_PADDING); + // bgRect.bottom = bgRect.top + m_rowHeights[row] + GRID_WIDTH; + // bgRect.top += GRID_WIDTH; + // dc.FillRect(bgRect,CBrush::FromHandle(GetSysColorBrush(COLOR_INFOBK))); //cafvt custom + // //dc.FillRect(bgRect,CBrush::FromHandle(GetSysColorBrush(COLOR_HIGHLIGHT))); + //} + if (cell.m_disabled) + { + dc.SetTextColor(RGB(200,200,200)); + } + else + { + // else, ensure text color is set to the non-selected color + //dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT)); + dc.SetTextColor(cell.m_TextColor); + } + + textRect.bottom += INNER_PADDING; + textRect.bottom += GRID_WIDTH; + + // ensure tallest cell is stored + if (textRect.bottom > y2) + { + y2 = textRect.bottom; + } + + //store cell rect + cell.cx1=textRect.left; + cell.cx2=textRect.right; + cell.cy1=textRect.top; + cell.cy2=textRect.bottom; + m_cells[coord] = cell; + + + //mark cell as selected - cafvt custom + //if(m_IsMarkable) + //{ + //if(m_markXPos>textRect.left && m_markXPostextRect.top && m_markYPos0) + // { + // cell.m_marked = !cell.m_marked; + // m_markXPos = 0; + // m_markYPos = 0; + // // store the cell object back in the map + // m_cells[coord] = cell; + // m_sel = cell.m_marked; + // } + // } + //} + + if(cell.m_marked2) + { + CBrush markbrush(RGB(240,240,250)); + CRect markrect(textRect); + markrect.bottom +=2; + markrect.left -=3; + dc.FillRect(markrect,&markbrush); + } + if(cell.m_marked) + { + CBrush markbrush(RGB(255,220,150)); + CRect markrect(textRect); + markrect.bottom +=2; + markrect.left -=3; + markrect.DeflateRect(2,2); + dc.FillRect(markrect,&markbrush); + } + //} + + // render the cell text + dc.DrawTextEx(cell.m_text,textRect, + cell.m_align|DT_NOPREFIX|DT_TOP|DT_WORDBREAK, + NULL); + + x1 = x2; + } + + // render horizontal grid line below the current row + //dc.MoveTo(r.left,y2+GRID_WIDTH+50); //cafvt customization + //dc.LineTo(x1,y2+GRID_WIDTH+50); + dc.MoveTo(r.left,y2+GRID_WIDTH); + dc.LineTo(x1,y2+GRID_WIDTH); + + // if not the first row, also render the top horizontal line above the current row + if (row > firstRenderedRow) + { + dc.MoveTo(r.left,y1+GRID_WIDTH); + dc.LineTo(x1,y1+GRID_WIDTH); + } + + // render the vertical lines between the columns + //for (int col = 0, x1 = r.left-m_viewXPos; (col < m_nCols) && (x1 <= r.right); col++) + for (int col = 0, x1 = r.left-m_viewXPos; (col < m_nCols-1) && (x1 <= r.right); col++)//cafvt custom + { + Column column; + std::map::iterator i = m_columns.find(col); + if (i != m_columns.end()) + { + column = i->second; + } + + int x2 = x1 + column.m_width; + + dc.MoveTo(x2-2,y1+GRID_WIDTH); //cafvt customization + dc.LineTo(x2-2,y2+GRID_WIDTH+50); + //dc.MoveTo(x2,y1+GRID_WIDTH); + //dc.LineTo(x2,y2+GRID_WIDTH); + + + x1 = x2; + } + + y1 = y2; + } + + dc.SelectObject(origPen); +} + +void CMultilineList::GetCellSelection() +{ + m_selcol = 0; + m_selrow = 0; + for (int col = 0; col coord = make_pair(col,row); + map,Cell>::iterator j = m_cells.find(make_pair(col,row)); + if (j != m_cells.end()) cell = j->second; + //mark cell as selected - cafvt custom + if((m_IsMarkable)&&(!cell.m_disabled)) + { + if(m_markXPos>cell.cx1-2 && m_markXPoscell.cy1-2 && m_markYPos=0) + { + cell.m_marked = !cell.m_marked; + m_markXPos = 0; + m_markYPos = 0; + // store the cell object back in the map + m_cells[coord] = cell; + m_sel = cell.m_marked; + return; + } + } + } + } + + } + } + +} + +BOOL CMultilineList::GetColStatus(int ncol) +{ + int res = 0; + for (int row = 0; row coord = make_pair(ncol,row); + map,Cell>::iterator j = m_cells.find(make_pair(ncol,row)); + if (j != m_cells.end()) cell = j->second; + + res += cell.m_marked; + + } + if(res > 0) return true; + return false; + +} + +void CMultilineList::SetCellDisable(int col, int row, BOOL dis) +{ + ASSERT(col >= 0); + ASSERT(row >= 0); + ASSERT(col < m_nCols); + ASSERT(row < m_nRows); + + // use existing cell object (if there is one) or a new one + Cell cell; + pair coord = make_pair(col,row); + map,Cell>::iterator i = m_cells.find(coord); + if (i != m_cells.end()) + { + cell = i->second; + + // abort if no change + if (cell.m_disabled == dis) return; + } + + // set cell disable + cell.m_disabled = dis; + + // store the cell object back in the map + m_cells[coord] = cell; + + Invalidate(false); +} \ No newline at end of file diff --git a/MultilineList.h b/MultilineList.h new file mode 100644 index 0000000..b089773 --- /dev/null +++ b/MultilineList.h @@ -0,0 +1,326 @@ +#pragma once + +/* + * CMultilineList custom control + * Copyright (C) 2006 Dave Calkins (coder1024@gmail.com) + * + * This library is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or (at your option) + * any later version. + * + * This library 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 Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the + * + * Free Software Foundation, Inc. + * 59 Temple Place, Suite 330 + * Boston, MA 02111-1307 USA + * + */ + +//****************************************************************************** +// REVISION HISTORY +//------------------------------------------------------------------------------ +// 2006.09.04 - initial release +//****************************************************************************** + +#include +#include + +// default column width in pixels; this is used if width for a column is +// not specified +#define DEFAULT_COLUMN_WIDTH 100 +#define TXTBLACK RGB(0,0,0) +#define TXTRED RGB(220,0,0) +#define TXTGREEN RGB(0,160,0) +#define TXTBLUE RGB(0,0,220) + + +/** + * A custom control which provides a multi-column list with varying row heights, + * allowing multi-line text in the cells. Cell text is wrapped as necessary and + * may contain '\n' chars which will force line breaks. + * + * To use, set the overall size (# cols, # rows), the column headings, and widths + * and then set individual cell text. + * + * When the current row selection changes, this control will send a WM_COMMAND + * message to its parent with the LBN_SELCHANGE code. i.e., it notifies its parent + * of selection changes using the same technique used by the standard list box. + * + * There are 2 ways to use this control in your code. + * + * 1) You can create the control dynamically by adding an instance of this class + * to your parent window class and then calling Create() with the desired + * geometry + * 2) You can also use the VS dialog editor to allow you to visually place the + * control. To do this, create a custom control, position and size as + * desired, and then set the Class property to "CMultilineList" (without the + * double-quotes). You can then right-click on the control and select + * "Add Variable" and then use that added variable in your code. + */ +class CMultilineList : public CWnd +{ +public: + + CMultilineList(); + virtual ~CMultilineList(); + + /** + * You can use this method to dynamically create an instance of the control. + */ + BOOL Create(CWnd* pParentWnd, const RECT& rect, UINT nID, DWORD dwStyle = WS_VISIBLE); + + /** + * Sets the overall geometry of the grid. When reducing the size using this + * method, anything which is then outside the new size is deleted. You must call + * this before anything else to ensure the size you need is available. + * @param nCols Desired number of columns (which are numbered [0...N-1]) + * @param nRows Desired number of rows (which are numbered [0...N-1]) + */ + void SetSize(int nCols, int nRows); + + /** + * Gets the current overall geometry of the grid. + * @param nCols will be initialized with the number of columns (which are numbered [0...N-1]) + * @param nRows will be initialized with the number of rows (which are numbered [0...N-1]) + */ + void GetSize(int & nCols, int & nRows); + + /** + * Sets the text shown in the heading above the specified column. + * @param col the column number [0...N-1] + * @param heading the text to be displayed + */ + void SetColHeading(int col, LPCTSTR heading); + + /** + * Sets the width of the specified column in pixels. Note that the user cal + * also change this themselves by dragging the column separators in the + * header control. + * @param col the column number [0...N-1] + * @param width desired width of the column in pixels + */ + void SetColWidth(int col, int width); + + /** + * Sets the text for the specified cell. The text may contain '\n' which + * will cause line breaks and heightening of the row as needed. The text + * will also be word-wrapped to ensure it fits within the column width. + * @param col the column number [0...N-1] + * @param row the row number [0...N-1] + * @param text the desired text for the cell + */ + void SetCellText(int col, int row, LPCTSTR text,int align = DT_LEFT, COLORREF color = TXTBLACK); + + /** + * Gets the current text in the specified cell. + * @param col the column number [0...N-1] + * @param row the row number [0...N-1] + * @return text in the specified cell + */ + CString GetCellText(int col, int row); + + /** + * changes the current selection to the specified row. changing the selection + * programmatically using this method will not trigger a WM_COMMAND notification + * message to be sent to the parent window. + * @param row the row number to select [0...N-1] + */ + void SetSelRow(int row); + + /** + * Gets the row number [0...N-1] of the currently selected row. + * @return the currently selected row number [0...N-1] or -1 if no row is currently selected + */ + int GetSelRow(); + + /** + * Gets the row which is displayed at the specified client co-ords in the window + * @param pt the point in client coords + * @return the row number [0...N-1] which the specified point is over (or -1 if there is no row at that point) + */ + int GetRowFromPoint(CPoint pt); + + /** + * Ensure the specified row is visible + * @param row the row number [0...N-1] + */ + void EnsureRowIsVisible(int row); + + //cafvt custom funcs + void SetCellMark(int col, int row, BOOL mark); + void SetCellBg(int col, int row, BOOL mark); + void SetCellDisable(int col, int row, BOOL dis); + void GetCellSelection(void); + + BOOL GetColStatus(int ncol); + + BOOL m_IsMarkable, m_sel; + int m_nHighlightedRow, m_selrow, m_selcol; + + // the overall size of the list (# of columns and # of rows) + int m_nCols, m_nRows; + // tracks the position of the top left of the visible area (# pixels relative to top and left of the list) + int m_viewXPos; + int m_viewYPos; + + //coord to display pop-up menu //naadh custom + int m_XPos; + int m_YPos; + + +public: // windows message handlers + + /// called to erase the background + afx_msg BOOL OnEraseBkgnd(CDC* pDC); + + /// called to paint the contents of the window + afx_msg void OnPaint(); + + /// called when the window has been resized + afx_msg void OnSize(UINT nType, int cx, int cy); + + /// called when scrolling occurs using the vertical scrollbar + afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); + + /// called when scrolling occurs using the horizontal scrollbar + afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); + + /// called in response to mouse-wheel + afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt); + + /// called when user clicks in the window + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + +protected: + + /// called at initialization + virtual void PreSubclassWindow(); + + /// called when receiving notification messages from the child controls + virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult); + + /// holds information about a single column + class Column + { + public: + + // column width in pixels + int m_width; + + // heading text to display above the column in the header control + CString m_heading; + + Column() + { + m_width = DEFAULT_COLUMN_WIDTH; + m_heading = _T(" "); + } + }; + + /// holds information about a single cell + class Cell + { + public: + + // text to display in the cell (can contain '\n' which will cause line breaks) + CString m_text; + int m_align; + BOOL m_marked, m_marked2; + int cx1,cy1,cx2,cy2; + BOOL m_disabled; + COLORREF m_TextColor; + + Cell() + { + m_text = _T(" "); + m_align = DT_LEFT; + m_marked = false; + m_marked2 = false; + m_disabled = false; + m_TextColor = TXTBLACK; + cx1=cx2=cy1=cy2=0; + } + }; + + // currently selected row + int m_curSelRow; + + + // tracks the position of mouseclick + int m_markXPos; + int m_markYPos; + + + /// maps column # to Column objects + std::map m_columns; + + /// maps to Cell objects + std::map,Cell> m_cells; + + /// maps row# to row height in pixels; values are invalidated by removing them; all values in here are valid + std::map m_rowHeights; + + /// registers the window class + BOOL RegisterWindowClass(); + + // the below provide an offscreen rendering surface, allowing us to render + // to that surface and then blt the resultant image into the window's DC + CDC m_offscreenDC; + CBitmap m_offscreenBitmap; + CSize m_offscreenBitmapSize; + + /** + * child header control, used to display the column headings and to allow + * dynamic resize of columns by the user + */ + CHeaderCtrl m_headerCtrl; + + /** + * child vertical scrollbar control + */ + CScrollBar m_scrollBar; + + /** + * child horizontal scrollbar control + */ + CScrollBar m_scrollBarHorz; + + // misc GDI objects used when rendering + CPen m_gridPen; + CFont m_defaultFont; + CFont m_headerFont; + + /// ensures the offscreen drawing surface is available and sized to the window's client area + BOOL PrepareOffscreenSurface(); + + /// creates the child controls during initialization + void CreateChildControls(); + + /// positions/sizes the child controls based on the current window size + void PositionChildControls(); + + /// updates the state of the child controls to match the state of this control + void UpdateChildControls(); + + /// ensures a complete set of valid row heights is available + void CalculateRowHeights(); + + /// calcuates the content area rect in window client coords + void GetContentRect(CRect & r); + + /// renders the content area (client area minus the border, header control, and scroll bar) + void RenderContent(CDC & dc, CRect & r); + + + DECLARE_DYNAMIC(CMultilineList) + DECLARE_MESSAGE_MAP() +}; + + diff --git a/Naad.cpp b/Naad.cpp new file mode 100644 index 0000000..8b8b418 --- /dev/null +++ b/Naad.cpp @@ -0,0 +1,73 @@ +// Naadh.cpp : Defines the class behaviors for the application. +// + +#include "stdafx.h" +#include "Naadh.h" +#include "NaadhDlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + + +// CNaadhApp + +BEGIN_MESSAGE_MAP(CNaadhApp, CWinApp) + ON_COMMAND(ID_HELP, CWinApp::OnHelp) +END_MESSAGE_MAP() + + +// CNaadhApp construction + +CNaadhApp::CNaadhApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + + +// The one and only CNaadhApp object + +CNaadhApp theApp; + + +// CNaadhApp initialization + +BOOL CNaadhApp::InitInstance() +{ + // InitCommonControls() is required on Windows XP if an application + // manifest specifies use of ComCtl32.dll version 6 or later to enable + // visual styles. Otherwise, any window creation will fail. + InitCommonControls(); + + CWinApp::InitInstance(); + + AfxEnableControlContainer(); + + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need + // Change the registry key under which our settings are stored + // TODO: You should modify this string to be something appropriate + // such as the name of your company or organization + SetRegistryKey(_T("Local AppWizard-Generated Applications")); + + CNaadhDlg dlg; + m_pMainWnd = &dlg; + INT_PTR nResponse = dlg.DoModal(); + if (nResponse == IDOK) + { + // TODO: Place code here to handle when the dialog is + // dismissed with OK + } + else if (nResponse == IDCANCEL) + { + // TODO: Place code here to handle when the dialog is + // dismissed with Cancel + } + + // Since the dialog has been closed, return FALSE so that we exit the + // application, rather than start the application's message pump. + return FALSE; +} diff --git a/Naad.rc b/Naad.rc new file mode 100644 index 0000000..4245722 --- /dev/null +++ b/Naad.rc @@ -0,0 +1,649 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "#define _AFX_NO_SPLITTER_RESOURCES\r\n" + "#define _AFX_NO_OLE_RESOURCES\r\n" + "#define _AFX_NO_TRACKER_RESOURCES\r\n" + "#define _AFX_NO_PROPERTY_RESOURCES\r\n" + "\r\n" + "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n" + "LANGUAGE 9, 1\r\n" + "#pragma code_page(1252)\r\n" + "#include ""res\\Naadh.rc2"" // non-Microsoft Visual C++ edited resources\r\n" + "#include ""afxres.rc"" // Standard components\r\n" + "#endif\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDR_MAINFRAME ICON "res\\Naad.ico" + +IDR_ICON1 ICON "res\\idr_main.ico" + +IDI_ICON1 ICON "res\\icon1.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUTBOX DIALOGEX 0, 0, 235, 62 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About Naad" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + CTEXT "Naad Version 1.0",IDC_STATIC,38,16,167,15,SS_NOPREFIX | SS_CENTERIMAGE | WS_BORDER + DEFPUSHBUTTON "OK",IDOK,93,39,50,16,WS_GROUP + ICON IDR_MAINFRAME,IDC_STATIC,7,14,21,20 +END + +IDD_NAADH_DIALOG DIALOGEX 0, 0, 610, 316 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_APPWINDOW +CAPTION "Naad" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + DEFPUSHBUTTON "Play >",IDC_BUTTON_PLAY,126,264,71,16 + PUSHBUTTON "Stop",IDC_BUTTON_STOP,412,264,71,16 + CONTROL "",IDC_SLIDER_TEMPO,"msctls_trackbar32",TBS_AUTOTICKS | TBS_BOTH | WS_TABSTOP,14,188,180,22 + PUSHBUTTON "Exit",IDOK,532,262,71,16,NOT WS_VISIBLE + LTEXT "Static",IDC_STATIC_MSG,7,289,294,10,SS_SUNKEN + CONTROL "Custom1",IDC_LIST,"CMultilineList",WS_TABSTOP,7,6,596,127 + GROUPBOX "Tempo or Gati",IDC_STATIC,7,176,190,82 + CTEXT "Madhya",IDC_STATIC,86,213,32,8 + CTEXT "Vilambit",IDC_STATIC,14,213,32,8 + CTEXT "Drut",IDC_STATIC,158,213,32,8 + GROUPBOX "Timing Variation and Randomness",IDC_STATIC,211,179,190,78 + CONTROL "",IDC_SLIDER_RAND,"msctls_trackbar32",TBS_AUTOTICKS | TBS_BOTH | WS_TABSTOP,217,191,180,22 + CTEXT "Too Perfect",IDC_STATIC,222,217,39,8 + CTEXT "Natural",IDC_STATIC,289,217,39,8 + CTEXT "Imperfect",IDC_STATIC,356,217,39,8 + LTEXT "Static",IDC_STATIC_FILE,309,289,294,10,SS_SUNKEN + CONTROL "Tanpura",IDC_CHECK_ACC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,224,154,43,12 + GROUPBOX "Composition",IDC_STATIC,7,139,190,34 + CONTROL "Stereo",IDC_CHECK_STEREO,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED | WS_TABSTOP,7,258,41,9 + CONTROL "Echo",IDC_CHECK_ECHO,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED | WS_TABSTOP,7,268,41,9 + CONTROL "Test Test",IDC_CHECK_RNDBOL,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,7,276,45,12 + CONTROL "",IDC_SLIDER_BOLVAR,"msctls_trackbar32",TBS_AUTOTICKS | TBS_BOTH | WS_TABSTOP,417,151,180,22 + GROUPBOX "Bol Variety",IDC_STATIC,413,139,190,118 + CTEXT "Medium",IDC_STATIC,493,176,32,8 + CTEXT "Narrow",IDC_STATIC,421,176,32,8 + CTEXT "Wide",IDC_STATIC,565,176,32,8 + GROUPBOX "Accompaniments",IDC_STATIC,210,139,190,34 + CONTROL "Lehra",IDC_CHECK_ACC2,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,279,155,34,12 + CONTROL "Ghungru at Sam",IDC_CHECK_SAM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,328,157,67,9 + PUSHBUTTON "Replace the original",IDC_BUTTON_SAVEVAR,425,236,71,16 + CONTROL "Use Same Species",IDC_CHECK_VARSAME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,519,203,74,12 + CONTROL "Use Any Species",IDC_CHECK_VARANY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,519,215,74,12 + PUSHBUTTON "1 X",IDC_BUTTON_GUN1,152,230,35,16 + CONTROL "Affect Composition",IDC_CHECK_VARCOMP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,425,203,74,12 + CONTROL "Affect Current Loop",IDC_CHECK_VARLOOP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,425,215,82,12 + PUSHBUTTON "Auto Compose",IDC_BUTTON_AUTOCOMPOSE,18,151,71,16 + EDITTEXT IDC_EDIT_TEMPO,14,224,127,25,ES_MULTILINE | ES_AUTOHSCROLL | WS_DISABLED | NOT WS_BORDER + EDITTEXT IDC_EDIT_TEMPOVAR,225,229,165,8,ES_CENTER | ES_AUTOHSCROLL | WS_DISABLED | NOT WS_BORDER + EDITTEXT IDC_EDIT_BOLVAR,426,189,165,8,ES_CENTER | ES_AUTOHSCROLL | WS_DISABLED | NOT WS_BORDER + PUSHBUTTON "Play Loop >",IDC_BUTTON_PLAYLOOP,269,264,71,16 + PUSHBUTTON "Restore the original",IDC_BUTTON_RESVAR,519,236,71,16,NOT WS_VISIBLE +END + +IDD_DIALOG_ABT DIALOGEX 0, 0, 394, 192 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION +CAPTION "About Naad" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "Close",IDOK,7,171,380,14,BS_FLAT + LTEXT "Static",IDC_STATIC_ABT,7,7,380,158 +END + +IDD_DIALOG_PROPCOMP DIALOGEX 0, 0, 300, 170 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Composition Properties" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + EDITTEXT IDC_EDIT_COMPNAME,51,7,242,13,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_COMPOSER,51,27,242,13,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_COMPNOTES,7,63,286,72,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN + PUSHBUTTON "Apply",IDOK,243,149,50,14 + PUSHBUTTON "Cancel",IDCANCEL,7,149,50,14 + LTEXT "Name :",IDC_STATIC,7,7,32,13 + LTEXT "Composer :",IDC_STATIC,7,29,43,13 + LTEXT "Notes :",IDC_STATIC,7,50,32,13 +END + +IDD_DIALOG_PROPLOOP DIALOGEX 0, 0, 300, 205 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Loop Properties" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + EDITTEXT IDC_EDIT_LOOPNAME,73,7,220,12,ES_AUTOHSCROLL + COMBOBOX IDC_COMBO_MATRA,73,29,58,130,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + EDITTEXT IDC_EDIT_REPEAT,73,79,58,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_DELAY,73,97,58,12,ES_AUTOHSCROLL + COMBOBOX IDC_COMBO_ACC,73,116,126,130,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + EDITTEXT IDC_EDIT_LOOPNOTES,73,137,220,42,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL + PUSHBUTTON "Apply",IDOK,243,184,50,14 + PUSHBUTTON "Cancel",IDCANCEL,7,184,50,14 + LTEXT "Name :",IDC_STATIC,7,9,32,11 + LTEXT "1 Maatra is : ",IDC_STATIC,7,32,45,8 + CTEXT "Bols",IDC_STATIC,144,30,18,8 + LTEXT "Accompaniment :",IDC_STATIC,7,121,63,8 + LTEXT "Repeat :",IDC_STATIC,7,81,32,11 + CTEXT "Times",IDC_STATIC,137,80,18,8 + LTEXT "Notes :",IDC_STATIC,7,140,32,11 + LTEXT "Tempo :",IDC_STATIC,7,100,32,11 + CONTROL "Start just after the last loop",IDC_CHECK_B2B,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED | WS_TABSTOP,188,99,103,9 + LTEXT "Maatras : ",IDC_STATIC,7,56,45,8 + EDITTEXT IDC_EDIT_MAATRAS,73,52,58,12,ES_AUTOHSCROLL | WS_DISABLED + LTEXT "BPM",IDC_STATIC,137,99,39,8 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,0 + PRODUCTVERSION 1,0,0,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "Oormi Creations" + VALUE "FileDescription", "Naad Tabla Composer" + VALUE "FileVersion", "1.0.0.0" + VALUE "InternalName", "Naad.exe" + VALUE "LegalCopyright", "(c) Oormi Creations. All rights reserved." + VALUE "OriginalFilename", "Naad.exe" + VALUE "ProductName", "Naad" + VALUE "ProductVersion", "1.0.0.0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_ABOUTBOX, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 228 + TOPMARGIN, 7 + BOTTOMMARGIN, 55 + END + + IDD_NAADH_DIALOG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 603 + TOPMARGIN, 6 + BOTTOMMARGIN, 299 + END + + IDD_DIALOG_ABT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 387 + TOPMARGIN, 7 + BOTTOMMARGIN, 185 + END + + IDD_DIALOG_PROPCOMP, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 293 + TOPMARGIN, 7 + BOTTOMMARGIN, 163 + END + + IDD_DIALOG_PROPLOOP, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 293 + TOPMARGIN, 7 + BOTTOMMARGIN, 198 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MENU1 MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "New &Composition", ID_FILE_NEWCOMPOSITION + MENUITEM "Add &Loop", ID_FILE_NEWTAAL + MENUITEM SEPARATOR + MENUITEM "&Open Composition", ID_FILE_OPEN32773 + MENUITEM SEPARATOR + MENUITEM "&Save", ID_FILE_SAVE32774 + MENUITEM "Save &As", ID_FILE_SAVEAS + MENUITEM SEPARATOR + MENUITEM "E&xit", ID_FILE_EXIT + END + POPUP "&Edit" + BEGIN + MENUITEM "&Select", ID_EDIT_SELECT + MENUITEM "&Copy", ID_EDIT_COPY32956 + MENUITEM "Cu&t", ID_EDIT_CUT32957 + MENUITEM "&Paste", ID_EDIT_PASTE32958 + MENUITEM "Clea&r", ID_EDIT_CLEAR32974 + END + POPUP "&View" + BEGIN + MENUITEM "&Composition Properties", ID_VIEW_COMPOSITION + MENUITEM "&Loop Properties", ID_VIEW_LOOP + END + POPUP "&Instrument" + BEGIN + MENUITEM "&Tabla", ID_INSTRUMENT_TABLA + MENUITEM "&Dholak", ID_INSTRUMENT_DHOLAK, GRAYED + MENUITEM "&Pakhawaj", ID_INSTRUMENT_PAKHAWAJ, GRAYED + MENUITEM "&Mridangam", ID_INSTRUMENT_MRIDANGAM, GRAYED + MENUITEM "D&hapli", ID_INSTRUMENT_DHAPLI, GRAYED + MENUITEM "D&rums", ID_INSTRUMENT_D, GRAYED + MENUITEM "&Conga", ID_INSTRUMENT_CONGO, GRAYED + END + POPUP "&Accompaniment" + BEGIN + POPUP "Taanpura" + BEGIN + MENUITEM "&1. Tanpura (Sa Pa) in G", ID_ACCOMPANIMENT_TANPURA + MENUITEM "&2. Tanpura (Sa Pa) in C", ID_ACCOMPANIMENT_2, GRAYED + MENUITEM "&3. Tanpura (Sa Ma) in G", ID_ACCOMPANIMENT_3, GRAYED + MENUITEM "&4. Tanpura (Sa Ma) in C", ID_ACCOMPANIMENT_4, GRAYED + END + POPUP "Organ" + BEGIN + MENUITEM "&1. Organ (Sa Ma) in G", ID_ACCOMPANIMENT_7, GRAYED + MENUITEM "&2. Organ (Sa Ma) in C", ID_ACCOMPANIMENT_8, GRAYED + MENUITEM "&3. Organ (Sa Pa) in C", ID_ACCOMPANIMENT_6, GRAYED + MENUITEM "&4. Organ (Sa Pa) in G", ID_ACCOMPANIMENT_5, GRAYED + END + POPUP "Ghungru" + BEGIN + MENUITEM "&1. Ghungru 01", ID_GHUNGRU_GHUNGRU01 + MENUITEM "&2. Ghungru 02", ID_GHUNGRU_GHUNGRU02 + MENUITEM "&3. Ghungru 03", ID_GHUNGRU_GHUNGRU03 + MENUITEM "&4. Ghungru 04", ID_GHUNGRU_GHUNGRU04 + MENUITEM "&5. Ghungru 05", ID_GHUNGRU_GHUNGRU05 + MENUITEM "&6. Ghungru 06", ID_GHUNGRU_GHUNGRU06, GRAYED + END + END + POPUP "&Options" + BEGIN + MENUITEM "&Settings", ID_OPTIONS_SETTINGS + MENUITEM "&Bol Folder", ID_OPTIONS_BOLFOLDER + MENUITEM "&Play All Samples", ID_OPTIONS_PLAYALLSAMPLES + END + POPUP "&Help" + BEGIN + MENUITEM "Naad &Help", ID_HELP_NAADHHELP + MENUITEM SEPARATOR + MENUITEM "Check for &Updates", ID_HELP_CHECKFORUPDATES + MENUITEM SEPARATOR + MENUITEM "&About Naad", ID_HELP_ABOUTNAADH + MENUITEM "&Contact", ID_HELP_CONTACT + END +END + +IDR_MENU2 MENU +BEGIN + POPUP "Bols" + BEGIN + MENUITEM "<- View Composition", ID_BOLS_VIEWCOMP + MENUITEM SEPARATOR + POPUP "> Dayan" + BEGIN + POPUP "Na" + BEGIN + MENUITEM "Na01", ID_NA_NA01 + MENUITEM "Na02", ID_NA_NA02 + MENUITEM "Na03", ID_NA_NA03 + MENUITEM "Na04", ID_NA_NA04 + MENUITEM "Na05", ID_NA_NA05 + MENUITEM "Na06", ID_NA_NA06 + MENUITEM "Na07", ID_NA_NA07 + MENUITEM "Na08", ID_NA_NA08 + MENUITEM "Na09", ID_NA_NA09 + MENUITEM "Na10", ID_NA_NA10 + END + POPUP "Ta" + BEGIN + MENUITEM "Ta01", ID_TA_TA01 + MENUITEM "Ta02", ID_TA_TA02 + MENUITEM "Ta03", ID_TA_TA03 + MENUITEM "Ta04", ID_TA_TA04 + MENUITEM "Ta05", ID_TA_TA05 + MENUITEM "Ta06", ID_TA_TA06 + MENUITEM "Ta07", ID_TA_TA07 + MENUITEM "Ta08", ID_TA_TA08 + MENUITEM "Ta09", ID_TA_TA09 + MENUITEM "Ta10", ID_TA_TA10 + END + POPUP "Ti" + BEGIN + MENUITEM "Ti01", ID_TI_TI01 + MENUITEM "Ti02", ID_TI_TI02 + MENUITEM "Ti03", ID_TI_TI03 + MENUITEM "Ti04", ID_TI_TI04 + MENUITEM "Ti05", ID_TI_TI05 + MENUITEM "Ti06", ID_TI_TI06 + MENUITEM "Ti07", ID_TI_TI07 + MENUITEM "Ti08", ID_TI_TI08 + MENUITEM "Ti09", ID_TI_TI09 + MENUITEM "Ti10", ID_TI_TI10 + END + POPUP "Tin" + BEGIN + MENUITEM "Tin01", ID_TIN_TIN01 + MENUITEM "Tin02", ID_TIN_TIN02 + MENUITEM "Tin03", ID_TIN_TIN03 + MENUITEM "Tin04", ID_TIN_TIN04 + MENUITEM "Tin05", ID_TIN_TIN05 + MENUITEM "Tin06", ID_TIN_TIN06 + MENUITEM "Tin07", ID_TIN_TIN07 + MENUITEM "Tin08", ID_TIN_TIN08 + MENUITEM "Tin09", ID_TIN_TIN09 + MENUITEM "Tin10", ID_TIN_TIN10 + END + POPUP "Tun" + BEGIN + MENUITEM "Tun01", ID_TUN_TUN01 + MENUITEM "Tun02", ID_TUN_TUN02 + MENUITEM "Tun03", ID_TUN_TUN03 + MENUITEM "Tun04", ID_TUN_TUN04 + MENUITEM "Tun05", ID_TUN_TUN05 + MENUITEM "Tun06", ID_TUN_TUN06 + MENUITEM "Tun07", ID_TUN_TUN07 + MENUITEM "Tun08", ID_TUN_TUN08 + MENUITEM "Tun09", ID_TUN_TUN09 + MENUITEM "Tun10", ID_TUN_TUN10 + END + END + POPUP "< Bayan" + BEGIN + POPUP "Dha" + BEGIN + MENUITEM "Dha01", ID_DHA_DHA01 + MENUITEM "Dha02", ID_DHA_DHA02 + MENUITEM "Dha03", ID_DHA_DHA03 + MENUITEM "Dha04", ID_DHA_DHA04 + MENUITEM "Dha05", ID_DHA_DHA05 + MENUITEM "Dha06", ID_DHA_DHA06 + MENUITEM "Dha07", ID_DHA_DHA07 + MENUITEM "Dha08", ID_DHA_DHA08 + MENUITEM "Dha09", ID_DHA_DHA09 + MENUITEM "Dha10", ID_DHA_DHA10 + END + POPUP "Dhin" + BEGIN + MENUITEM "Dhin01", ID_DHIN_DHIN01 + MENUITEM "Dhin02", ID_DHIN_DHIN02 + MENUITEM "Dhin03", ID_DHIN_DHIN03 + MENUITEM "Dhin04", ID_DHIN_DHIN04 + MENUITEM "Dhin05", ID_DHIN_DHIN05 + MENUITEM "Dhin06", ID_DHIN_DHIN06 + MENUITEM "Dhin07", ID_DHIN_DHIN07 + MENUITEM "Dhin08", ID_DHIN_DHIN08 + MENUITEM "Dhin09", ID_DHIN_DHIN09 + MENUITEM "Dhin10", ID_DHIN_DHIN10 + END + POPUP "Dhit" + BEGIN + MENUITEM "Dhit01", ID_DHIT_DHIT01 + MENUITEM "Dhit02", ID_DHIT_DHIT02 + MENUITEM "Dhit03", ID_DHIT_DHIT03 + MENUITEM "Dhit04", ID_DHIT_DHIT04 + MENUITEM "Dhit05", ID_DHIT_DHIT05 + MENUITEM "Dhit06", ID_DHIT_DHIT06 + MENUITEM "Dhit07", ID_DHIT_DHIT07 + MENUITEM "Dhit08", ID_DHIT_DHIT08 + MENUITEM "Dhit09", ID_DHIT_DHIT09 + MENUITEM "Dhit10", ID_DHIT_DHIT10 + END + POPUP "Dhun" + BEGIN + MENUITEM "Dhun01", ID_DHUN_DHUN01 + MENUITEM "Dhun02", ID_DHUN_DHUN02 + MENUITEM "Dhun03", ID_DHUN_DHUN03 + MENUITEM "Dhun04", ID_DHUN_DHUN04 + MENUITEM "Dhun05", ID_DHUN_DHUN05 + MENUITEM "Dhun06", ID_DHUN_DHUN06 + MENUITEM "Dhun07", ID_DHUN_DHUN07 + MENUITEM "Dhun08", ID_DHUN_DHUN08 + MENUITEM "Dhun09", ID_DHUN_DHUN09 + MENUITEM "Dhun10", ID_DHUN_DHUN10 + END + POPUP "Ga" + BEGIN + MENUITEM "Ga01", ID_GA_GA01 + MENUITEM "Ga02", ID_GA_GA02 + MENUITEM "Ga03", ID_GA_GA03 + MENUITEM "Ga04", ID_GA_GA04 + MENUITEM "Ga05", ID_GA_GA05 + MENUITEM "Ga06", ID_GA_GA06 + MENUITEM "Ga07", ID_GA_GA07 + MENUITEM "Ga08", ID_GA_GA08 + MENUITEM "Ga09", ID_GA_GA09 + MENUITEM "Ga10", ID_GA_GA10 + END + POPUP "Ge" + BEGIN + MENUITEM "Ge01", ID_GE_GE01 + MENUITEM "Ge02", ID_GE_GE02 + MENUITEM "Ge03", ID_GE_GE03 + MENUITEM "Ge04", ID_GE_GE04 + MENUITEM "Ge05", ID_GE_GE05 + MENUITEM "Ge06", ID_GE_GE06 + MENUITEM "Ge07", ID_GE_GE07 + MENUITEM "Ge08", ID_GE_GE08 + MENUITEM "Ge09", ID_GE_GE09 + MENUITEM "Ge10", ID_GE_GE10 + END + POPUP "Ke" + BEGIN + MENUITEM "Ke01", ID_KE_KE01 + MENUITEM "Ke02", ID_KE_KE02 + MENUITEM "Ke03", ID_KE_KE03 + MENUITEM "Ke04", ID_KE_KE04 + MENUITEM "Ke05", ID_KE_KE05 + MENUITEM "Ke06", ID_KE_KE06 + MENUITEM "Ke07", ID_KE_KE07 + MENUITEM "Ke08", ID_KE_KE08 + MENUITEM "Ke09", ID_KE_KE09 + MENUITEM "Ke10", ID_KE_KE10 + END + END + POPUP "<> Pieces" + BEGIN + MENUITEM "DhaGeTiTa", ID__DHAGETITA + MENUITEM "DhaGeTuNa", ID__DHAGETUNA + MENUITEM "GaDhiGeNa", ID__GADHIGENA + MENUITEM "TiRaKeTaDha", ID__TIRAKETADHA + END + MENUITEM SEPARATOR + MENUITEM "~o~ Silence", ID_BOLS_SILENCE + MENUITEM SEPARATOR + MENUITEM "~S~ Sam", ID_BOLS_SAM + MENUITEM "~T~ Tali", ID_BOLS_TALI + MENUITEM "~K~ Khali", ID_BOLS_KHALI + MENUITEM SEPARATOR + MENUITEM "X Clear", ID_BOLS_CLEAR32792 + END +END + +IDR_MENU3 MENU +BEGIN + POPUP "Loop" + BEGIN + MENUITEM "-> Open", ID_LOOP_OPEN + MENUITEM "+ Properties", ID_LOOP_PROPERTIES + MENUITEM SEPARATOR + MENUITEM "^ Load Loop", ID_LOOP_LOADLOOP + MENUITEM "^ Save Loop", ID_LOOP_SAVELOOP + MENUITEM SEPARATOR + MENUITEM "X Clear", ID_LOOP_CLEAR + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog Info +// + +IDD_DIALOG_PROPLOOP DLGINIT +BEGIN + IDC_COMBO_MATRA, 0x403, 2, 0 +0x0031, + IDC_COMBO_MATRA, 0x403, 2, 0 +0x0032, + IDC_COMBO_MATRA, 0x403, 2, 0 +0x0033, + IDC_COMBO_MATRA, 0x403, 2, 0 +0x0034, + IDC_COMBO_MATRA, 0x403, 2, 0 +0x0035, + IDC_COMBO_MATRA, 0x403, 2, 0 +0x0036, + IDC_COMBO_MATRA, 0x403, 2, 0 +0x0037, + IDC_COMBO_MATRA, 0x403, 2, 0 +0x0038, + IDC_COMBO_ACC, 0x403, 5, 0 +0x6f4e, 0x656e, "\000" + IDC_COMBO_ACC, 0x403, 8, 0 +0x6154, 0x706e, 0x7275, 0x0061, + 0 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// AFX_DIALOG_LAYOUT +// + +IDD_ABOUTBOX AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IDD_DIALOG_ABT AFX_DIALOG_LAYOUT +BEGIN + 0 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_ABOUTBOX "&About Naad" + IDS_UPDATE_AVAILABLE "You are currently using version %u.%u\r\nThe newest version %u.%u is available online for free.\r\nDo you wish to download it now ?" + IDS_UPDATE_NO "No Updates are available.\r\nThis is the latest version." + IDS_UPDATE_NOCHECK "Unable to check for updates." + IDS_UPDATE "http://oormi.in/software/updatenaad.txt" +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#define _AFX_NO_SPLITTER_RESOURCES +#define _AFX_NO_OLE_RESOURCES +#define _AFX_NO_TRACKER_RESOURCES +#define _AFX_NO_PROPERTY_RESOURCES + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE 9, 1 +#pragma code_page(1252) +#include "res\Naad.rc2" // non-Microsoft Visual C++ edited resources +#include "afxres.rc" // Standard components +#endif + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Naad.sln b/Naad.sln new file mode 100644 index 0000000..6a2d353 --- /dev/null +++ b/Naad.sln @@ -0,0 +1,22 @@ +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Naadh", "Naadh.vcxproj", "{2CF1DEDB-2800-477F-8FC2-0E24A1B56EA4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + Template|Win32 = Template|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2CF1DEDB-2800-477F-8FC2-0E24A1B56EA4}.Debug|Win32.ActiveCfg = Debug|Win32 + {2CF1DEDB-2800-477F-8FC2-0E24A1B56EA4}.Debug|Win32.Build.0 = Debug|Win32 + {2CF1DEDB-2800-477F-8FC2-0E24A1B56EA4}.Release|Win32.ActiveCfg = Release|Win32 + {2CF1DEDB-2800-477F-8FC2-0E24A1B56EA4}.Release|Win32.Build.0 = Release|Win32 + {2CF1DEDB-2800-477F-8FC2-0E24A1B56EA4}.Template|Win32.ActiveCfg = Template|Win32 + {2CF1DEDB-2800-477F-8FC2-0E24A1B56EA4}.Template|Win32.Build.0 = Template|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/NaadDlg.cpp b/NaadDlg.cpp new file mode 100644 index 0000000..7d9dec4 --- /dev/null +++ b/NaadDlg.cpp @@ -0,0 +1,2535 @@ +// NaadhDlg.cpp : implementation file +// + +#include "stdafx.h" +#include "Naadh.h" +#include "NaadhDlg.h" +#include "mmsystem.h" +#include "AboutNaadDlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + + +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + enum { IDD = IDD_ABOUTBOX }; + + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + +// Implementation +protected: + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) +END_MESSAGE_MAP() + + +// CNaadhDlg dialog + + + +CNaadhDlg::CNaadhDlg(CWnd* pParent /*=NULL*/) + : CDialog(CNaadhDlg::IDD, pParent) +{ + m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); +} + +void CNaadhDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_LIST, m_List); + DDX_Control(pDX, IDC_SLIDER_TEMPO, m_TempoSliderCtrl); + DDX_Control(pDX, IDC_SLIDER_RAND, m_RandSliderCtrl); + DDX_Control(pDX, IDC_SLIDER_BOLVAR, m_BolVarSliderCtrl); +} + +BEGIN_MESSAGE_MAP(CNaadhDlg, CDialog) + ON_WM_SYSCOMMAND() + ON_WM_PAINT() + ON_WM_QUERYDRAGICON() + ON_WM_TIMER () + ON_WM_HSCROLL() + ON_COMMAND(ID_FILE_EXIT, OnFileExit) + ON_COMMAND(ID_HELP_ABOUTNAADH, OnHelpAboutnaadh) + ON_COMMAND(ID_HELP_CHECKFORUPDATES, OnHelpCheckforupdates) + ON_COMMAND(ID_FILE_OPEN32773, OnFileOpen32773) + ON_COMMAND(ID_FILE_SAVE32774, OnFileSave32774) + ON_COMMAND(ID_FILE_SAVEAS, OnFileSaveas) + ON_COMMAND(ID_BOLS_CLEAR32792, OnBolsClear32792) + ON_COMMAND(ID_BOLS_SILENCE, OnBolsSilence) + ON_COMMAND(ID_FILE_NEWTAAL, OnFileNewtaal) + ON_BN_CLICKED(IDC_BUTTON_PLAY, OnBnClickedButtonPlay) + ON_BN_CLICKED(IDC_BUTTON_STOP, OnBnClickedButtonStop) + ON_BN_CLICKED(IDC_CHECK_ACC, OnBnClickedCheckAcc) + ON_BN_CLICKED(IDC_CHECK_RNDBOL, OnBnClickedCheckRndbol) + ON_WM_MENUSELECT() + ON_COMMAND(ID_OPTIONS_PLAYALLSAMPLES, OnOptionsPlayallsamples) + ON_CONTROL_RANGE(BN_CLICKED,ID_NA_NA01,ID_KE_KE10, OnSelectBol) + ON_COMMAND(ID_BOLS_SAM, OnBolsSam) + ON_COMMAND(ID_BOLS_TALI, OnBolsTali) + ON_COMMAND(ID_BOLS_KHALI, OnBolsKhali) + ON_BN_CLICKED(IDC_CHECK_SAM, OnBnClickedCheckSam) + ON_COMMAND(ID_OPTIONS_BOLFOLDER, OnOptionsBolfolder) + ON_COMMAND(ID_HELP_CONTACT, OnHelpContact) + ON_COMMAND(ID_HELP_NAADHHELP, OnHelpNaadhhelp) + ON_COMMAND(ID_FILE_NEWCOMPOSITION, OnFileNewcomposition) + ON_COMMAND(ID_LOOP_OPEN, OnLoopOpen) + ON_COMMAND(ID_VIEW_COMPOSITION, OnViewComposition) + ON_COMMAND(ID_LOOP_CLEAR, OnLoopClear) + ON_COMMAND(ID_BOLS_VIEWCOMP, OnBolsViewcomp) + ON_COMMAND(ID_LOOP_PROPERTIES, OnLoopProperties) + ON_COMMAND(ID_VIEW_LOOP, OnViewLoop) + ON_BN_CLICKED(IDC_CHECK_ECHO, &CNaadhDlg::OnBnClickedCheckEcho) + ON_BN_CLICKED(IDOK, &CNaadhDlg::OnBnClickedOk) + ON_COMMAND(ID_GHUNGRU_GHUNGRU01, &CNaadhDlg::OnGhungruGhungru01) + ON_COMMAND(ID_GHUNGRU_GHUNGRU02, &CNaadhDlg::OnGhungruGhungru02) + ON_COMMAND(ID_GHUNGRU_GHUNGRU03, &CNaadhDlg::OnGhungruGhungru03) + ON_COMMAND(ID_GHUNGRU_GHUNGRU04, &CNaadhDlg::OnGhungruGhungru04) + ON_COMMAND(ID_GHUNGRU_GHUNGRU05, &CNaadhDlg::OnGhungruGhungru05) + ON_COMMAND(ID_GHUNGRU_GHUNGRU06, &CNaadhDlg::OnGhungruGhungru06) + ON_COMMAND(ID_ACCOMPANIMENT_TANPURA, &CNaadhDlg::OnAccompanimentTanpura) + ON_COMMAND(ID_ACCOMPANIMENT_2, &CNaadhDlg::OnAccompaniment2) + ON_COMMAND(ID_ACCOMPANIMENT_3, &CNaadhDlg::OnAccompaniment3) + ON_COMMAND(ID_ACCOMPANIMENT_4, &CNaadhDlg::OnAccompaniment4) + ON_BN_CLICKED(IDC_CHECK_VARSAME, &CNaadhDlg::OnBnClickedCheckVarsame) + ON_BN_CLICKED(IDC_CHECK_VARANY, &CNaadhDlg::OnBnClickedCheckVarany) + ON_BN_CLICKED(IDC_BUTTON_SAVEVAR, &CNaadhDlg::OnBnClickedButtonSavevar) + ON_BN_CLICKED(IDC_CHECK_VARCOMP, &CNaadhDlg::OnBnClickedCheckVarcomp) + ON_BN_CLICKED(IDC_CHECK_VARLOOP, &CNaadhDlg::OnBnClickedCheckVarloop) + ON_BN_CLICKED(IDC_BUTTON_AUTOCOMPOSE, &CNaadhDlg::OnBnClickedButtonAutocompose) + ON_BN_CLICKED(IDC_BUTTON_PLAYLOOP, &CNaadhDlg::OnBnClickedButtonPlayloop) + ON_BN_CLICKED(IDC_BUTTON_GUN1, &CNaadhDlg::OnBnClickedButtonGun1) + //ON_BN_CLICKED(IDC_BUTTON_GUN2, &CNaadhDlg::OnBnClickedButtonGun2) + //ON_BN_CLICKED(IDC_BUTTON_GUN3, &CNaadhDlg::OnBnClickedButtonGun3) + //ON_BN_CLICKED(IDC_BUTTON_GUN4, &CNaadhDlg::OnBnClickedButtonGun4) + ON_COMMAND(ID_LOOP_LOADLOOP, &CNaadhDlg::OnLoopLoadloop) + ON_COMMAND(ID_LOOP_SAVELOOP, &CNaadhDlg::OnLoopSaveloop) + ON_COMMAND(ID_EDIT_SELECT, &CNaadhDlg::OnEditSelect) + ON_COMMAND(ID_EDIT_CLEAR32974, &CNaadhDlg::OnEditClear32974) + ON_COMMAND(ID_EDIT_COPY32956, &CNaadhDlg::OnEditCopy32956) + ON_COMMAND(ID_EDIT_CUT32957, &CNaadhDlg::OnEditCut32957) + ON_COMMAND(ID_EDIT_PASTE32958, &CNaadhDlg::OnEditPaste32958) +END_MESSAGE_MAP() + + +// CNaadhDlg message handlers + +BOOL CNaadhDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + + // Add "About..." menu item to system menu. + + // IDM_ABOUTBOX must be in the system command range. + ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); + ASSERT(IDM_ABOUTBOX < 0xF000); + + CMenu* pSysMenu = GetSystemMenu(FALSE); + if (pSysMenu != NULL) + { + CString strAboutMenu; + strAboutMenu.LoadString(IDS_ABOUTBOX); + if (!strAboutMenu.IsEmpty()) + { + pSysMenu->AppendMenu(MF_SEPARATOR); + pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); + } + } + + // Set the icon for this dialog. The framework does this automatically + // when the application's main window is not a dialog + SetIcon(m_hIcon, TRUE); // Set big icon + SetIcon(m_hIcon, FALSE); // Set small icon + + // TODO: Add extra initialization here + m_Menu.LoadMenu(IDR_MENU1); + SetMenu(&m_Menu); + m_BolMenu.LoadMenu(IDR_MENU2); + m_LoopMenu.LoadMenu(IDR_MENU3); + + m_Quiet = TRUE; + m_IsInstalled = FALSE; + m_IsShellOpen = FALSE; + m_IsBolLoaded = FALSE; + m_Version = VERSION; + + m_Mesg.Format("%.1f", (float)VERSION/10.0); + m_Mesg = " Naad - Version " + m_Mesg + ", " + VERMONTH; + this->SetDlgItemText(IDC_STATIC_MSG, m_Mesg); + + // get the app path. + char strPathName[_MAX_PATH]; + ::GetModuleFileName(NULL, strPathName, _MAX_PATH); + + CString newPath(strPathName); + CString t(strPathName); + + int fpos = newPath.ReverseFind('\\'); + if (fpos != -1) newPath = newPath.Left(fpos + 1); + m_AppPath = newPath; + + LoadSettings(); + if(!m_IsInstalled) + { + AssociateFileType(".nad", t , "NaadFile", "Naad File", t+",1"); + AssociateFileType(".nlp", t , "NaadLoopFile", "Naad Loop File", t+",2"); + m_IsInstalled = true; + SaveSettings(); + } + +#ifndef _DEBUG + OnHelpCheckforupdates(); +#endif + + m_Quiet = FALSE; + m_Saved = TRUE; + + m_List.SetSize(MC,MR); + m_List.m_IsMarkable = TRUE; + + m_TempoSliderCtrl.SetRange(-MAXBPM, MAXBPM); + m_TempoSliderCtrl.SetTicFreq(MAXBPM/10); + + m_RandSliderCtrl.SetRange(0,30); + m_RandSliderCtrl.SetTicFreq(2); + + m_BolVarSliderCtrl.SetRange(0,100); + m_BolVarSliderCtrl.SetTicFreq(5); + //UpdateTempo(); + + LoadBolWaves(); + + m_Menu.CheckMenuItem(ID_INSTRUMENT_TABLA, MF_CHECKED|MF_BYCOMMAND); + m_Menu.CheckMenuItem(ID_ACCOMPANIMENT_TANPURA, MF_CHECKED|MF_BYCOMMAND); + m_Menu.CheckMenuItem(ID_GHUNGRU_GHUNGRU01, MF_CHECKED|MF_BYCOMMAND); + + Reset(); + + //get the command line + CCommandLineInfo cinfo; + theApp.ParseCommandLine(cinfo); + m_NaadhFileName = cinfo.m_strFileName; + if(!m_NaadhFileName.IsEmpty()) + { + m_IsShellOpen = TRUE; + OnFileOpen32773(); + m_IsShellOpen = FALSE; + } + else + { + OnFileNewcomposition(); + } + + + return TRUE; // return TRUE unless you set the focus to a control +} + +void CNaadhDlg::OnSysCommand(UINT nID, LPARAM lParam) +{ + if ((nID & 0xFFF0) == IDM_ABOUTBOX) + { + CAboutDlg dlgAbout; + dlgAbout.DoModal(); + } + else if ((nID & 0xFFF0) == SC_CLOSE) + { + OnFileExit(); + } + else + { + CDialog::OnSysCommand(nID, lParam); + } +} + +// If you add a minimize button to your dialog, you will need the code below +// to draw the icon. For MFC applications using the document/view model, +// this is automatically done for you by the framework. + +void CNaadhDlg::OnPaint() +{ + if (IsIconic()) + { + CPaintDC dc(this); // device context for painting + + SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0); + + // Center icon in client rectangle + int cxIcon = GetSystemMetrics(SM_CXICON); + int cyIcon = GetSystemMetrics(SM_CYICON); + CRect rect; + GetClientRect(&rect); + int x = (rect.Width() - cxIcon + 1) / 2; + int y = (rect.Height() - cyIcon + 1) / 2; + + // Draw the icon + dc.DrawIcon(x, y, m_hIcon); + } + else + { + CDialog::OnPaint(); + } +} + +// The system calls this function to obtain the cursor to display while the user drags +// the minimized window. +HCURSOR CNaadhDlg::OnQueryDragIcon() +{ + return static_cast(m_hIcon); +} + +void CNaadhDlg::Reset() +{ + for(int x=0;xCheckDlgButton(IDC_CHECK_VARSAME, m_VarietySameSpecies); + this->CheckDlgButton(IDC_CHECK_VARANY, m_VarietyAnySpecies); + this->CheckDlgButton(IDC_CHECK_VARLOOP, m_VarietyLoop); + this->CheckDlgButton(IDC_CHECK_VARCOMP, m_VarietyComp); + this->CheckDlgButton(IDC_CHECK_SAM, m_SamBeat); + + m_TempoSliderCtrl.SetPos(m_BpmDeviation); + m_RandSliderCtrl.SetPos(m_Rand); + m_BolVarSliderCtrl.SetPos(m_BolVar); + + m_List.SetColHeading(7,"Compose Mode"); + m_Menu.CheckMenuItem(ID_EDIT_SELECT, (MF_CHECKED * (UINT)m_EditMode) |MF_BYCOMMAND); + + m_Mesg.Format("%.1f", (float)VERSION/10.0); + m_Mesg = " Naad - Version " + m_Mesg + ", " + VERMONTH; + this->SetDlgItemText(IDC_STATIC_MSG, m_Mesg); +} + +void CNaadhDlg::OnFileExit() +{ + OnBnClickedButtonStop(); + DeleteLoopSequence(); + + CDialog::OnOK(); +} + +void CNaadhDlg::OnHelpAboutnaadh() +{ + m_WaveBox.Play(126); + + CAboutNaadDlg dlgAbout; + dlgAbout.m_ImageFileName = m_AppPath + "NaadHelp\\HelpImages\\About.jpg"; + if(IDCANCEL==dlgAbout.DoModal()) + { + CAboutDlg adlg; + adlg.DoModal(); + } +} + +UINT UpdateCheckProc(LPVOID param) +{ + CUpdateCheck *checkUpdate = (CUpdateCheck *)param; + checkUpdate->Check(IDS_UPDATE); + delete checkUpdate; + return 0; +} + +void CNaadhDlg::OnHelpCheckforupdates() +{ + CUpdateCheck *checkUpdate1 = new CUpdateCheck; + checkUpdate1->m_Quiet = m_Quiet; + CWinThread* hTh1 = AfxBeginThread( UpdateCheckProc, checkUpdate1, THREAD_PRIORITY_NORMAL ); +} + +void CNaadhDlg::OpenOldVer() +{ + //new comp + CString filetitle = m_NaadhFileName; + m_Saved = TRUE; + OnFileNewcomposition(); + m_Composition.DeleteLoop(0); + + m_List.m_selcol = 0; + m_List.m_selrow = 0; + OpenLoopOldVer(filetitle); + + //CFile naadhfile; + //BOOL res1 = naadhfile.Open(m_NaadhFileName, CFile::modeRead); + //if(!res1) + //{ + // AfxMessageBox("Error : Failed to open the file"); + // m_NaadhFileName = ""; + // return; + //} + //CArchive arch(&naadhfile, CArchive::load); + + //UINT ver = 0; + ////ver + //arch >> ver; + //if(ver < 2) + //{ + // arch.Close(); + // naadhfile.Close(); + // AfxMessageBox("The file you are trying to open is of a version that is no longer supported"); + // return; + //} + //UINT futureuint = 0, col, row; + //CString futurestr; + //BOOL futurebool = false; + ////ClearDisplay(); + + //arch >> col >> row >> m_MaatraBol; + //if(m_MaatraBol<1) m_MaatraBol = 1; + + //for(int x=0;x> futureuint; + //for(int x=0;x> futurestr; + //for(int x=0;x> futurebool; + + ////for(int x=0;x> m_Taal[x][y]; + //// //arch >> m_Status[x][y]; + //// } + ////} + + //arch.Close(); + //naadhfile.Close(); + + ////DisplayTaal(); + + //CString filetitle = m_NaadhFileName; + //filetitle.Delete(0,m_NaadhFileName.ReverseFind('\\')+1); + + //m_Mesg = " Loaded ... " + filetitle; //DataFileOpenDialog.GetFileTitle(); + //this->SetDlgItemText(IDC_STATIC_FILE, m_Mesg); + //this->SetDlgItemText(IDC_STATIC_MSG, " Ready..."); + //m_Saved = true; +} + +void CNaadhDlg::OnFileOpen32773() +{ + if(!m_IsShellOpen) + { + if(m_IsPlaying) OnBnClickedButtonStop(); + if(!m_Saved) + { + int ex = AfxMessageBox("Do you wish to save this composition before loading another one ??",MB_YESNOCANCEL | MB_ICONQUESTION); + if( ex == IDCANCEL) return; + if( ex == IDYES) OnFileSave32774(); + } + + //opens output file select dialog + CFileDialog DataFileOpenDialog(true,"nad","",OFN_HIDEREADONLY,"Naad Files (*.nad)|*.nad|All Files (*.*)|*.*||"); + DataFileOpenDialog.m_ofn.lpstrTitle = "Load a Naad File ..."; + DataFileOpenDialog.m_ofn.lpstrInitialDir = m_AppPath + "Compositions"; + INT_PTR res = DataFileOpenDialog.DoModal(); + if(res==IDCANCEL) return; + m_NaadhFileName = DataFileOpenDialog.GetPathName(); + if(m_NaadhFileName.IsEmpty()) return; + if(DataFileOpenDialog.GetFileExt() != "nad") return; + } + + CFile naadhfile; + BOOL res1 = naadhfile.Open(m_NaadhFileName, CFile::modeRead); + if(!res1) + { + AfxMessageBox("Error : Failed to open the file"); + m_NaadhFileName = ""; + return; + } + CArchive arch(&naadhfile, CArchive::load); + + UINT ver = 0, type = 0; + //ver + arch >> ver; + if(ver < VERSION) + { + arch.Close(); + naadhfile.Close(); + OpenOldVer(); + return; + } + + if(ver > VERSION) + { + arch.Close(); + naadhfile.Close(); + AfxMessageBox("The file you are trying to open is of a newer version. Please update to the latest version and try again."); + return; + } + + arch >> type; + if(type != FILETYPE_COMP) + { + arch.Close(); + naadhfile.Close(); + AfxMessageBox("The file you are trying to open is probably not a Naad composition and cannot be opened"); + return; + } + + + //new comp + CString filetitle = m_NaadhFileName; + m_Saved = TRUE; + OnFileNewcomposition(); + m_Composition.DeleteLoop(0); + + //comp + UINT loopcount = 0; + arch + >> m_Composition.m_CompositionName + >> m_Composition.m_ComposerName + >> m_Composition.m_Notes + >> loopcount; + + //chk loopcount + if(loopcount > MC*MR) + { + arch.Close(); + naadhfile.Close(); + AfxMessageBox("The file you are trying to open is probably corrupt and cannot be opened"); + OnFileNewcomposition(); + return; + } + + //loops + UINT col = 0, row = 0, bolcount = 0; + for(UINT x=0; x> col + >> row; + + m_Composition.AddLoop(col, row); + + arch + >> m_Composition.m_Loop[x].m_LoopName + >> m_Composition.m_Loop[x].m_Note + >> m_Composition.m_Loop[x].m_Accompaniment + >> m_Composition.m_Loop[x].m_LoopBpm + >> m_Composition.m_Loop[x].m_MaatraBol + >> m_Composition.m_Loop[x].m_RepeatCount + >> bolcount; + + for(UINT y=0; y> m_Composition.m_Loop[x].m_Bol[y].m_BolId + >> m_Composition.m_Loop[x].m_Bol[y].m_BolName + >> m_Composition.m_Loop[x].m_Bol[y].m_BolStatusName + >> m_Composition.m_Loop[x].m_Bol[y].m_Col + >> m_Composition.m_Loop[x].m_Bol[y].m_Row + >> m_Composition.m_Loop[x].m_Bol[y].m_Species + >> m_Composition.m_Loop[x].m_Bol[y].m_Status; + } + + } + + + arch.Close(); + naadhfile.Close(); + + DisplayComposition(); + + filetitle.Delete(0,m_NaadhFileName.ReverseFind('\\')+1); + + m_Mesg = " Loaded ... " + filetitle; //DataFileOpenDialog.GetFileTitle(); + this->SetDlgItemText(IDC_STATIC_FILE, m_Mesg); + this->SetDlgItemText(IDC_STATIC_MSG, " Ready..."); + m_Saved = true; +} + +void CNaadhDlg::OnFileSave32774() +{ + if(m_NaadhFileName.IsEmpty()) {OnFileSaveas(); return;} + + CFile naadhfile; + BOOL res = naadhfile.Open(m_NaadhFileName, CFile::modeCreate|CFile::modeWrite); + if(!res) + { + AfxMessageBox("Error : Failed to create the file"); + m_NaadhFileName = ""; + return; + } + CArchive arch(&naadhfile, CArchive::store); + + //ver + arch << VERSION << FILETYPE_COMP; + + //comp + arch + << m_Composition.m_CompositionName + << m_Composition.m_ComposerName + << m_Composition.m_Notes + << m_Composition.m_LoopCount; + + //loops + for(UINT x=0; xSetDlgItemText(IDC_STATIC_MSG, m_Mesg); + m_Mesg.Delete(0,1+m_Mesg.ReverseFind('\\')); + this->SetDlgItemText(IDC_STATIC_FILE, m_Mesg); + + m_Saved = true; +} + +void CNaadhDlg::OnFileSaveas() +{ + CFileDialog ResFileOpenDialog(false,"nad",m_NaadhFileName,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"Naad Files (*.nad)|*.nad|All Files (*.*)|*.*||"); + ResFileOpenDialog.m_ofn.lpstrInitialDir = m_AppPath + "Compositions"; + INT_PTR res = ResFileOpenDialog.DoModal(); + if(res==IDOK) + { + m_NaadhFileName = ResFileOpenDialog.GetPathName(); + OnFileSave32774(); + } +} + +//void CNaadhDlg::DisplayTaal() +//{ +// //CString bols[MAXBOLS] = BOLS; +// +// for(int x=0;xTrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, m_List.m_XPos, m_List.m_YPos, this); + } + } + + return CDialog::OnCommand(wParam, lParam); +} + +void CNaadhDlg::ClearDisplay() +{ + for(int x=0;x 0) m_TotalLoops += m_Composition.m_Loop[nloop].m_RepeatCount; + } + + if(m_TotalLoops == 0) return false; + + m_LoopSequence = new UINT[m_TotalLoops]; + if(m_LoopSequence == NULL) + { + allocloop = false; + } + + + //seq of loops + UINT nseq = 0; + for(UINT by=0;by 0) ) + { + for(UINT bz=0;bz= m_Composition.m_LoopCount) +// { +// return false; //all loops are empty +// } +// +// } +//} + +void CNaadhDlg::PlayLoopSequence() +{ + if(m_LoopDone) + { + if((m_PlayLoop) && (m_ActiveLoop != LOOP_NONE)) + { + //do nothing + } + else + { + if(m_SeqNum < m_TotalLoops-1) m_SeqNum ++; + else m_SeqNum = 0; + m_NextLoop = m_LoopSequence[m_SeqNum]; + SetLoopBpm(); + m_LoopDone = FALSE; + } + + } + + PlayBolSequence(); +} + +void CNaadhDlg::PlayBolSequence() +{ + if(m_Sequence[m_NextLoop].m_BolSeqCount == 0) return; + + //play bol + UINT nbolseq = BOL_NONE; + + if( m_BolVar > 0) nbolseq = m_Sequence[m_NextLoop].m_BolVarSeq[m_NextBol]; + else nbolseq = m_Sequence[m_NextLoop].m_BolIdSeq[m_NextBol]; + + //play it + if(nbolseq != BOL_SILENCE) m_WaveBox.Play(nbolseq); + + //sam + if(m_SamBeat) + { + if(m_Sequence[m_NextLoop].m_BolStatusSeq[m_NextBol] == BOL_SAM) m_WaveBox.Play(m_Ghungru[m_GhungruSel]); + } + + //set next + if(m_NextBol < m_Sequence[m_NextLoop].m_BolSeqCount-1) + { + m_NextBol ++; + } + else + { + m_NextBol = 0; + m_LoopDone = TRUE; + } + + TempoVariation(); +} + +//void CNaadhDlg::PlaySequence() +//{ +// //check seq +// if((m_Sequence[m_NextLoop].m_BolSeqCount == 0) && (m_Composition.m_LoopCount<=1)) return; //nothing to play +// +// if((m_PlayLoop) && (m_ActiveLoop != LOOP_NONE)) +// { +// if(m_Sequence[m_NextLoop].m_BolSeqCount == 0) +// { +// //OnTimer(WM_USER+200); +// return; +// } +// } +// else +// { +// if(m_Sequence[m_NextLoop].m_BolSeqCount == 0) +// { +// if(m_NextLoop < m_Composition.m_LoopCount-1) {m_NextLoop ++; SetLoopBpm();} +// else {m_NextLoop = 0; SetLoopBpm();} +// +// //OnTimer(WM_USER+200); +// return; +// } +// } +// +// //play bol +// UINT nbolseq = BOL_NONE; +// +// if( m_BolVar > 0) nbolseq = m_Sequence[m_NextLoop].m_BolVarSeq[m_NextBol]; +// else nbolseq = m_Sequence[m_NextLoop].m_BolIdSeq[m_NextBol]; +// +// //play it +// if(nbolseq != BOL_SILENCE) m_WaveBox.Play(nbolseq); +// +// //sam +// if(m_SamBeat) +// { +// if(m_Sequence[m_NextLoop].m_BolStatusSeq[m_NextBol] == BOL_SAM) m_WaveBox.Play(m_Ghungru[m_GhungruSel]); +// } +// +// //set next +// if(m_NextBol < m_Sequence[m_NextLoop].m_BolSeqCount-1) m_NextBol ++; +// else +// { +// m_NextBol = 0; +// if((m_PlayLoop) && (m_ActiveLoop != LOOP_NONE)) +// { +// m_NextLoop = m_ActiveLoop; +// } +// else +// { +// if(m_NextLoop <= m_Composition.m_LoopCount-1) +// { +// //check repeats +// if(m_Sequence[m_NextLoop].m_RepeatSeqCount > 1) +// { +// if(m_Sequence[m_NextLoop].m_RepeatCountDown < 2) +// { +// m_Sequence[m_NextLoop].m_RepeatCountDown = m_Sequence[m_NextLoop].m_RepeatSeqCount; +// if(m_NextLoop < m_Composition.m_LoopCount-1) {m_NextLoop ++; SetLoopBpm();} +// else {m_NextLoop = 0; SetLoopBpm();} +// } +// else m_Sequence[m_NextLoop].m_RepeatCountDown --; +// } +// else +// { +// if(m_NextLoop < m_Composition.m_LoopCount-1) {m_NextLoop ++; SetLoopBpm();} +// else {m_NextLoop = 0; SetLoopBpm();} +// } +// +// } +// else +// { +// m_NextLoop = 0; +// SetLoopBpm(); +// } +// } +// } +// +// TempoVariation(); +//} + +void CNaadhDlg::SetLoopBpm() +{ + m_Bpm = m_Composition.m_Loop[m_NextLoop].m_LoopBpm; + m_MaatraBol = m_Composition.m_Loop[m_NextLoop].m_MaatraBol; + UpdateTempo(); +} + +void CNaadhDlg::OnTimer(UINT nIDEvent) +{ + if(!m_IsPlaying) return; + + if(nIDEvent==m_TimerAcc) + { + m_WaveBox.Play(m_Tanpura[m_TanpuraSel]); + } + else + { + PlayLoopSequence(); + } + + + //else + //{ + // //variation in bols + // //series1 0-11 series2 12-23 series3 24-35 + // int r = /*rand() % */m_BolVar; + // UINT nbol = r + m_BolSeq[m_NextBol]; + // if(nbol>m_MaxBol) nbol = m_BolSeq[m_NextBol]; + // //TRACE2("%d, %d\r\n",r,s); + + // //play it + // if(m_BolSeq[m_NextBol] != BOL_SILENCE) m_WaveBox.Play(nbol); + + // //sam + // if(m_SamBeat) + // { + // if(m_StatusSeq[m_NextBol] == BOL_SAM) m_WaveBox.Play(121); + // } + + // //set next + // m_NextBol ++; + // if(m_NextBol>=m_BolCount) m_NextBol = 0; + + // //variation in timer + // KillTimer(m_Timer); + // r = rand() % m_Rand;//1-100 + // r = (int)m_Tempo*(r - (int)m_Rand/2)/150; + // //TRACE2("%d, %d\r\n",r,m_Rand); + // m_Timer = SetTimer(WM_USER+200, m_Tempo + r, NULL); + //} + + CDialog::OnTimer(nIDEvent); +} + +void CNaadhDlg::OnBnClickedButtonStop() +{ + KillTimer(m_Timer); + m_IsPlaying = FALSE; + this->SetDlgItemText(IDC_STATIC_MSG, " Stopped ..."); +} + +void CNaadhDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) +{ + if (pScrollBar == (CScrollBar*)&m_TempoSliderCtrl) + { + if((nSBCode == SB_THUMBPOSITION)||(nSBCode == SB_THUMBTRACK)) + { + m_BpmDeviation = nPos; + UpdateTempo(); + //if(nSBCode == SB_THUMBPOSITION) OnBnClickedButtonPlay(); + } + } + if (pScrollBar == (CScrollBar*)&m_RandSliderCtrl) + { + if((nSBCode == SB_THUMBPOSITION)||(nSBCode == SB_THUMBTRACK)) + { + m_Rand = nPos; + m_Mesg.Format("Timing Variation = %d",nPos); + this->SetDlgItemText(IDC_EDIT_TEMPOVAR, m_Mesg); + //if(nSBCode == SB_THUMBPOSITION) OnBnClickedButtonPlay(); + } + } + if (pScrollBar == (CScrollBar*)&m_BolVarSliderCtrl) + { + if((nSBCode == SB_THUMBPOSITION)/*||(nSBCode == SB_THUMBTRACK)*/) + { + m_BolVar = nPos; + + //create a varient + if(m_BolVar > 0) + { + CreateVarient(); + m_List.SetColHeading(2,"Variant"); + } + else m_List.SetColHeading(2," "); + + m_Mesg.Format("Bol Variation = %d",m_BolVar); + this->SetDlgItemText(IDC_EDIT_BOLVAR, m_Mesg); + } + } + CDialog::OnHScroll(nSBCode, nPos, pScrollBar); +} + + +void CNaadhDlg::FormatCells() +{ + bool mark = true; + UINT m = 1; + for(int x=0;xm_MaatraBol) {m = 1; mark = !mark;} + } + m_List.Invalidate(); +} + +void CNaadhDlg::LoadBolWaves() +{ + CString bolfile[MAXBOLS] = BOLS; + CString t, alarm; + int nbol = 0, failed = 0; + if(m_BolFolder.IsEmpty()) + { + m_BolFolder = m_AppPath+"Bol"; + } + + //check paths validity + if(GetFileAttributes(m_BolFolder) == INVALID_FILE_ATTRIBUTES) + { + m_IsBolLoaded = FALSE; + m_BolFolder = ""; + return; + } + + alarm = m_BolFolder + "\\Acc\\Alarm.wav"; + + UINT loadedcount = 0; + m_WaveBox.wload = 0; //reset in case another bol folder is loaded + for(int x=0;xIsDlgButtonChecked(IDC_CHECK_ACC)) + { + m_TimerAcc = SetTimer(WM_USER+201, 7880, NULL); + m_WaveBox.Play(m_Tanpura[m_TanpuraSel]);//dont wait till it starts + } + else KillTimer(m_TimerAcc); +} + +void CNaadhDlg::OnBnClickedCheckRndbol() +{ +} + +void CNaadhDlg::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu) +{ + CDialog::OnMenuSelect(nItemID, nFlags, hSysMenu); + + UINT id = 0; + if((nItemID>=ID_NA_NA01)&&(nItemID<=ID_KE_KE10)) + { + if(!m_IsBolLoaded) + { + OnOptionsBolfolder(); + return; + } + m_WaveBox.Play(nItemID - ID_NA_NA01); + } + + if(nItemID==ID_ACCOMPANIMENT_TANPURA) + { + id = m_Tanpura[0] + nItemID - ID_ACCOMPANIMENT_TANPURA; + if(id<=m_Tanpura[MAXTANPURA-1]) m_WaveBox.Play(id); + } + + if((nItemID>=ID_GHUNGRU_GHUNGRU01)&&(nItemID<=ID_GHUNGRU_GHUNGRU06)) + { + id = m_Ghungru[0]+ nItemID - ID_GHUNGRU_GHUNGRU01; + if(id<=m_Ghungru[MAXGHUNGRU-1]) m_WaveBox.Play(id); + } +} + +void CNaadhDlg::OnOptionsPlayallsamples() +{ + if(!m_IsBolLoaded) + { + OnOptionsBolfolder(); + return; + } + + for(UINT x=0;xIsDlgButtonChecked(IDC_CHECK_SAM); +} + + +CString strTmpPath; + +int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData) +{ + TCHAR szDir[MAX_PATH]; + switch(uMsg){ + case BFFM_INITIALIZED: + if (lpData){ + strcpy_s(szDir, strTmpPath.GetBuffer(strTmpPath.GetLength())); + SendMessage(hwnd,BFFM_SETSELECTION,TRUE,(LPARAM)szDir); + } + break; + case BFFM_SELCHANGED: { + if (SHGetPathFromIDList((LPITEMIDLIST) lParam ,szDir)){ + SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)szDir); + } + break; + } + default: + break; + } + + return 0; +} + +BOOL GetFolder(CString* strSelectedFolder, + const char* lpszTitle, + const HWND hwndOwner, + const char* strRootFolder, + const char* strStartFolder) +{ + char pszDisplayName[MAX_PATH]; + LPITEMIDLIST lpID; + BROWSEINFOA bi; + + bi.hwndOwner = hwndOwner; + if (strRootFolder == NULL){ + bi.pidlRoot = NULL; + }else{ + LPITEMIDLIST pIdl = NULL; + IShellFolder* pDesktopFolder; + char szPath[MAX_PATH]; + OLECHAR olePath[MAX_PATH]; + ULONG chEaten; + ULONG dwAttributes; + + strcpy_s(szPath, (LPCTSTR)strRootFolder); + if (SUCCEEDED(SHGetDesktopFolder(&pDesktopFolder))) + { + MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szPath, -1, olePath, MAX_PATH); + pDesktopFolder->ParseDisplayName(NULL, NULL, olePath, &chEaten, &pIdl, &dwAttributes); + pDesktopFolder->Release(); + } + bi.pidlRoot = pIdl; + } + bi.pszDisplayName = pszDisplayName; + bi.lpszTitle = lpszTitle; + bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT; + bi.lpfn = BrowseCallbackProc; + if (strStartFolder == NULL){ + bi.lParam = FALSE; + }else{ + strTmpPath.Format("%s", strStartFolder); + bi.lParam = TRUE; + } + bi.iImage = NULL; + lpID = SHBrowseForFolderA(&bi); + if (lpID != NULL){ + BOOL b = SHGetPathFromIDList(lpID, pszDisplayName); + if (b == TRUE){ + strSelectedFolder->Format("%s",pszDisplayName); + return TRUE; + } + }else{ + strSelectedFolder->Empty(); + } + return FALSE; +} + +void CNaadhDlg::OnOptionsBolfolder() +{ + if(m_IsPlaying) OnBnClickedButtonStop(); + + //check current folder + CString t; + if(m_BolFolder.IsEmpty()) t = "Bol Samples were not loaded.\r\nUsually the samples are included with this program in a folder named Bol. If you have moved the program or misplaced this folder you can specify its path.\r\nDo you wish to specify the Bol folder now ?"; + else t = "Current Bol Folder is : " + m_BolFolder + "\r\n\r\nYou can play your own sample collection in Naad as long as you keep the folder structure and filenames like those in original Bol folder. Or if you are using some other Bol folder you can specify the original one again.\r\n\r\nDo you wish to specify another folder ?"; + if(IDNO==AfxMessageBox(t, MB_YESNO)) return; + + CString oldpath = m_BolFolder; + if (GetFolder(&m_BolFolder, "Select the Folder where your Bol Sample files are ....", this->m_hWnd, NULL, NULL)) + { + if (!m_BolFolder.IsEmpty()) + { + LoadBolWaves(); + SaveSettings(); + } + } + else m_BolFolder = oldpath; +} + +void CNaadhDlg::OnHelpContact() +{ + CString str; + str.Format("%.1f", (float)VERSION/10.0); + str = "mailto:oormicreations@gmail.com? subject=Naad & body=I wish to report following problem/bug/feature request:%0A%0ANaad version: " + str + "%0A%0ADated: " + VERMONTH + " Beta%0A%0ADescription: %0A%0A%0A%0A%0A%0AThanks.%0A%0A%0A%0AName:%0A%0ALocation:%0A%0A" ; + ShellExecute(NULL, "open", str, NULL , NULL, SW_SHOWNORMAL); +} + +void CNaadhDlg::OnHelpNaadhhelp() +{ + ShellExecute(0,"open",m_AppPath + "NaadHelp\\HelpIndex.htm",0,0,SW_SHOWNORMAL); +} + +void CNaadhDlg::SaveSettings() +{ + if(m_AppPath.IsEmpty()) return; + + CFile SettFile; + BOOL m_IsSettFileOpen = SettFile.Open( m_AppPath + "\\NaadSettings.set", CFile::modeCreate | CFile::modeWrite ); + if(!m_IsSettFileOpen) {return;} + + CArchive archive(&SettFile, CArchive::store); + archive << VERSION << FILETYPE_SETT << m_IsInstalled << m_BolFolder; + + archive.Close(); + SettFile.Close(); +} + +void CNaadhDlg::LoadSettings() +{ + if(m_AppPath.IsEmpty()) return; + + CFile SettFile; + BOOL m_IsSettFileOpen = SettFile.Open( m_AppPath + "\\NaadSettings.set", CFile::modeRead ); + if(!m_IsSettFileOpen) {return;} + CArchive archive(&SettFile, CArchive::load); + + int ver, type; + archive >> ver >> type; + + if(type != FILETYPE_SETT) return; + + if(ver == VERSION) + { + archive >> m_IsInstalled >> m_BolFolder; + } + + archive.Close(); + SettFile.Close(); + +} + + +void CNaadhDlg::AssociateFileType(CString ext, CString app, CString id, CString desc, CString icon) +{ + //CreateRegistryKey HKEY_CLASSES_ROOT\Extension + DWORD dwDisposition; + HKEY hKey, hKey2; + + LONG res = RegCreateKeyEx(HKEY_CLASSES_ROOT, ext, 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &hKey, &dwDisposition); + if(res != ERROR_SUCCESS) return; + if(dwDisposition == REG_OPENED_EXISTING_KEY) TRACE("Opened key ext"); + + //SetRegistryValue of HKEY_CLASSES_ROOT\Extension, _use default value, value= Identifier + res = RegSetValueEx(hKey, "", 0, REG_SZ, reinterpret_cast((LPSTR)(LPCSTR)id), id.GetLength() +1); + if(res != ERROR_SUCCESS) return; + + //CreateRegistryKey HKEY_CLASSES_ROOT\Identifier + res = RegCreateKeyEx(HKEY_CLASSES_ROOT, id, 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &hKey, &dwDisposition); + if(res != ERROR_SUCCESS) return; + if(dwDisposition == REG_OPENED_EXISTING_KEY) TRACE("Opened key id"); + //SetRegistryValue HKEY_CLASSES_ROOT, Identifier, "", _REG_SZ, Description + res = RegSetValueEx(hKey, "", 0, REG_SZ, reinterpret_cast((LPSTR)(LPCSTR)desc), desc.GetLength() +1); + if(res != ERROR_SUCCESS) return; + + //CreateRegistryKey HKEY_CLASSES_ROOT\Identifier\DefaultIcon + res = RegCreateKeyEx(hKey, "DefaultIcon", 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &hKey2, &dwDisposition); + if(res != ERROR_SUCCESS) return; + if(dwDisposition == REG_OPENED_EXISTING_KEY) TRACE("Opened key id"); + //SetRegistryValue of HKEY_CLASSES_ROOT\Identifier\DefaultIcon, _use default value,value= Icon + res = RegSetValueEx(hKey2, "", 0, REG_SZ, reinterpret_cast((LPSTR)(LPCSTR)icon), icon.GetLength() +1); + if(res != ERROR_SUCCESS) return; + + //Identifier = Identifier + "\shell" + id = id + "\\shell"; + //CreateRegistryKey HKEY_CLASSES_ROOT\Identifier + res = RegCreateKeyEx(HKEY_CLASSES_ROOT, id, 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &hKey, &dwDisposition); + if(res != ERROR_SUCCESS) return; + if(dwDisposition == REG_OPENED_EXISTING_KEY) TRACE("Opened key id"); + + //Identifier = Identifier + "\open" + id = id + "\\open"; + //CreateRegistryKey HKEY_CLASSES_ROOT\Identifier + res = RegCreateKeyEx(HKEY_CLASSES_ROOT, id, 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &hKey, &dwDisposition); + if(res != ERROR_SUCCESS) return; + if(dwDisposition == REG_OPENED_EXISTING_KEY) TRACE("Opened key id"); + + //Identifier = Identifier + "\command" + id = id + "\\command"; + //CreateRegistryKey HKEY_CLASSES_ROOT\Identifier + res = RegCreateKeyEx(HKEY_CLASSES_ROOT, id, 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &hKey, &dwDisposition); + if(res != ERROR_SUCCESS) return; + if(dwDisposition == REG_OPENED_EXISTING_KEY) TRACE("Opened key id"); + //SetRegistryValue of HKEY_CLASSES_ROOT\Identifier, _use default value,value= ("Application" "%1") + app = "\""+app+"\" \"%1\""; + res = RegSetValueEx(hKey, "", 0, REG_SZ, reinterpret_cast((LPSTR)(LPCSTR)app), app.GetLength() +1); + if(res != ERROR_SUCCESS) return; + +} + +void CNaadhDlg::OnFileNewcomposition() +{ + if(!m_Saved) + { + int ex = AfxMessageBox("Do you wish to save this composition before creating a new one ??",MB_YESNOCANCEL | MB_ICONQUESTION); + if( ex == IDCANCEL) return; + if( ex == IDYES) OnFileSave32774(); + } + if(m_IsPlaying) OnBnClickedButtonStop(); + m_NaadhFileName = ""; + + //clean up previous composition + UINT lastcount = m_Composition.m_LoopCount; + for(UINT x=0; xSetDlgItemText(IDC_STATIC_FILE, " New Composition"); + m_Saved = true; +} + +void CNaadhDlg::DisplayBol(UINT nloop, UINT nbol) +{ + COLORREF color; + if(m_Composition.m_Loop[nloop].m_Bol[nbol].m_Species < 5) color = TXTRED; + else color = TXTBLUE; + + m_List.SetCellText( + m_Composition.m_Loop[nloop].m_Bol[nbol].m_Col, + m_Composition.m_Loop[nloop].m_Bol[nbol].m_Row, + m_Composition.m_Loop[nloop].m_Bol[nbol].m_BolName + " " + + m_Composition.m_Loop[nloop].m_Bol[nbol].m_BolStatusName, 1, color); + + m_List.SetColHeading(3, m_Composition.m_Loop[nloop].GetMatraCount()); + m_Saved = false; +} + +void CNaadhDlg::DisplayLoop(UINT nloop) +{ + if(nloop == LOOP_NONE) return; + + ClearDisplay(); + + for(UINT x=0;xIsDlgButtonChecked(IDC_CHECK_ECHO)) + //{ + // m_Echo = 50; + //} + //else m_Echo = 0; +} + + +void CNaadhDlg::OnBnClickedOk() +{ + OnFileExit(); +} + + +void CNaadhDlg::OnGhungruGhungru01() +{ + m_GhungruSel = 0; +} + + +void CNaadhDlg::OnGhungruGhungru02() +{ + m_GhungruSel = 1; +} + + +void CNaadhDlg::OnGhungruGhungru03() +{ + m_GhungruSel = 2; +} + + +void CNaadhDlg::OnGhungruGhungru04() +{ + m_GhungruSel = 3; +} + + +void CNaadhDlg::OnGhungruGhungru05() +{ + m_GhungruSel = 4; +} + + +void CNaadhDlg::OnGhungruGhungru06() +{ + //m_GhungruSel = 5; +} + + +void CNaadhDlg::OnAccompanimentTanpura() +{ + m_TanpuraSel = 0; +} + + +void CNaadhDlg::OnAccompaniment2() +{ + //m_TanpuraSel = 1; +} + + +void CNaadhDlg::OnAccompaniment3() +{ + //m_TanpuraSel = 2; +} + + +void CNaadhDlg::OnAccompaniment4() +{ + //m_TanpuraSel = 3; +} + + +void CNaadhDlg::OnBnClickedCheckVarsame() +{ + m_VarietySameSpecies = this->IsDlgButtonChecked(IDC_CHECK_VARSAME); + m_VarietyAnySpecies = !m_VarietySameSpecies; + this->CheckDlgButton(IDC_CHECK_VARANY, m_VarietyAnySpecies); + //reset to original varient + ResetVarient(); +} + + +void CNaadhDlg::OnBnClickedCheckVarany() +{ + m_VarietyAnySpecies = this->IsDlgButtonChecked(IDC_CHECK_VARANY); + m_VarietySameSpecies = !m_VarietyAnySpecies; + this->CheckDlgButton(IDC_CHECK_VARSAME, m_VarietySameSpecies); + //reset to original varient + ResetVarient(); +} + +UINT CNaadhDlg::GetBolVarient(UINT nbol) +{ + if((nbol == BOL_SILENCE)||(nbol == BOL_NONE)) return nbol; + + UINT r = 0, vbol = nbol, maxany = MAXBOLS*MAXBOLVARS, species = nbol/MAXBOLVARS; + + if(m_VarietyAnySpecies) + { + r = rand() % (1+(maxany*m_BolVar/100)); + vbol = nbol + r; + if(vbol >= maxany) vbol = vbol - maxany; //wrap + } + + if(m_VarietySameSpecies) + { + r = rand() % (1+(MAXBOLVARS*m_BolVar/100)); + vbol = nbol + r; + if(vbol >= (species*MAXBOLVARS+MAXBOLVARS)) vbol = vbol - MAXBOLVARS; //wrap + } + + return vbol; +} + +void CNaadhDlg::OnBnClickedButtonSavevar() +{ + int res = AfxMessageBox("Do you wish to save the original before replacing it with this variation ?", MB_YESNOCANCEL); + if(res == IDCANCEL) return; + if(res == IDYES) OnFileSaveas(); + + //replace + UINT nseq = 0; + for(UINT x=0; xSetDlgItemText(IDC_STATIC_MSG, m_Mesg); + +} + + +void CNaadhDlg::OnBnClickedCheckVarcomp() +{ + m_VarietyComp = this->IsDlgButtonChecked(IDC_CHECK_VARCOMP); + m_VarietyLoop = !m_VarietyComp; + this->CheckDlgButton(IDC_CHECK_VARLOOP, m_VarietyLoop); + //reset to original varient + ResetVarient(); +} + + +void CNaadhDlg::OnBnClickedCheckVarloop() +{ + m_VarietyLoop = this->IsDlgButtonChecked(IDC_CHECK_VARLOOP); + m_VarietyComp = !m_VarietyLoop; + this->CheckDlgButton(IDC_CHECK_VARCOMP, m_VarietyComp); + //reset to original varient + ResetVarient(); +} + +void CNaadhDlg::ResetVarient() +{ + m_BolVar = 0; + m_List.SetColHeading(2," "); + m_BolVarSliderCtrl.SetPos(m_BolVar); + this->SetDlgItemText(IDC_EDIT_BOLVAR, ""); +} + +void CNaadhDlg::CreateVarient() +{ + if(!m_IsPlaying) return; + + if(m_BolVar > (UINT)m_BolVarSliderCtrl.GetRangeMax()) + { + this->OnBnClickedButtonStop(); + AfxMessageBox("Bol variance is out of range"); + return; + } + + if(m_VarietyLoop) + { + if(m_ActiveLoop != LOOP_NONE) + { + for(UINT y=0; ySetDlgItemText(IDC_EDIT_TEMPO, m_Mesg); +} + +void CNaadhDlg::OnBnClickedButtonPlayloop() +{ + if(m_ActiveLoop == LOOP_NONE) return; + m_PlayLoop = TRUE; + //m_NextLoop = m_ActiveLoop; + InitPlay(); +} + +void CNaadhDlg::InitPlay() +{ + if(m_IsPlaying) OnBnClickedButtonStop(); + if(m_Composition.m_LoopCount<1) return; + if(!m_IsBolLoaded) + { + OnOptionsBolfolder(); + return; + } + + if(!CreateLoopSequence()) + { + if(m_TotalLoops > 0) AfxMessageBox("Loop sequence creation Failed"); + return; + } + + m_SeqNum = 0; + m_NextLoop = m_LoopSequence[m_SeqNum]; + if(m_PlayLoop) m_NextLoop = m_ActiveLoop; + m_NextBol = 0; + m_IsPlaying = TRUE; + m_LoopDone = FALSE; + + //seed rand + CTime time = CTime::GetCurrentTime(); + srand(time.GetSecond()); + + //no varient + ResetVarient(); + + //start timer + SetLoopBpm(); + + this->SetDlgItemText(IDC_STATIC_MSG, " Playing ..."); +} + + +void CNaadhDlg::OnBnClickedButtonGun1() +{ + m_Gun++; + if(m_Gun > 4) m_Gun = -3; + if(m_Gun == 0) m_Gun = 1; + + CString t; + if(m_Gun>0) + { + m_BpmDeviation = m_Bpm * (m_Gun - 1); + t.Format("%d X", m_Gun); + } + else + { + m_BpmDeviation = ((int)m_Bpm/(1-m_Gun)) - (int)m_Bpm; + t.Format("1/%d X", 1-m_Gun); + } + + UpdateTempo(); + + this->SetDlgItemTextA(IDC_BUTTON_GUN1,t); + m_TempoSliderCtrl.SetPos(m_BpmDeviation); +} + + +void CNaadhDlg::OpenLoopOldVer(CString loopfilename) +{ + CFile naadhfile; + if(!naadhfile.Open(loopfilename, CFile::modeRead)) + { + AfxMessageBox("Error : Failed to open the file"); + return; + } + + CArchive arch(&naadhfile, CArchive::load); + + //ver + UINT ver = 0, type = 0, bolcount = 0; + arch >> ver; + + if(ver == 1) + { + arch.Close(); + naadhfile.Close(); + AfxMessageBox("The file you are trying to open is of a version that is no longer supported"); + return; + } + + if(ver == 2) + { + UINT futureuint = 0, mcols = 0, mrows = 0, matrabol, mtaal[24][24], mstat[24][24], bolcount = 0, nloop; + CString futurestr; + BOOL futurebool = false; + + arch >> mcols >> mrows >> matrabol; + if(matrabol<1) matrabol = 1; + + m_Composition.AddLoop(m_List.m_selcol,m_List.m_selrow); + nloop = m_Composition.m_LoopCount-1; + + //loop + loopfilename.Replace(".nad",""); + CString filetitle = loopfilename; + filetitle.Delete(0,loopfilename.ReverseFind('\\')+1); + m_Composition.m_Loop[nloop].m_Note = "Converted from Naad Version 0.2 file :\r\n" + filetitle + ".nad"; + m_Composition.m_Loop[nloop].m_LoopName = filetitle; + m_Composition.m_Loop[nloop].m_MaatraBol = matrabol; + + for(int x=0;x> futureuint; + for(int x=0;x> futurestr; + for(int x=0;x> futurebool; + + for(int x=0;x<24;x++) + { + for(int y=0;y<24;y++) + { + arch >> mtaal[x][y]; + arch >> mstat[x][y]; + if(mtaal[x][y] != BOL_NONE) + { + m_Composition.m_Loop[nloop].AddBol(); + m_Composition.m_Loop[nloop].m_Bol[bolcount].SetBolType(mtaal[x][y], y, x); + m_Composition.m_Loop[nloop].m_Bol[bolcount].SetBolStatus(mstat[x][y]); + bolcount ++; + } + } + } + + m_Mesg = " Loop Loaded ... " + loopfilename; + + } + + if (ver == 3) + { + arch >> type; + if (type != FILETYPE_COMP) + { + arch.Close(); + naadhfile.Close(); + AfxMessageBox("The file you are trying to open is probably not a Naad composition and cannot be opened"); + return; + } + + + //new comp + CString filetitle = loopfilename; + m_Saved = TRUE; + OnFileNewcomposition(); + m_Composition.DeleteLoop(0); + + //comp + UINT loopcount = 0; + arch + >> m_Composition.m_CompositionName + >> m_Composition.m_ComposerName + >> m_Composition.m_Notes + >> loopcount; + + //chk loopcount + if (loopcount > MC*MR) + { + arch.Close(); + naadhfile.Close(); + AfxMessageBox("The file you are trying to open is probably corrupt and cannot be opened"); + OnFileNewcomposition(); + return; + } + + //loops + UINT col = 0, row = 0, bolcount = 0; + for (UINT x = 0; x> col + >> row; + + m_Composition.AddLoop(col, row); + + arch + >> m_Composition.m_Loop[x].m_LoopName + >> m_Composition.m_Loop[x].m_Note + >> m_Composition.m_Loop[x].m_Accompaniment + >> m_Composition.m_Loop[x].m_LoopBpm + >> m_Composition.m_Loop[x].m_MaatraBol + >> m_Composition.m_Loop[x].m_RepeatCount + >> bolcount; + + for (UINT y = 0; y> m_Composition.m_Loop[x].m_Bol[y].m_BolId + >> m_Composition.m_Loop[x].m_Bol[y].m_BolName + >> m_Composition.m_Loop[x].m_Bol[y].m_BolStatusName + >> m_Composition.m_Loop[x].m_Bol[y].m_Col + >> m_Composition.m_Loop[x].m_Bol[y].m_Row + >> m_Composition.m_Loop[x].m_Bol[y].m_Species + >> m_Composition.m_Loop[x].m_Bol[y].m_Status; + } + + } + + filetitle.Delete(0, loopfilename.ReverseFind('\\') + 1); + m_Mesg = " Loaded ... " + filetitle; //DataFileOpenDialog.GetFileTitle(); + } + + arch.Close(); + naadhfile.Close(); + DisplayComposition(); + + this->SetDlgItemText(IDC_STATIC_FILE, m_Mesg); + this->SetDlgItemText(IDC_STATIC_MSG, " Ready..."); +} + +void CNaadhDlg::OnLoopLoadloop() +{ + UINT nloop = m_Composition.GetLoop(m_List.m_selcol,m_List.m_selrow); + if(nloop != LOOP_NONE) + { + if(IDNO == AfxMessageBox("Do you wish to overwrite the existing loop ?", MB_YESNO)) return; + m_Composition.DeleteLoop(nloop); + } + + CString loopfilename; + CFileDialog ResFileOpenDialog(true,"nlp","",OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"Naad Loop Files (*.nlp)|*.nlp|All Files (*.*)|*.*||"); + ResFileOpenDialog.m_ofn.lpstrInitialDir = m_AppPath + "Loops"; + INT_PTR res = ResFileOpenDialog.DoModal(); + if(res==IDOK) loopfilename = ResFileOpenDialog.GetPathName(); + if(loopfilename.IsEmpty()) return; + + CFile naadhfile; + if(!naadhfile.Open(loopfilename, CFile::modeRead)) + { + AfxMessageBox("Error : Failed to open the nlp file"); + return; + } + CArchive arch(&naadhfile, CArchive::load); + + //ver + UINT ver = 0, type = 0, bolcount = 0; + arch >> ver; + + if(ver < VERSION) + { + arch.Close(); + naadhfile.Close(); + OpenLoopOldVer(loopfilename); + return; + } + + if(ver > VERSION) + { + arch.Close(); + naadhfile.Close(); + AfxMessageBox("The file you are trying to open is of a newer version. Please update to the latest version and try again."); + return; + } + + arch >> type; + if(type != FILETYPE_LOOP) + { + arch.Close(); + naadhfile.Close(); + AfxMessageBox("The file you are trying to open is probably not a Naad loop and cannot be opened"); + return; + } + + m_Composition.AddLoop(m_List.m_selcol,m_List.m_selrow); + nloop = m_Composition.m_LoopCount-1; + + //loop + arch + >> m_Composition.m_Loop[nloop].m_LoopName + >> m_Composition.m_Loop[nloop].m_Note + >> m_Composition.m_Loop[nloop].m_Accompaniment + >> m_Composition.m_Loop[nloop].m_LoopBpm + >> m_Composition.m_Loop[nloop].m_MaatraBol + >> m_Composition.m_Loop[nloop].m_RepeatCount + >> bolcount; + + for(UINT y=0; y> m_Composition.m_Loop[nloop].m_Bol[y].m_BolId + >> m_Composition.m_Loop[nloop].m_Bol[y].m_BolName + >> m_Composition.m_Loop[nloop].m_Bol[y].m_BolStatusName + >> m_Composition.m_Loop[nloop].m_Bol[y].m_Col + >> m_Composition.m_Loop[nloop].m_Bol[y].m_Row + >> m_Composition.m_Loop[nloop].m_Bol[y].m_Species + >> m_Composition.m_Loop[nloop].m_Bol[y].m_Status; + } + + arch.Close(); + naadhfile.Close(); + DisplayComposition(); + + m_Mesg = " Loop Loaded ... " + loopfilename; + this->SetDlgItemText(IDC_STATIC_FILE, m_Mesg); +} + + +void CNaadhDlg::OnLoopSaveloop() +{ + UINT nloop = m_Composition.GetLoop(m_List.m_selcol,m_List.m_selrow); + if(nloop == LOOP_NONE) return; + + CString loopfilename; + CFileDialog ResFileOpenDialog(false,"nlp",m_Composition.m_Loop[nloop].m_LoopName,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"Naad Loop Files (*.nlp)|*.nlp|All Files (*.*)|*.*||"); + ResFileOpenDialog.m_ofn.lpstrInitialDir = m_AppPath + "Loops"; + INT_PTR res = ResFileOpenDialog.DoModal(); + if(res==IDOK) loopfilename = ResFileOpenDialog.GetPathName(); + if(loopfilename.IsEmpty()) return; + + CFile naadhfile; + if(!naadhfile.Open(loopfilename, CFile::modeCreate|CFile::modeWrite)) + { + AfxMessageBox("Error : Failed to create the nlp file"); + return; + } + CArchive arch(&naadhfile, CArchive::store); + + //ver + arch << VERSION << FILETYPE_LOOP; + + //loop + arch + //<< m_Composition.m_Loop[nloop].m_Col + //<< m_Composition.m_Loop[nloop].m_Row + << m_Composition.m_Loop[nloop].m_LoopName + << m_Composition.m_Loop[nloop].m_Note + << m_Composition.m_Loop[nloop].m_Accompaniment + << m_Composition.m_Loop[nloop].m_LoopBpm + << m_Composition.m_Loop[nloop].m_MaatraBol + << m_Composition.m_Loop[nloop].m_RepeatCount + << m_Composition.m_Loop[nloop].m_BolCount; + + for(UINT y=0; ySetDlgItemText(IDC_STATIC_FILE, m_Mesg); +} + + +void CNaadhDlg::OnEditSelect() +{ + m_EditMode = !m_EditMode; + m_Menu.CheckMenuItem(ID_EDIT_SELECT, (MF_CHECKED * (UINT)m_EditMode) |MF_BYCOMMAND); + //m_Paste = FALSE; + if(m_EditMode) + { + ClearSelection(); + this->SetDlgItemTextA(IDC_STATIC_MSG, " Edit Mode"); + m_List.SetColHeading(7,"Edit Mode"); + this->SetDlgItemTextA(IDC_STATIC_FILE, " Click on cells to select/deselect. Click [Edit->Select] again to cancel edit mode"); + } + else + { + ClearSelection(); + this->SetDlgItemTextA(IDC_STATIC_MSG, " Compose Mode"); + m_List.SetColHeading(7,"Compose Mode"); + this->SetDlgItemTextA(IDC_STATIC_FILE, " Ready ..."); + } +} + + +void CNaadhDlg::OnEditClear32974() +{ + if(m_ActiveLoop != LOOP_NONE) + { + for(UINT x=0; xSetDlgItemTextA(IDC_STATIC_FILE, " Please select an empty cell to paste into.\r\nEnsure that there are enough empty cells around it"); + //ClearSelection(); + //m_Paste = TRUE; + //m_List.GetCellSelection(); + if(!m_List.m_sel) + { + AfxMessageBox("Please select an empty cell to paste into and click [Edit->Paste] on menu.", MB_OK, MB_ICONINFORMATION); + return; + } + + Paste(m_List.m_selcol, m_List.m_selrow); + ClearSelection(); + m_Saved = FALSE; +} + +void CNaadhDlg::Paste(UINT col, UINT row) +{ + bool overwritten = false; + + if(m_ActiveLoop != LOOP_NONE) + { + UINT nbol = 0; + for(UINT x=0; xSetDlgItemTextA(IDC_STATIC_FILE, " Some items were overwritten !"); + } + else + { + this->SetDlgItemTextA(IDC_STATIC_FILE, " Ready..."); + } + +} diff --git a/Naadh.h b/Naadh.h new file mode 100644 index 0000000..4aef6d2 --- /dev/null +++ b/Naadh.h @@ -0,0 +1,47 @@ +// Naadh.h : main header file for the PROJECT_NAME application +// + +#pragma once + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +#define VERSION 10 +#define VERMONTH "March 2018" + +#define MAXRESRV 16 +#define MAXGHUNGRU 5 +#define MAXTANPURA 1 +#define MAXBPM 800 +#define DEFAULT_BPM 180 + +#define FILETYPE_COMP 1 +#define FILETYPE_LOOP 2 +#define FILETYPE_SETT 3 + + +//#define BOLFILE {"Dha0^.wav", "Dhin0^.wav", "Dhit0^.wav", "Dhun0^.wav", "Ga0^.wav", "Ge0^.wav", "Ke0^.wav", "Na0^.wav", "Tat0^.wav", "Ti0^.wav", "Tin0^.wav", "Tun0^.wav"} + +// CNaadhApp: +// See Naadh.cpp for the implementation of this class +// + +class CNaadhApp : public CWinApp +{ +public: + CNaadhApp(); + +// Overrides + public: + virtual BOOL InitInstance(); + +// Implementation + + DECLARE_MESSAGE_MAP() +}; + +extern CNaadhApp theApp; + diff --git a/Naadh.vcproj b/Naadh.vcproj new file mode 100644 index 0000000..08e9316 --- /dev/null +++ b/Naadh.vcproj @@ -0,0 +1,265 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Naadh.vcxproj b/Naadh.vcxproj new file mode 100644 index 0000000..a37e92c --- /dev/null +++ b/Naadh.vcxproj @@ -0,0 +1,183 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Template + Win32 + + + + {2CF1DEDB-2800-477F-8FC2-0E24A1B56EA4} + MFCProj + Naad + + + + Application + Dynamic + MultiByte + v140 + + + Application + Dynamic + MultiByte + v140 + + + v140 + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + Debug\ + Debug\ + true + Release\ + Release\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + Use + Level3 + EditAndContinue + + + GdiPlus.lib %(AdditionalOptions) + Winmm.lib;wininet.lib;version.lib;%(AdditionalDependencies) + true + Windows + MachineX86 + + + _DEBUG;%(PreprocessorDefinitions) + false + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + $(IntDir);%(AdditionalIncludeDirectories) + + + + + WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions) + false + MultiThreadedDLL + true + Use + Level3 + ProgramDatabase + + + GdiPlus.lib %(AdditionalOptions) + Winmm.lib;wininet.lib;version.lib;%(AdditionalDependencies) + true + Windows + true + true + MachineX86 + + + NDEBUG;%(PreprocessorDefinitions) + false + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + $(IntDir);%(AdditionalIncludeDirectories) + + + + + + + + + + + + + + + + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Naadh.vcxproj.filters b/Naadh.vcxproj.filters new file mode 100644 index 0000000..56943d8 --- /dev/null +++ b/Naadh.vcxproj.filters @@ -0,0 +1,137 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + + Resource Files + + + Resource Files + + + Resource Files + + + + + + + + Resource Files + + + \ No newline at end of file diff --git a/NaadhDlg.h b/NaadhDlg.h new file mode 100644 index 0000000..179b275 --- /dev/null +++ b/NaadhDlg.h @@ -0,0 +1,154 @@ +// NaadhDlg.h : header file +// + +#pragma once +#include "UpdateCheck.h" +#include "multilinelist.h" +#include "afxcmn.h" +#include "afxwin.h" +#include "wavebox.h" +#include "composition.h" +#include "Sequence.h" + + + +// CNaadhDlg dialog +class CNaadhDlg : public CDialog +{ +// Construction +public: + CNaadhDlg(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + enum { IDD = IDD_NAADH_DIALOG }; + +//------------------------------------------------------------------------------------------------------------ + CMenu m_Menu, m_BolMenu, m_LoopMenu; + BOOL m_Quiet, m_Saved, m_SamBeat, m_IsInstalled, m_IsShellOpen, m_IsCompView, m_IsPlaying, m_IsBolLoaded; + BOOL m_VarietySameSpecies, m_VarietyAnySpecies, m_VarietyComp, m_VarietyLoop, m_PlayLoop, m_EditMode; + BOOL m_LoopDone; + CString m_Mesg, m_AppPath, m_NaadhFileName, m_BolFileSeq[MC*MR], m_BolFolder; + UINT m_Version, /*m_Cols, m_Rows,*/ m_Tempo, m_NextBol, m_NextLoop, m_MaatraBol, m_BolVar; + //UINT m_MaxBol, m_Echo; + UINT m_ActiveLoop, m_Bpm, *m_LoopSequence, m_TotalLoops, m_SeqNum; + int m_BpmDeviation, m_Gun, m_Rand, m_BpmRand; + UINT m_Ghungru[MAXGHUNGRU], m_Tanpura[MAXTANPURA], m_GhungruSel, m_TanpuraSel; + UINT_PTR m_Timer, m_TimerAcc; + + CMultilineList m_List; + CSliderCtrl m_TempoSliderCtrl, m_RandSliderCtrl, m_BolVarSliderCtrl; + CWaveBox m_WaveBox; + CComposition m_Composition, m_CompositionCopy; + CSequence* m_Sequence; + +//------------------------------------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------------------------------------ + void DisplayComposition(void); + void DisplayLoop(UINT nloop); + void DisplayBol(UINT nloop, UINT nbol); + void ClearDisplay(void); + void ClearSelection(void); + void LoadBolWaves(void); + void FormatCells(void); + void SaveSettings(void); + void LoadSettings(void); + void AssociateFileType(CString ext, CString app, CString id, CString desc, CString icon); + //void DoLoopPropDlg(UINT nloop); + bool CreateLoopSequence(void); + //bool GetNextLoop(void); + void DeleteLoopSequence(void); + //void PlaySequence(void); + void PlayLoopSequence(void); + void PlayBolSequence(void); + UINT GetBolVarient(UINT nbol); + void CreateVarient(void); + void ResetVarient(void); + void UpdateTempo(void); + void InitPlay(void); + void TempoVariation(void); + void SetLoopBpm(void); + void Reset(void); + void OpenOldVer(void); + void OpenLoopOldVer(CString loopfilename); + void Paste(UINT col, UINT row); + void NormalizeLocations(); + +//------------------------------------------------------------------------------------------------------------ + + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + + +// Implementation +protected: + HICON m_hIcon; + + // Generated message map functions + virtual BOOL OnInitDialog(); + afx_msg void OnSysCommand(UINT nID, LPARAM lParam); + afx_msg void OnPaint(); + afx_msg void OnTimer(UINT nIDEvent); + afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); + afx_msg HCURSOR OnQueryDragIcon(); + DECLARE_MESSAGE_MAP() +public: + afx_msg BOOL OnCommand(WPARAM wParam, LPARAM lParam); + afx_msg void OnFileExit(); + afx_msg void OnHelpAboutnaadh(); + afx_msg void OnHelpCheckforupdates(); + afx_msg void OnFileOpen32773(); + afx_msg void OnFileSave32774(); + afx_msg void OnFileSaveas(); + afx_msg void OnBolsClear32792(); + afx_msg void OnFileNewtaal(); + afx_msg void OnBnClickedButtonPlay(); + afx_msg void OnBnClickedButtonStop(); + afx_msg void OnBolsSilence(); + afx_msg void OnBnClickedCheckAcc(); + afx_msg void OnBnClickedCheckRndbol(); + afx_msg void OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu); + afx_msg void OnOptionsPlayallsamples(); + afx_msg void OnSelectBol(UINT nID); + afx_msg void OnBolsSam(); + afx_msg void OnBolsTali(); + afx_msg void OnBolsKhali(); + afx_msg void OnBnClickedCheckSam(); + afx_msg void OnOptionsBolfolder(); + afx_msg void OnHelpContact(); + afx_msg void OnHelpNaadhhelp(); + afx_msg void OnFileNewcomposition(); + afx_msg void OnLoopOpen(); + afx_msg void OnViewComposition(); + afx_msg void OnLoopClear(); + afx_msg void OnBolsViewcomp(); + afx_msg void OnLoopProperties(); + afx_msg void OnViewLoop(); + afx_msg void OnBnClickedCheckEcho(); + afx_msg void OnBnClickedOk(); + afx_msg void OnGhungruGhungru01(); + afx_msg void OnGhungruGhungru02(); + afx_msg void OnGhungruGhungru03(); + afx_msg void OnGhungruGhungru04(); + afx_msg void OnGhungruGhungru05(); + afx_msg void OnGhungruGhungru06(); + afx_msg void OnAccompanimentTanpura(); + afx_msg void OnAccompaniment2(); + afx_msg void OnAccompaniment3(); + afx_msg void OnAccompaniment4(); + afx_msg void OnBnClickedCheckVarsame(); + afx_msg void OnBnClickedCheckVarany(); + afx_msg void OnBnClickedButtonSavevar(); + afx_msg void OnBnClickedCheckVarcomp(); + afx_msg void OnBnClickedCheckVarloop(); + afx_msg void OnBnClickedButtonAutocompose(); + afx_msg void OnBnClickedButtonPlayloop(); + afx_msg void OnBnClickedButtonGun1(); + afx_msg void OnLoopLoadloop(); + afx_msg void OnLoopSaveloop(); + afx_msg void OnEditSelect(); + afx_msg void OnEditClear32974(); + afx_msg void OnEditCopy32956(); + afx_msg void OnEditCut32957(); + afx_msg void OnEditPaste32958(); +}; diff --git a/ReadMe.txt b/ReadMe.txt new file mode 100644 index 0000000..a11971a --- /dev/null +++ b/ReadMe.txt @@ -0,0 +1,37 @@ +About Naad: + +Naad (Sanskrit: Vibration), is a program for composing and playing loops, of the Indian percussion instrument Tabla. + +Latest Exe Release is available here: +https://github.com/oormicreations/naad/releases + +Program features: + +Plays and composes Tabla loops out of up to 120 real samples of individual Tabla strokes (Bols) + +Loops can be composed on an interactive UI + +Composition can be made using several loops + +Compositions or loops can be saved and re-loaded + +Accompaniments (Taanpura and Ghungaru). + +Samples are actual sounds in .wav format + +Simultaneous multiple wav file samples can be played + +Tempo can be varied + +Randomness can be introduced in timing to make is sound less mechanical + +Variation in Bols can be introduced in real time during play. + +Users can specify their own samples. + +Auto update notifications + +Contact: + +oormicreations@gmail.com +http://oormi.in \ No newline at end of file diff --git a/ScrollHelper.cpp b/ScrollHelper.cpp new file mode 100644 index 0000000..ba2d000 --- /dev/null +++ b/ScrollHelper.cpp @@ -0,0 +1,417 @@ +// Filename: ScrollHelper.cpp +// 2005-07-01 nschan Initial revision. +// 2005-09-08 nschan Added GetClientRectSB() function. +// published at: http://www.codeproject.com/KB/dialog/scrolling_support.aspx?fid=195884 +// modified by J Dill, 3/08 + +#include "stdafx.h" +#include "ScrollHelper.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +// Helper function to get client rect with possible +// modification by adding scrollbar width/height. +static void GetClientRectSB(CWnd* pWnd, CRect& rect) +{ + ASSERT( pWnd != NULL ); + + CRect winRect; + pWnd->GetWindowRect(&winRect); + pWnd->ScreenToClient(&winRect); + + pWnd->GetClientRect(&rect); + + int cxSB = ::GetSystemMetrics(SM_CXVSCROLL); + int cySB = ::GetSystemMetrics(SM_CYHSCROLL); + + if ( winRect.right >= (rect.right + cxSB) ) + rect.right += cxSB; + if ( winRect.bottom >= (rect.bottom + cySB) ) + rect.bottom += cySB; +} + +// CScrollHelper ///////////////////////////////////////////////////////////////////// + +CScrollHelper::CScrollHelper() +{ + m_attachWnd = NULL; + m_pageSize = CSize(0,0); + m_displaySize = CSize(0,0); + m_scrollPos = CSize(0,0); +} + +CScrollHelper::~CScrollHelper() +{ + DetachWnd(); +} + +void CScrollHelper::AttachWnd(CWnd* pWnd) +{ + m_attachWnd = pWnd; +} + +void CScrollHelper::DetachWnd() +{ + m_attachWnd = NULL; +} + +void CScrollHelper::SetDisplaySize(int displayWidth, int displayHeight) +{ + m_displaySize = CSize(displayWidth, displayHeight); + + if ( m_attachWnd != NULL && ::IsWindow(m_attachWnd->m_hWnd) ) + UpdateScrollInfo(); +} + +void CScrollHelper::SetPageSize(int wid, int hgt) // added by JD +{ + m_pageSize = CSize(wid, hgt); +} + +const CSize& CScrollHelper::GetDisplaySize() const +{ + return m_displaySize; +} + +const CSize& CScrollHelper::GetScrollPos() const +{ + return m_scrollPos; +} + +const CSize& CScrollHelper::GetPageSize() const +{ + return m_pageSize; +} + +void CScrollHelper::ScrollToOrigin(bool scrollLeft, bool scrollTop) +{ + if ( m_attachWnd == NULL ) + return; + + if ( scrollLeft ) + { + if ( m_displaySize.cx > 0 && m_pageSize.cx > 0 && m_scrollPos.cx > 0 ) + { + int deltaPos = -m_scrollPos.cx; + m_scrollPos.cx += deltaPos; + m_attachWnd->SetScrollPos(SB_HORZ, m_scrollPos.cx, TRUE); + DoTheScroll(-deltaPos, 0); + } + } + + if ( scrollTop ) + { + if ( m_displaySize.cy > 0 && m_pageSize.cy > 0 && m_scrollPos.cy > 0 ) + { + int deltaPos = -m_scrollPos.cy; + m_scrollPos.cy += deltaPos; + m_attachWnd->SetScrollPos(SB_VERT, m_scrollPos.cy, TRUE); + DoTheScroll(0, -deltaPos); + } + } +} + +void CScrollHelper::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) +{ + if ( m_attachWnd == NULL ) + return; + + const int lineOffset = 60; + + // Compute the desired change or delta in scroll position. + int deltaPos = 0; + switch( nSBCode ) + { + case SB_LINELEFT: + // Left scroll arrow was pressed. + deltaPos = -lineOffset; + break; + + case SB_LINERIGHT: + // Right scroll arrow was pressed. + deltaPos = lineOffset; + break; + + case SB_PAGELEFT: + // User clicked inbetween left arrow and thumb. + deltaPos = -m_pageSize.cx; + break; + + case SB_PAGERIGHT: + // User clicked inbetween thumb and right arrow. + deltaPos = m_pageSize.cx; + break; + + case SB_THUMBTRACK: + // Scrollbar thumb is being dragged. + deltaPos = Get32BitScrollPos(SB_HORZ, pScrollBar) - m_scrollPos.cx; + break; + + case SB_THUMBPOSITION: + // Scrollbar thumb was released. + deltaPos = Get32BitScrollPos(SB_HORZ, pScrollBar) - m_scrollPos.cx; + break; + + default: + // We don't process other scrollbar messages. + return; + } + + // Compute the new scroll position. + int newScrollPos = m_scrollPos.cx + deltaPos; + + // If the new scroll position is negative, we adjust + // deltaPos in order to scroll the window back to origin. + if ( newScrollPos < 0 ) + deltaPos = -m_scrollPos.cx; + + // If the new scroll position is greater than the max scroll position, + // we adjust deltaPos in order to scroll the window precisely to the + // maximum position. + int maxScrollPos = m_displaySize.cx - m_pageSize.cx; + if ( newScrollPos > maxScrollPos ) + deltaPos = maxScrollPos - m_scrollPos.cx; + + // Scroll the window if needed. + if ( deltaPos != 0 ) + { + m_scrollPos.cx += deltaPos; + m_attachWnd->SetScrollPos(SB_HORZ, m_scrollPos.cx, TRUE); + DoTheScroll(-deltaPos, 0); + } +} + +void CScrollHelper::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) +{ + if ( m_attachWnd == NULL ) + return; + + const int lineOffset = 60; + + // Compute the desired change or delta in scroll position. + int deltaPos = 0; + switch( nSBCode ) + { + case SB_LINEUP: + // Up arrow button on scrollbar was pressed. + deltaPos = -lineOffset; + break; + + case SB_LINEDOWN: + // Down arrow button on scrollbar was pressed. + deltaPos = lineOffset; + break; + + case SB_PAGEUP: + // User clicked inbetween up arrow and thumb. + deltaPos = -m_pageSize.cy; + break; + + case SB_PAGEDOWN: + // User clicked inbetween thumb and down arrow. + deltaPos = m_pageSize.cy; + break; + + case SB_THUMBTRACK: + // Scrollbar thumb is being dragged. + deltaPos = Get32BitScrollPos(SB_VERT, pScrollBar) - m_scrollPos.cy; + break; + + case SB_THUMBPOSITION: + // Scrollbar thumb was released. + deltaPos = Get32BitScrollPos(SB_VERT, pScrollBar) - m_scrollPos.cy; + break; + + default: + // We don't process other scrollbar messages. + return; + } + + // Compute the new scroll position. + int newScrollPos = m_scrollPos.cy + deltaPos; + + // If the new scroll position is negative, we adjust + // deltaPos in order to scroll the window back to origin. + if ( newScrollPos < 0 ) + deltaPos = -m_scrollPos.cy; + + // If the new scroll position is greater than the max scroll position, + // we adjust deltaPos in order to scroll the window precisely to the + // maximum position. + int maxScrollPos = m_displaySize.cy - m_pageSize.cy; + if ( newScrollPos > maxScrollPos ) + deltaPos = maxScrollPos - m_scrollPos.cy; + + // Scroll the window if needed. + if ( deltaPos != 0 ) + { + m_scrollPos.cy += deltaPos; + m_attachWnd->SetScrollPos(SB_VERT, m_scrollPos.cy, TRUE); + DoTheScroll(0, -deltaPos); + } +} + +BOOL CScrollHelper::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) +{ + if ( m_attachWnd == NULL ) + return FALSE; + + // Don't do anything if the vertical scrollbar is not enabled. + int scrollMin = 0, scrollMax = 0; + m_attachWnd->GetScrollRange(SB_VERT, &scrollMin, &scrollMax); + if ( scrollMin == scrollMax ) + return FALSE; + + // Compute the number of scrolling increments requested. + int numScrollIncrements = abs(zDelta) / WHEEL_DELTA; + + // Each scrolling increment corresponds to a certain number of + // scroll lines (one scroll line is like a SB_LINEUP or SB_LINEDOWN). + // We need to query the system parameters for this value. + int numScrollLinesPerIncrement = 0; + ::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &numScrollLinesPerIncrement, 0); + + // Check if a page scroll was requested. + if ( numScrollLinesPerIncrement == WHEEL_PAGESCROLL ) + { + // Call the vscroll message handler to do the work. + OnVScroll(zDelta > 0 ? SB_PAGEUP : SB_PAGEDOWN, 0, NULL); + return TRUE; + } + + // Compute total number of lines to scroll. + int numScrollLines = numScrollIncrements * numScrollLinesPerIncrement; + + // Adjust numScrollLines to slow down the scrolling a bit more. + numScrollLines = max(numScrollLines/3, 1); + + // Do the scrolling. + for(int i = 0; i < numScrollLines; ++i) + { + // Call the vscroll message handler to do the work. + OnVScroll(zDelta > 0 ? SB_LINEUP : SB_LINEDOWN, 0, NULL); + } + + return TRUE; +} + +void CScrollHelper::OnSize(UINT nType, int cx, int cy) +{ + UpdateScrollInfo(); +} + +int CScrollHelper::Get32BitScrollPos(int bar, CScrollBar* pScrollBar) +{ + // Code below is from MSDN Article ID 152252, "How To Get + // 32-bit Scroll Position During Scroll Messages". + + // First determine if the user scrolled a scroll bar control + // on the window or scrolled the window itself. + ASSERT( m_attachWnd != NULL ); + HWND hWndScroll; + if ( pScrollBar == NULL ) + hWndScroll = m_attachWnd->m_hWnd; + else + hWndScroll = pScrollBar->m_hWnd; + + SCROLLINFO si; + si.cbSize = sizeof(SCROLLINFO); + si.fMask = SIF_TRACKPOS; + ::GetScrollInfo(hWndScroll, bar, &si); + + int scrollPos = si.nTrackPos; + + return scrollPos; +} + +void CScrollHelper::UpdateScrollInfo() +{ + if ( m_attachWnd == NULL ) + return; + + // Get the width/height of the attached wnd that includes the area + // covered by the scrollbars (if any). The reason we need this is + // because when scrollbars are present, both cx/cy and GetClientRect() + // when accessed from OnSize() do not include the scrollbar covered + // areas. In other words, their values are smaller than what you would + // expect. + CRect rect; + GetClientRectSB(m_attachWnd, rect); + CSize windowSize(rect.Width(), rect.Height()); + + // Update horizontal scrollbar. + CSize deltaPos(0,0); + UpdateScrollBar(SB_HORZ, windowSize.cx, m_displaySize.cx, + m_pageSize.cx, m_scrollPos.cx, deltaPos.cx); + + // Update vertical scrollbar. + UpdateScrollBar(SB_VERT, windowSize.cy, m_displaySize.cy, + m_pageSize.cy, m_scrollPos.cy, deltaPos.cy); + + // See if we need to scroll the window back in place. + // This is needed to handle the case where the scrollbar is + // moved all the way to the right for example, and controls + // at the left side disappear from the view. Then the user + // resizes the window wider until scrollbars disappear. Without + // this code below, the controls off the page will be gone forever. + if ( deltaPos.cx != 0 || deltaPos.cy != 0 ) + { + DoTheScroll(deltaPos.cx, deltaPos.cy); + } +} + +void CScrollHelper::DoTheScroll(int cx, int cy) +{ + // call scrollwindow and specify clipping within page; added by JD + // not quite right -- doesn't clip scrollbars -- but better than none + //CRect rClip(0, 0, m_pageSize.cx, m_pageSize.cy); + //m_attachWnd->ScrollWindow(cx, cy, 0, &rClip); + + //corrected for CAFVT, thanks to pcordes @ codeproject + CRect rClip; + m_attachWnd->GetClientRect(rClip); + m_attachWnd->ScrollWindow(cx, cy, 0, &rClip); +} + +void CScrollHelper::UpdateScrollBar(int bar, int windowSize, int displaySize, + LONG& pageSize, LONG& scrollPos, LONG& deltaPos) +{ + int scrollMax = 0; + deltaPos = 0; + if ( windowSize < displaySize ) + { + scrollMax = displaySize - 1; + if ( pageSize > 0 && scrollPos > 0 ) + { + // Adjust the scroll position when the window size is changed. + scrollPos = (LONG)(1.0 * scrollPos * windowSize / pageSize); + } + pageSize = windowSize; + scrollPos = min(scrollPos, displaySize - pageSize - 1); + deltaPos = m_attachWnd->GetScrollPos(bar) - scrollPos; + } + else + { + // Force the scrollbar to go away. + pageSize = 0; + scrollPos = 0; + deltaPos = m_attachWnd->GetScrollPos(bar); + } + + SCROLLINFO si; + memset(&si, 0, sizeof(SCROLLINFO)); + si.cbSize = sizeof(SCROLLINFO); + si.fMask = SIF_ALL; // SIF_ALL = SIF_PAGE | SIF_RANGE | SIF_POS; + si.nMin = 0; + si.nMax = scrollMax; + si.nPage = pageSize; + si.nPos = scrollPos; + m_attachWnd->SetScrollInfo(bar, &si, TRUE); +} + +// END + diff --git a/ScrollHelper.h b/ScrollHelper.h new file mode 100644 index 0000000..2b3ba30 --- /dev/null +++ b/ScrollHelper.h @@ -0,0 +1,61 @@ +// Filename: ScrollHelper.h +// S.Chan, 01 Jul 2005 + +#ifndef SCROLL_HELPER_INCLUDED +#define SCROLL_HELPER_INCLUDED + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +class CScrollHelper +{ +public: + CScrollHelper(); + ~CScrollHelper(); + + // Attach/detach a CWnd or CDialog. + void AttachWnd(CWnd* pWnd); + void DetachWnd(); + + // Set/get the virtual display size. When the dialog or window + // size is smaller than the display size, then that is when + // scrollbars will appear. Set either the display width or display + // height to zero if you don't want to enable the scrollbar in the + // corresponding direction. + void SetDisplaySize(int displayWidth, int displayHeight); + const CSize& GetDisplaySize() const; + + // Get current scroll position. This is needed if you are scrolling + // a custom CWnd which implements its own drawing in OnPaint(). + const CSize& GetScrollPos() const; + + // Get current page size. Useful for debugging purposes. + const CSize& GetPageSize() const; + void SetPageSize(int wid, int hgt); + + // Scroll back to top, left, or top-left corner of the window. + void ScrollToOrigin(bool scrollLeft, bool scrollTop); + + // Message handling. + void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); + void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); + BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt); + void OnSize(UINT nType, int cx, int cy); + +private: + int Get32BitScrollPos(int bar, CScrollBar* pScrollBar); + void UpdateScrollInfo(); + void UpdateScrollBar(int bar, int windowSize, int displaySize, + LONG& pageSize, LONG& scrollPos, LONG& deltaPos); + void DoTheScroll(int cx, int cy); + + CWnd* m_attachWnd; + CSize m_pageSize; + CSize m_displaySize; + CSize m_scrollPos; +}; + +#endif // SCROLL_HELPER_INCLUDED + +// END diff --git a/Sequence.cpp b/Sequence.cpp new file mode 100644 index 0000000..c4fcd35 --- /dev/null +++ b/Sequence.cpp @@ -0,0 +1,68 @@ +#include "StdAfx.h" +#include "Sequence.h" + + +CSequence::CSequence(void) +{ + m_BolIdSeq = NULL; + m_BolVarSeq = NULL; + m_BolStatusSeq = NULL; + m_BolSeqCount = 0; + m_RepeatSeqCount = 1; + m_RepeatCountDown = 1; +} + + +CSequence::~CSequence(void) +{ + if((m_BolIdSeq)||(m_BolStatusSeq)) DeleteBolSequence(); +} + +bool CSequence::CreateBolSequence(CLoop loop) +{ + if(loop.m_BolCount==0) + { + m_BolSeqCount = 0; + return true; + } + + //allocate bol seq memory + if((m_BolIdSeq)||(m_BolStatusSeq)||(m_BolVarSeq)) DeleteBolSequence(); + bool allocbolid = m_BolIdSeq = new UINT[loop.m_BolCount]; + bool allocbolvar = m_BolVarSeq = new UINT[loop.m_BolCount]; + bool allocbolstatus = m_BolStatusSeq = new UINT[loop.m_BolCount]; + if(!(allocbolid && allocbolstatus && allocbolvar)) return false; + + //prepare bol sequence + UINT nseq = 0; + for(int by=0;bydwFileVersionMS; + dwLS = pVsffi->dwFileVersionLS; + delete [] lpVersionData; + return TRUE; + } + + delete [] lpVersionData; + return FALSE; + +} + +void CUpdateCheck::Check(UINT uiURL) +{ + CString strURL(MAKEINTRESOURCE(uiURL)); + Check(strURL); +} + +void CUpdateCheck::Check(const CString& strURL) +{ + DWORD dwMS, dwLS; + if (!GetFileVersion(dwMS, dwLS)) + { + ASSERT(FALSE); + return; + } + + CWaitCursor wait; + //check for a connection + BOOL connected = FALSE; + DWORD flags; + connected = InternetGetConnectedState(&flags, NULL); + + if(!connected) + { + if(m_Quiet) return; + } + + HINTERNET hInet = InternetOpen(UPDATECHECK_BROWSER_STRING, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, NULL); + HINTERNET hUrl = InternetOpenUrl(hInet, strURL, NULL, -1L, + INTERNET_FLAG_RELOAD | INTERNET_FLAG_PRAGMA_NOCACHE | + INTERNET_FLAG_NO_CACHE_WRITE |WININET_API_FLAG_ASYNC, NULL); + if (hUrl) + { + char szBuffer[512]; + DWORD dwRead; + if (InternetReadFile(hUrl, szBuffer, sizeof(szBuffer), &dwRead)) + { + if (dwRead > 500) dwRead = 0; //abort if 404 or any other page retrived + if (dwRead > 0) + { + szBuffer[dwRead] = 0; + CString strSubMS1; + CString strSubMS2; + CString strSub; + DWORD dwMSWeb; + + //Contents of file updatecnaad.txt are 1|0|https://github.com/oormicreations/naad/releases + + AfxExtractSubString(strSubMS1, szBuffer, 0, '|'); //major ver num + AfxExtractSubString(strSubMS2, szBuffer, 1, '|'); //minor ver num + dwMSWeb = MAKELONG((WORD) atol(strSubMS2), (WORD) atol(strSubMS1)); + + if (dwMSWeb > dwMS) + { + AfxExtractSubString(strSub, szBuffer, 2, '|'); //download url + MsgUpdateAvailable(dwMS, dwLS, dwMSWeb, 0, strSub); + } + else + MsgUpdateNotAvailable(dwMS, dwLS); + } + else + MsgUpdateNoCheck(dwMS, dwLS); + + } + InternetCloseHandle(hUrl); + } + else + MsgUpdateNoCheck(dwMS, dwLS); + + InternetCloseHandle(hInet); +} + +HINSTANCE CUpdateCheck::GotoURL(LPCTSTR url, int showcmd) +{ + TCHAR key[MAX_PATH + MAX_PATH]; + + // First try ShellExecute() + HINSTANCE result = ShellExecute(NULL, _T("open"), url, NULL,NULL, showcmd); + + // If it failed, get the .htm regkey and lookup the program + if ((UINT)result <= HINSTANCE_ERROR) + { + + if (GetRegKey(HKEY_CLASSES_ROOT, _T(".htm"), key) == ERROR_SUCCESS) + { + lstrcat(key, _T("\\shell\\open\\command")); + + if (GetRegKey(HKEY_CLASSES_ROOT,key,key) == ERROR_SUCCESS) + { + TCHAR *pos; + pos = _tcsstr(key, _T("\"%1\"")); + if (pos == NULL) { // No quotes found + pos = _tcsstr(key, _T("%1")); // Check for %1, without quotes + if (pos == NULL) // No parameter at all... + pos = key+lstrlen(key)-1; + else + *pos = '\0'; // Remove the parameter + } + else + *pos = '\0'; // Remove the parameter + + lstrcat(pos, _T(" ")); + lstrcat(pos, url); + + result = (HINSTANCE) WinExec(key,showcmd); + } + } + } + + return result; +} + +LONG CUpdateCheck::GetRegKey(HKEY key, LPCTSTR subkey, LPTSTR retdata) +{ + HKEY hkey; + LONG retval = RegOpenKeyEx(key, subkey, 0, KEY_QUERY_VALUE, &hkey); + + if (retval == ERROR_SUCCESS) + { + long datasize = MAX_PATH; + TCHAR data[MAX_PATH]; + RegQueryValue(hkey, NULL, data, &datasize); + lstrcpy(retdata,data); + RegCloseKey(hkey); + } + + return retval; +} + + +void CUpdateCheck::MsgUpdateAvailable(DWORD dwMSlocal, DWORD dwLSlocal, DWORD dwMSWeb, DWORD dwLSWeb, const CString& strURL) +{ + CString strMessage; + strMessage.Format(IDS_UPDATE_AVAILABLE, HIWORD(dwMSlocal), LOWORD(dwMSlocal), HIWORD(dwMSWeb), LOWORD(dwMSWeb)); + + if (AfxMessageBox(strMessage, MB_YESNO|MB_ICONINFORMATION) == IDYES) + GotoURL(strURL, SW_SHOW); +} + +void CUpdateCheck::MsgUpdateNotAvailable(DWORD dwMSlocal, DWORD dwLSlocal) +{ + if(!m_Quiet) AfxMessageBox(IDS_UPDATE_NO, MB_OK|MB_ICONINFORMATION); +} + +void CUpdateCheck::MsgUpdateNoCheck(DWORD dwMSlocal, DWORD dwLSlocal) +{ + if(!m_Quiet) AfxMessageBox(IDS_UPDATE_NOCHECK, MB_OK|MB_ICONINFORMATION); +} diff --git a/UpdateCheck.h b/UpdateCheck.h new file mode 100644 index 0000000..f9c9338 --- /dev/null +++ b/UpdateCheck.h @@ -0,0 +1,34 @@ +// UpdateCheck.h +// +////////////////////////////////////////////////////////////////////// +#include "wininet.h" + +#if !defined(AFX_UPDATECHECK_H__6D1C0A60_F616_43C6_9850_F3C0F052C0DB__INCLUDED_) +#define AFX_UPDATECHECK_H__6D1C0A60_F616_43C6_9850_F3C0F052C0DB__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + + +#define UPDATECHECK_BROWSER_STRING _T("Update search") +class CUpdateCheck +{ +public: + BOOL m_Quiet; + virtual void Check(UINT uiURL); + virtual void Check(const CString& strURL); + CUpdateCheck(); + virtual ~CUpdateCheck(); + + static HINSTANCE GotoURL(LPCTSTR url, int showcmd); + static BOOL GetFileVersion(DWORD &dwMS, DWORD &dwLS); + static LONG GetRegKey(HKEY key, LPCTSTR subkey, LPTSTR retdata); + +protected: + virtual void MsgUpdateAvailable(DWORD dwMSlocal, DWORD dwLSlocal, DWORD dwMSWeb, DWORD dwLSWeb, const CString& strURL); + virtual void MsgUpdateNotAvailable(DWORD dwMSlocal, DWORD dwLSlocal); + virtual void MsgUpdateNoCheck(DWORD dwMSlocal, DWORD dwLSlocal); +}; + +#endif // !defined(AFX_UPDATECHECK_H__6D1C0A60_F616_43C6_9850_F3C0F052C0DB__INCLUDED_) diff --git a/WaveBox.cpp b/WaveBox.cpp new file mode 100644 index 0000000..b306c38 --- /dev/null +++ b/WaveBox.cpp @@ -0,0 +1,486 @@ +// WaveBox.cpp: implementation of the CWave class. +// +////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +#include "WaveBox.h" + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CWaveBox::CWaveBox() +{ + // init wave(s) counter + wload = 0; + + // thread suspended < used for resuming thread at first play > + run = 0; + + // create suspended player thread + thread = CreateThread( NULL, + 0, + (LPTHREAD_START_ROUTINE)PlayThread, + (LPVOID)this, + CREATE_SUSPENDED, + NULL ); + + + // alloc mem for interface(s) + for( unsigned int i = 0; i < SUPPORT_INTERFACES; i++ ) + { + I[i].wblock = allocateBlocks( BLOCK_SIZE, BLOCK_COUNT ); + I[i].wfreeblock = BLOCK_COUNT; + I[i].wcurrblock = 0; + I[i].state = INT_FREE; + I[i].wpos = 0; + } + + // init msg + for(int i = 0; i < SUPPORT_WAVES; i++ ) W[i].WMSG = WMSG_WAIT; + + // init cs + InitializeCriticalSection( &cs ); +} + + +CWaveBox::~CWaveBox() +{ + unsigned long exit = 0; + + if( run ) // thread resumed + { + // set thread close message + EnterCriticalSection( &cs ); + TMSG = TMSG_CLOSE; + LeaveCriticalSection( &cs ); + + do // wait for soft close + { + GetExitCodeThread( thread, &exit ); + Sleep( 10 ); + + }while( exit != THREAD_EXIT ); + + }else // thread suspended + { + // hard close + GetExitCodeThread( thread, &exit ); + TerminateThread( thread, exit ); + } + + + // release wave(s) + for( unsigned int i = 0; i < wload; i++ ) + free( W[i].data ); + + // release interface(s) + for(int i = 0; i < SUPPORT_INTERFACES; i++ ) + freeBlocks( I[i].wblock ); + + // del cs + DeleteCriticalSection( &cs ); +} + + + +WAVEHDR* CWaveBox::allocateBlocks(int size, int count) +{ + unsigned char* buffer; + int i; + WAVEHDR* blocks; + DWORD totalBufferSize = (size + sizeof(WAVEHDR)) * count; + + // allocate memory for the entire set in one go + if((buffer = ( UCHAR*) HeapAlloc( GetProcessHeap(), + HEAP_ZERO_MEMORY, + totalBufferSize )) == NULL) return NULL; + + // and set up the pointers to each bit + blocks = (WAVEHDR*)buffer; + buffer += sizeof(WAVEHDR) * count; + for(i = 0; i < count; i++) + { + blocks[i].dwBufferLength = size; + blocks[i].lpData = (CHAR *)buffer; + buffer += size; + } + + return blocks; +} + + +void CWaveBox::freeBlocks(WAVEHDR* blockArray) +{ + // and this is why allocateBlocks works the way it does + HeapFree(GetProcessHeap(), 0, blockArray); +} + + +int CWaveBox::Load( TCHAR *file ) +{ + if( wload == SUPPORT_WAVES ) + return -1; + + HANDLE hFile; + + // open file + if((hFile = CreateFile( file, + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + 0, + NULL )) == INVALID_HANDLE_VALUE) return -1; + + + // read wave header + char header[HEADER_SIZE]; + unsigned long rbytes = 0; + + if( !ReadFile(hFile, header, sizeof(header), &rbytes, NULL) ) + { CloseHandle(hFile); return -1; } + + if( !rbytes || rbytes < sizeof(header) ) + { CloseHandle(hFile); return -1; } + + /// check if this is a wave file + if( strncmp( header, WAVE_FILE_MARK, strlen( WAVE_FILE_MARK )) ) + { CloseHandle(hFile); return -1; } + + if( strncmp( header + OFFSET_HEAD_MARK, WAVE_HEAD_MARK, strlen( WAVE_HEAD_MARK )) ) + { CloseHandle(hFile); return -1; } + + /// check if wave is uncompressed PCM format + if ( ((*(DWORD*)(header + OFFSET_WAVE_PCM1)) != WAVE_PCM_16 ) + || ((*(WORD *)(header + OFFSET_WAVE_PCM2)) != WAVE_PCM_1 )) + {CloseHandle(hFile); return -1; } + + /// check for 'data' mark + if( !strncmp( header + OFFSET_DATA_MARK, WAVE_DATA_MARK, strlen( WAVE_DATA_MARK )) ) + W[wload].size = *((DWORD*)(header + OFFSET_DATA_SIZE )); /* size of data */ + else + { /// if data block size cant be read + /// try to predict data block without extra info + /// this is unusualy case + W[wload].size = *((DWORD*)(header + OFFSET_FILE_LEFT )); + W[wload].size -= ( HEADER_SIZE - EOF_EXTRA_INFO ); /* size of data */ + } + + // fill WAVEFORMATEX from wave header + W[wload].wfx.nSamplesPerSec = *((DWORD*)(header + OFFSET_SAMPLESPERSEC )); /* sample rate */ + W[wload].wfx.wBitsPerSample = *((WORD *)(header + OFFSET_BITSPERSAMPLE )); /* sample size */ + W[wload].wfx.nChannels = *((WORD *)(header + OFFSET_CHANNELS )); /* channels */ + W[wload].wfx.cbSize = 0; /* size of _extra_ info */ + W[wload].wfx.wFormatTag = WAVE_FORMAT_PCM; + W[wload].wfx.nBlockAlign = *((WORD *)(header + OFFSET_BLOCKALIGN )); + W[wload].wfx.nAvgBytesPerSec = *((DWORD*)(header + OFFSET_AVGBYTESPERSEC)); + + // get mem for wave data block + if((W[wload].data = ( char *) calloc( W[wload].size, sizeof( char ))) == NULL) + { CloseHandle(hFile); return -1; } + + char buffer[READ_BLOCK]; + + unsigned long size = W[wload].size; + unsigned long read_block = 0; + rbytes = 0; + + do /// copy uncompressed PCM wave data block + { + if( ( size -= rbytes ) >= READ_BLOCK ) read_block = READ_BLOCK; + else + if( size && size < READ_BLOCK ) read_block = size; + else break; + + if( !ReadFile(hFile, buffer, read_block, &rbytes, NULL) ) + break; + if( rbytes == 0 ) + break; + if( rbytes < sizeof(buffer) ) + memset(buffer + rbytes, 0, sizeof(buffer) - rbytes); + + memcpy( &W[wload].data[W[wload].size - size], buffer, rbytes ); + + }while( 1 ); + + // close file handle + CloseHandle(hFile); + + // return current wave count + return ++wload; +} + + +int CWaveBox::Play( unsigned int wave ) +{ + // check wave id + if( wave < 0 || wave >= wload ) + return -1; + + // set play message + EnterCriticalSection(&cs); + W[wave].WMSG = WMSG_START; + LeaveCriticalSection(&cs); + + // resume thread < at first play > + if( !run ){ run = 1; TMSG = TMSG_ALIVE; ResumeThread( thread ); } + + return 1; +} + + +int CWaveBox::AddInterface( HWAVEOUT *dev, + WAVEFORMATEX *wfx, + volatile int *wfreeblock ) +{ + // check for free device + if( !waveOutGetNumDevs() ) + return -1; + + // try to open the default wave device. WAVE_MAPPER is + // a constant defined in mmsystem.h, it always points to the + // default wave device on the system (some people have 2 or + // more sound cards). + + if(waveOutOpen( dev, + WAVE_MAPPER, + wfx, + (DWORD)waveOutProc, + (DWORD)wfreeblock, + CALLBACK_FUNCTION ) != MMSYSERR_NOERROR ) return -1; + + return 1; +} + + +int CWaveBox::RemoveInterface( HWAVEOUT dev ) +{ + // try to close given wave device / interface. + + if( waveOutClose( dev ) != MMSYSERR_NOERROR ) return -1; + + return 1; +} + + +static void CALLBACK waveOutProc( HWAVEOUT hWaveOut, + UINT uMsg, + DWORD dwInstance, + DWORD dwParam1, + DWORD dwParam2 ) +{ + // pointer to free block counter + int* freeBlockCounter = (int*)dwInstance; + + // ignore calls that occur due to openining and closing the device. + if(uMsg != WOM_DONE) + return; + + // increase free block counter + EnterCriticalSection(&cs); + (*freeBlockCounter)++; + LeaveCriticalSection(&cs); +} + + +static unsigned int __stdcall PlayThread( LPVOID lp ) +{ + /// get the class instance + CWaveBox *wb = ( CWaveBox *)lp; + + /// pooling variables < most frequently used / checked > + register WMsg wmsg = WMSG_WAIT; + register TMsg tmsg = TMSG_ALIVE; + register unsigned int i = 0; + + + /// thread life cycle + while( tmsg ) + { + + /// check for 'play' msg + for( i = 0; i < wb->wload; i++ ) + { + /// read msg + EnterCriticalSection( &cs ); + wmsg = wb->W[i].WMSG; + LeaveCriticalSection( &cs ); + + /// wave to play? + if( wmsg == WMSG_START ) break; + } + + + /// playable wave + if( wmsg == WMSG_START ) + + /// link with first free interface + for( unsigned int j = 0; j < SUPPORT_INTERFACES; j++ ) + + /// check for free interface + if( wb->I[j].state == INT_FREE ) + + /// attach wave to interface + if( wb->AddInterface( &wb->I[j].dev, + &wb->W[i].wfx, + &wb->I[j].wfreeblock ) ) + { + /// get wave pointer + wb->I[j].wave = &wb->W[i]; + + /// mark interface as used + wb->I[j].state = INT_USED; + + /// free wave + EnterCriticalSection( &cs ); + wb->W[i].WMSG = WMSG_WAIT; + LeaveCriticalSection( &cs ); + + /// leave loop + break; + } + + + + + ///////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////// + /// + /// < main playing loop > + /// + /// search for the first marked interface and play attached wave + /// + + for( unsigned int k = 0; k < SUPPORT_INTERFACES; k++ ) + { + /// nothing to do with free interface + if( wb->I[k].state == INT_FREE ) continue; + + EnterCriticalSection( &cs ); + int free = wb->I[k].wfreeblock; + LeaveCriticalSection( &cs ); + + /// nothing to do with full queued interface + if( free < BP_TURN ) continue; + + WAVEHDR *current = NULL; + + /// how much blocks per turn will be queued + for( unsigned int m = 0; m < BP_TURN; m++ ) + { + /// set current block pointer + current = &wb->I[k].wblock[wb->I[k].wcurrblock]; + + // first make sure the header we're going to use is unprepared + if( current->dwFlags & WHDR_PREPARED ) + + waveOutUnprepareHeader( wb->I[k].dev, + current, + sizeof(WAVEHDR) ); + + /// how much data is left at this interface to play + unsigned long left = wb->I[k].wave->size - wb->I[k].wpos; + unsigned long chunk = 0; + + if( left >= BLOCK_SIZE ) + chunk = BLOCK_SIZE; + else + if( left && left < BLOCK_SIZE ) + chunk = left; + else + { + //////////////////// + /// nothing left /// + //////////////////////////////////////////////////////////////////////// + /// + /// < clean job, close waveOutProc threads > + /// + /// all buffers are queued to the interface + /// + + /// get free block count + EnterCriticalSection( &cs ); + int free = wb->I[k].wfreeblock; + LeaveCriticalSection( &cs ); + + + if( free == BLOCK_COUNT ) /// are all blocks played!? + { + + /// unprepare any blocks that are still prepared + for( int i = 0; i < wb->I[k].wfreeblock; i++) + + if( wb->I[k].wblock[i].dwFlags & WHDR_PREPARED ) + + waveOutUnprepareHeader( wb->I[k].dev, + &wb->I[k].wblock[i], + sizeof(WAVEHDR) ); + + /// close interface + if( wb->RemoveInterface( wb->I[k].dev ) ) + { + /// free interface + wb->I[k].wcurrblock = 0; + wb->I[k].state = INT_FREE; + wb->I[k].wpos = 0; + wb->I[k].wave = NULL; + } + } + + /// step out + break; + } + + /// prepare current wave data block header + memcpy( current->lpData, &wb->I[k].wave->data[wb->I[k].wpos], chunk ); + + current->dwBufferLength = chunk; // sizeof block + wb->I[k].wpos += chunk; // update position + + /// prepare for playback + waveOutPrepareHeader( wb->I[k].dev, current, sizeof(WAVEHDR) ); + + /// push to the queue + waveOutWrite(wb->I[k].dev, current, sizeof(WAVEHDR)); + + /// decrease free block counter + EnterCriticalSection( &cs ); + wb->I[k].wfreeblock--; + LeaveCriticalSection( &cs ); + + /// point to the next block + wb->I[k].wcurrblock++; + wb->I[k].wcurrblock %= BLOCK_COUNT; + + }/// block(s) + + }/// interface(s) + + /// wait 10 ms < save CPU time > + Sleep( 10 ); + + /// check for thread message + EnterCriticalSection( &cs ); + tmsg = wb->TMSG; + LeaveCriticalSection( &cs ); + + }/// thread + + + + /////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////// + /// + /// force to close interfaces which are still playing + /// + + for( i = 0; i < SUPPORT_INTERFACES; i++ ) + if( wb->I[i].state == INT_USED ) + if( waveOutReset( wb->I[i].dev ) == MMSYSERR_NOERROR ) + wb->RemoveInterface( wb->I[i].dev ); + + + return THREAD_EXIT; /// return exit code < destructor > +} + diff --git a/WaveBox.h b/WaveBox.h new file mode 100644 index 0000000..6a8a380 --- /dev/null +++ b/WaveBox.h @@ -0,0 +1,144 @@ +// WaveBox.h: interface for the CWave class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_WAVEBOX_H__DE24CFE1_7501_4DA3_AF18_667A845AAE49__INCLUDED_) +#define AFX_WAVEBOX_H__DE24CFE1_7501_4DA3_AF18_667A845AAE49__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + + +////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////// +//// +//// by Zen '05 +//// +//// WaveBox class v0.95 +//// ~~~~~~~~~~~~~~~~~~~~~~ +//// ( PCM multiwave player ) +//// play & joy +//// +//// +//// +//// + +/// precompiler +#include +#include + +/// wave & PCM marks +#define WAVE_FILE_MARK "RIFF" +#define WAVE_HEAD_MARK "WAVEfmt " +#define WAVE_DATA_MARK "data" +#define WAVE_PCM_16 16 +#define WAVE_PCM_1 1 + +/// wfx header offsets +#define OFFSET_FILE_LEFT 4 +#define OFFSET_HEAD_MARK 8 +#define OFFSET_WAVE_PCM1 16 +#define OFFSET_WAVE_PCM2 20 +#define OFFSET_CHANNELS 22 +#define OFFSET_SAMPLESPERSEC 24 +#define OFFSET_AVGBYTESPERSEC 28 +#define OFFSET_BLOCKALIGN 32 +#define OFFSET_BITSPERSAMPLE 34 +#define OFFSET_DATA_MARK 36 +#define OFFSET_DATA_SIZE 40 +#define OFFSET_WAVEDATA 44 +#define HEADER_SIZE OFFSET_WAVEDATA +#define EOF_EXTRA_INFO 60 + + +/// messages +typedef unsigned int WMsg; // wave messages +typedef unsigned int TMsg; // thread messages + +#define WMSG_WAIT 0 // wave wait +#define WMSG_START 1 // wave play +#define TMSG_ALIVE 1 // thread alive +#define TMSG_CLOSE 0 // thread close +#define INT_FREE 0 // interface free +#define INT_USED 1 // interface used +#define THREAD_EXIT 0xABECEDA // thread exit code + +/// performance predefines +#define SUPPORT_WAVES 130 // predefined wave count +#define SUPPORT_INTERFACES 130 // predefined interface count + +/// buffering +#define READ_BLOCK 8192 // read wave ( file ) block size +#define BLOCK_SIZE 8192 // queue block size +#define BLOCK_COUNT 20 // queue block count +#define BP_TURN 1 // blocks per turn + + +static CRITICAL_SECTION cs; // critical section + +static unsigned int __stdcall PlayThread( LPVOID lp ); // main play thread +static void CALLBACK waveOutProc( HWAVEOUT hWaveOut, // waveOut prototype + UINT uMsg, + DWORD dwInstance, + DWORD dwParam1, + DWORD dwParam2 ); +class CWaveBox +{ + struct WAVE + { + char *data; /// wave + unsigned long size; /// size + WAVEFORMATEX wfx; /// wfx + WMsg WMSG; /// { 0,1 } wait / play + }; + + struct INTERFACE + { + /// interface + HWAVEOUT dev; /// device handle + unsigned int state; /// { 0,1 } free / used + + /// wave + WAVE *wave; /// current wave + + /// wave interface + unsigned long wpos; /// current play position + WAVEHDR* wblock; /// wave block + volatile int wfreeblock; /// free blocks left + int wcurrblock; /// current block + }; + +public: + + /// members + INTERFACE I[SUPPORT_INTERFACES]; // interface(s) + WAVE W[SUPPORT_WAVES]; // wave(s) + unsigned int wload; // current wave(s) loaded + TMsg TMSG; // thread msg { 1,0 } alive / close + + /// prototypes + int Load( TCHAR *file ); // load wave into WaveBox + int Play( unsigned int wave ); // play n wave from WaveBox ( starts play thread ) + + CWaveBox(); // play thread created suspended + virtual ~CWaveBox(); // play thread terminated + + /// waveOut open & close + int AddInterface( HWAVEOUT *dev, /// push wave wfx to interface + WAVEFORMATEX *wfx, + volatile int *wfreeblock ); + int RemoveInterface( HWAVEOUT dev ); /// pull wave wfx from interface + +protected: + + /// thread + HANDLE thread; /// play thread handle + unsigned int run; /// suspended / resumed + + /// prototypes + WAVEHDR* allocateBlocks( int size, int count ); /// alloc heap for wave header blocks + void freeBlocks( WAVEHDR* blockArray ); /// free heap +}; + +#endif // !defined(AFX_WAVEBOX_H__DE24CFE1_7501_4DA3_AF18_667A845AAE49__INCLUDED_) \ No newline at end of file diff --git a/res/Naad.ico b/res/Naad.ico new file mode 100644 index 0000000..1bfe728 Binary files /dev/null and b/res/Naad.ico differ diff --git a/res/Naad.manifest b/res/Naad.manifest new file mode 100644 index 0000000..aaf183f --- /dev/null +++ b/res/Naad.manifest @@ -0,0 +1,22 @@ + + + +Your app description here + + + + + + diff --git a/res/Naad.rc2 b/res/Naad.rc2 new file mode 100644 index 0000000..93db2ea --- /dev/null +++ b/res/Naad.rc2 @@ -0,0 +1,13 @@ +// +// Naadh.RC2 - resources Microsoft Visual C++ does not edit directly +// + +#ifdef APSTUDIO_INVOKED +#error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// Add manually edited resources here... + +///////////////////////////////////////////////////////////////////////////// diff --git a/res/bitmap1.bmp b/res/bitmap1.bmp new file mode 100644 index 0000000..6e8e840 Binary files /dev/null and b/res/bitmap1.bmp differ diff --git a/res/bitmap2.bmp b/res/bitmap2.bmp new file mode 100644 index 0000000..6e8e840 Binary files /dev/null and b/res/bitmap2.bmp differ diff --git a/res/icon1.ico b/res/icon1.ico new file mode 100644 index 0000000..6f7e488 Binary files /dev/null and b/res/icon1.ico differ diff --git a/res/idr_main.ico b/res/idr_main.ico new file mode 100644 index 0000000..32ca032 Binary files /dev/null and b/res/idr_main.ico differ diff --git a/resource.h b/resource.h new file mode 100644 index 0000000..0d62013 --- /dev/null +++ b/resource.h @@ -0,0 +1,270 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Naad.rc +// +#define IDM_ABOUTBOX 0x0010 +#define IDD_ABOUTBOX 100 +#define IDS_ABOUTBOX 101 +#define IDD_NAADH_DIALOG 102 +#define IDS_UPDATE_AVAILABLE 102 +#define IDS_UPDATE_NO 103 +#define IDS_UPDATE_NOCHECK 104 +#define IDS_UPDATE 105 +#define IDR_MAINFRAME 128 +#define IDR_MENU1 129 +#define IDR_ICON1 129 +#define IDR_MENU2 130 +#define IDD_DIALOG_ABT 131 +#define IDR_MENU3 132 +#define IDD_DIALOG_PROPCOMP 133 +#define IDD_DIALOG_PROPLOOP 134 +#define IDI_ICON1 136 +#define IDC_STATIC_MSG 1000 +#define IDC_LIST 1001 +#define IDC_BUTTON_PLAY 1002 +#define IDC_BUTTON_STOP 1003 +#define IDC_SLIDER1 1004 +#define IDC_SLIDER_TEMPO 1004 +#define IDC_STATIC_ABT 1005 +#define IDC_SLIDER_RAND 1005 +#define IDC_STATIC_FILE 1006 +#define IDC_CHECK_ACC 1007 +#define IDC_COMBO1 1008 +#define IDC_COMBO_MATRA 1008 +#define IDC_CHECK_VARSAME 1008 +#define IDC_CHECK_STEREO 1009 +#define IDC_COMBO_ACC 1009 +#define IDC_CHECK_STEREO2 1010 +#define IDC_CHECK_ECHO 1010 +#define IDC_BUTTON1 1011 +#define IDC_CHECK_RNDBOL 1011 +#define IDC_CHECK_STEREO3 1012 +#define IDC_CHECK_SAM 1012 +#define IDC_EDIT_COMPNAME 1012 +#define IDC_SLIDER_BOLVAR 1013 +#define IDC_EDIT_COMPOSER 1013 +#define IDC_EDIT_LOOPNAME 1013 +#define IDC_CHECK_ACC2 1014 +#define IDC_EDIT_COMPNOTES 1014 +#define IDC_EDIT_REPEAT 1014 +#define IDC_EDIT_LOOPNOTES 1015 +#define IDC_CHECK_VARANY 1015 +#define IDC_EDIT_DELAY 1016 +#define IDC_CHECK_VARCOMP 1016 +#define IDC_CHECK_B2B 1017 +#define IDC_CHECK_VARLOOP 1017 +#define IDC_BUTTON2 1018 +#define IDC_BUTTON_SAVEVAR 1018 +#define IDC_EDIT_MAATRAS 1018 +#define IDC_BUTTON_GUN1 1019 +#define IDC_BUTTON_AUTOCOMPOSE 1023 +#define IDC_EDIT_TEMPO 1024 +#define IDC_EDIT_TEMPOVAR 1025 +#define IDC_EDIT_BOLVAR 1026 +#define IDC_BUTTON_PLAYLOOP 1027 +#define IDC_BUTTON_RESVAR 1028 +#define ID_HELP_NAADHHELP 32771 +#define ID_HELP_ABOUTNAADH 32772 +#define ID_FILE_OPEN32773 32773 +#define ID_FILE_SAVE32774 32774 +#define ID_FILE_SAVEAS 32775 +#define ID_FILE_EXIT 32776 +#define ID_HELP_CHECKFORUPDATES 32777 +#define ID_HELP_CONTACT 32778 +#define ID_DAYAN_NA 32779 +#define ID_DAYAN_TAT 32780 +#define ID_DAYAN_TI 32781 +#define ID_DAYAN_TIN 32782 +#define ID_DAYAN_TUN 32783 +#define ID_BAYAN_DHA 32784 +#define ID_BAYAN_DHIN 32785 +#define ID_BAYAN_DHIT 32786 +#define ID_BAYAN_DHUN 32787 +#define ID_BAYAN_GA 32788 +#define ID_BAYAN_GE 32789 +#define ID_BAYAN_KE 32790 +#define ID_BOLS_CLEAR 32791 +#define ID_BOLS_CLEAR32792 32792 +#define ID_FILE_NEWTAAL 32793 +#define ID_OPTIONS_SETTINGS 32794 +#define ID_OPTIONS_BOLFOLDER 32795 +#define ID_BOLS_SILENCE 32796 +#define ID_ACCOMPANIMENT_TANPURA 32797 +#define ID_ACCOMPANIMENT_2 32798 +#define ID_ACCOMPANIMENT_3 32799 +#define ID_ACCOMPANIMENT_4 32800 +#define ID_ACCOMPANIMENT_5 32801 +#define ID_ACCOMPANIMENT_6 32802 +#define ID_ACCOMPANIMENT_7 32803 +#define ID_ACCOMPANIMENT_8 32804 +#define ID_INSTRUMENT_TABLA 32805 +#define ID_INSTRUMENT_DHOLAK 32806 +#define ID_INSTRUMENT_PAKHAWAJ 32807 +#define ID_INSTRUMENT_MRIDANGAM 32808 +#define ID_INSTRUMENT_DHAPLI 32809 +#define ID_NA_NA01 32810 +#define ID_NA_NA02 32811 +#define ID_NA_NA03 32812 +#define ID_NA_NA04 32813 +#define ID_NA_NA05 32814 +#define ID_NA_NA06 32815 +#define ID_NA_NA07 32816 +#define ID_NA_NA08 32817 +#define ID_NA_NA09 32818 +#define ID_NA_NA10 32819 +#define ID_TA_TA01 32820 +#define ID_TA_TA02 32821 +#define ID_TA_TA03 32822 +#define ID_TA_TA04 32823 +#define ID_TA_TA05 32824 +#define ID_TA_TA06 32825 +#define ID_TA_TA07 32826 +#define ID_TA_TA08 32827 +#define ID_TA_TA09 32828 +#define ID_TA_TA10 32829 +#define ID_TI_TI01 32830 +#define ID_TI_TI02 32831 +#define ID_TI_TI03 32832 +#define ID_TI_TI04 32833 +#define ID_TI_TI05 32834 +#define ID_TI_TI06 32835 +#define ID_TI_TI07 32836 +#define ID_TI_TI08 32837 +#define ID_TI_TI09 32838 +#define ID_TI_TI10 32839 +#define ID_TIN_TIN01 32840 +#define ID_TIN_TIN02 32841 +#define ID_TIN_TIN03 32842 +#define ID_TIN_TIN04 32843 +#define ID_TIN_TIN05 32844 +#define ID_TIN_TIN06 32845 +#define ID_TIN_TIN07 32846 +#define ID_TIN_TIN08 32847 +#define ID_TIN_TIN09 32848 +#define ID_TIN_TIN10 32849 +#define ID_TUN_TUN01 32850 +#define ID_TUN_TUN02 32851 +#define ID_TUN_TUN03 32852 +#define ID_TUN_TUN04 32853 +#define ID_TUN_TUN05 32854 +#define ID_TUN_TUN06 32855 +#define ID_TUN_TUN07 32856 +#define ID_TUN_TUN08 32857 +#define ID_TUN_TUN09 32858 +#define ID_TUN_TUN10 32859 +#define ID_DHA_DHA01 32860 +#define ID_DHA_DHA02 32861 +#define ID_DHA_DHA03 32862 +#define ID_DHA_DHA04 32863 +#define ID_DHA_DHA05 32864 +#define ID_DHA_DHA06 32865 +#define ID_DHA_DHA07 32866 +#define ID_DHA_DHA08 32867 +#define ID_DHA_DHA09 32868 +#define ID_DHA_DHA10 32869 +#define ID_DHIN_DHIN01 32870 +#define ID_DHIN_DHIN02 32871 +#define ID_DHIN_DHIN03 32872 +#define ID_DHIN_DHIN04 32873 +#define ID_DHIN_DHIN05 32874 +#define ID_DHIN_DHIN06 32875 +#define ID_DHIN_DHIN07 32876 +#define ID_DHIN_DHIN08 32877 +#define ID_DHIN_DHIN09 32878 +#define ID_DHIN_DHIN10 32879 +#define ID_DHIT_DHIT01 32880 +#define ID_DHIT_DHIT02 32881 +#define ID_DHIT_DHIT03 32882 +#define ID_DHIT_DHIT04 32883 +#define ID_DHIT_DHIT05 32884 +#define ID_DHIT_DHIT06 32885 +#define ID_DHIT_DHIT07 32886 +#define ID_DHIT_DHIT08 32887 +#define ID_DHIT_DHIT09 32888 +#define ID_DHIT_DHIT10 32889 +#define ID_DHUN_DHUN01 32890 +#define ID_DHUN_DHUN02 32891 +#define ID_DHUN_DHUN03 32892 +#define ID_DHUN_DHUN04 32893 +#define ID_DHUN_DHUN05 32894 +#define ID_DHUN_DHUN06 32895 +#define ID_DHUN_DHUN07 32896 +#define ID_DHUN_DHUN08 32897 +#define ID_DHUN_DHUN09 32898 +#define ID_DHUN_DHUN10 32899 +#define ID_GA_GA01 32900 +#define ID_GA_GA02 32901 +#define ID_GA_GA03 32902 +#define ID_GA_GA04 32903 +#define ID_GA_GA05 32904 +#define ID_GA_GA06 32905 +#define ID_GA_GA07 32906 +#define ID_GA_GA08 32907 +#define ID_GA_GA09 32908 +#define ID_GA_GA10 32909 +#define ID_GE_GE01 32910 +#define ID_GE_GE02 32911 +#define ID_GE_GE03 32912 +#define ID_GE_GE04 32913 +#define ID_GE_GE05 32914 +#define ID_GE_GE06 32915 +#define ID_GE_GE07 32916 +#define ID_GE_GE08 32917 +#define ID_GE_GE09 32918 +#define ID_GE_GE10 32919 +#define ID_KE_KE01 32920 +#define ID_KE_KE02 32921 +#define ID_KE_KE03 32922 +#define ID_KE_KE04 32923 +#define ID_KE_KE05 32924 +#define ID_KE_KE06 32925 +#define ID_KE_KE07 32926 +#define ID_KE_KE08 32927 +#define ID_KE_KE09 32928 +#define ID_KE_KE10 32929 +#define ID_OPTIONS_PLAYALLSAMPLES 32931 +#define ID_ACCOMPANIMENT_TAANPURA 32932 +#define ID_ACCOMPANIMENT_ORGAN 32933 +#define ID_ACCOMPANIMENT_GHUNGRU 32934 +#define ID_GHUNGRU_GHUNGRU01 32937 +#define ID_GHUNGRU_GHUNGRU02 32938 +#define ID_GHUNGRU_GHUNGRU03 32939 +#define ID_GHUNGRU_GHUNGRU04 32940 +#define ID_GHUNGRU_GHUNGRU05 32941 +#define ID_GHUNGRU_GHUNGRU06 32942 +#define ID_BOLS_SAM 32947 +#define ID_BOLS_TALI 32948 +#define ID_BOLS_KHALI 32949 +#define ID_INSTRUMENT_CONGO 32950 +#define ID_INSTRUMENT_D 32951 +#define ID_GHUNGRU_6 32952 +#define ID_EDIT_SELECT 32955 +#define ID_EDIT_COPY32956 32956 +#define ID_EDIT_CUT32957 32957 +#define ID_EDIT_PASTE32958 32958 +#define ID_FILE_NEWCOMPOSITION 32959 +#define ID_LOOP_OPEN 32960 +#define ID_LOOP_CLEAR 32961 +#define ID_LOOP_PROPERTIES 32962 +#define ID_LOOP_SAVELOOP 32963 +#define ID_LOOP_LOADLOOP 32964 +#define ID_VIEW_COMPOSITION 32965 +#define ID_VIEW_LOOP 32966 +#define ID_BOLS_VIEWCOMP 32968 +#define ID_BOLS_ 32969 +#define ID__DHAGETITA 32970 +#define ID__DHAGETUNA 32971 +#define ID__GADHIGENA 32972 +#define ID__TIRAKETADHA 32973 +#define ID_EDIT_CLEAR32974 32974 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 140 +#define _APS_NEXT_COMMAND_VALUE 32975 +#define _APS_NEXT_CONTROL_VALUE 1026 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/stdafx.cpp b/stdafx.cpp new file mode 100644 index 0000000..02c5c8e --- /dev/null +++ b/stdafx.cpp @@ -0,0 +1,7 @@ +// stdafx.cpp : source file that includes just the standard includes +// Naadh.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + + diff --git a/stdafx.h b/stdafx.h new file mode 100644 index 0000000..b2b4fdd --- /dev/null +++ b/stdafx.h @@ -0,0 +1,42 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, +// but are changed infrequently + +#pragma once + +#ifndef VC_EXTRALEAN +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers +#endif + +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later. +#define WINVER 0x0501 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later. +#endif + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later. +#endif + +#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. +#define _WIN32_WINDOWS 0x0501 // Change this to the appropriate value to target Windows Me or later. +#endif + +#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later. +#define _WIN32_IE 0x0500 // Change this to the appropriate value to target IE 5.0 or later. +#endif + +#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit + +// turns off MFC's hiding of some common and often safely ignored warning messages +#define _AFX_ALL_WARNINGS + +#include // MFC core and standard components +#include // MFC extensions +#include // MFC Automation classes + +#include // MFC support for Internet Explorer 4 Common Controls +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + diff --git a/zoomctrl.cpp b/zoomctrl.cpp new file mode 100644 index 0000000..216e56e --- /dev/null +++ b/zoomctrl.cpp @@ -0,0 +1,315 @@ +// zoomctrl.cpp +//--------------------------------------------------------------------- +/* + Child control with zoom and scroll + + Jim Dill [jim@jimdill.net] + v 1.0, Mar 25 2008 +*/ +//--------------------------------------------------------------------- +#include "stdafx.h" +#include "zoomctrl.h" +#include +using namespace Gdiplus; +//Macro to release COM Components + +#ifdef SAFE_RELEASE +#undef SAFE_RELEASE +#endif +#define SAFE_RELEASE(x) do{\ + if((x) != NULL)\ + {\ + while((x)->Release() != 0);\ + (x) = NULL;\ + }\ + }while(0) + + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +//--------------------------------------------------------------------- +CZoomCtrl::CZoomCtrl() +{ + m_scrollHelper.AttachWnd(this); + GdiplusStartupInput gdiplusStartupInput; + GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL); + m_pStream = NULL; + m_zoomFactor = 1.0; + m_gdiplusToken = 0; + m_Error = 0; + m_Sx = 0; + m_Sy = 0; + m_Page = 0; + m_bIsPicLoaded = FALSE; + m_ResetPage = false; + m_IsMultiPage = false; + m_About = false; +} +//--------------------------------------------------------------------- +CZoomCtrl::~CZoomCtrl() +{ +} +//--------------------------------------------------------------------- + +BEGIN_MESSAGE_MAP(CZoomCtrl, CWnd) + ON_WM_PAINT() + ON_WM_HSCROLL() + ON_WM_VSCROLL() + ON_WM_MOUSEACTIVATE() + ON_WM_MOUSEWHEEL() + ON_WM_ERASEBKGND() +END_MESSAGE_MAP() + +//--------------------------------------------------------------------- +void CZoomCtrl::Draw(CDC *pDC) +{ + // fill background + CRect rClient; + GetClientRect(rClient); + COLORREF backgrColor = RGB(80,80,80); + pDC->FillRect(&rClient, &CBrush(backgrColor)); + + + // define virtual drawing space -- change this to suit + // if drawing must not distort, then create a rect same shape as image + Image image(m_pStream); + m_Sx = image.GetWidth(); + m_Sy = image.GetHeight(); + rClient.right = (LONG)((double)m_Sx * m_zoomFactor); + rClient.bottom = (LONG)((double)m_Sy * m_zoomFactor); + CRect rVirt(0, 0, rClient.right, rClient.bottom); + + PrepDC(pDC, rVirt, rClient); + + // do your drawing here, in virtual coords + Graphics graphics(pDC->GetSafeHdc()); + //graphics.Clear(Color::White); + ////Get control measures + ////RECT rc; + ////this->GetClientRect(&rc); + ////CRect rc(0, 0, 3000, 2800); + + //// scale and draw the picture + int nHeight = (rVirt.bottom-rVirt.top); + int nWidth = (rVirt.right-rVirt.left); + //double XScale = (double) nWidth / (double)image.GetWidth(); + //double YScale = (double) nHeight / (double)image.GetHeight(); + //double Scale = 1.0; + //if ( XScale < YScale ) + //Scale = XScale; + //else + //Scale = YScale; + + //nHeight = image.GetHeight() * Scale; + //nWidth = image.GetWidth() * Scale; + + + if(m_IsMultiPage) + { + GUID pageGuid = FrameDimensionPage; + UINT pc = image.GetFrameCount(&pageGuid); + if(m_Page > pc) {m_Page = 1; m_ResetPage = true;} + image.SelectActiveFrame(&pageGuid, m_Page-1); + } + + graphics.DrawImage(&image, (INT)rVirt.left, (INT)rVirt.top, (INT)nWidth, (INT) nHeight ); + + if(m_Error>0) + { + FontFamily fontFamily(L"Century Gothic"); + Font font(&fontFamily, 12, FontStyleRegular, UnitPixel); + PointF pointF(120.0f, 230.0f); + SolidBrush solidBrush(Color(255, 220, 0, 0)); + WCHAR* errstr; + + if(m_Error==1) errstr = L"Error : Image file was not found"; + if(m_Error==2) errstr = L"Error : Image file could not be loaded"; + if(m_Error==3) errstr = L"Error : Image file stream creation failed"; + graphics.DrawString(errstr, -1, &font, pointF, &solidBrush); + pointF.X = 80.f; + pointF.Y = 280.f; + Font font2(&fontFamily,12, FontStyleItalic, UnitPixel); + solidBrush.SetColor(Color(0,0,0)); + errstr = L"Unknown Error"; + graphics.DrawString(errstr, -1, &font2, pointF, &solidBrush); + pointF.X = 80.f; + pointF.Y = 400.f; + LPTSTR lpStr = m_ImageName.GetBuffer( m_ImageName.GetLength() ); + int nLen = MultiByteToWideChar(CP_ACP, 0,lpStr, -1, NULL, NULL); + LPWSTR lpszW = new WCHAR[nLen]; + MultiByteToWideChar(CP_ACP, 0, lpStr, -1, lpszW, nLen); + + graphics.DrawString(lpszW, -1, &font2, pointF, &solidBrush); + delete [] lpszW; + } + + if(m_About) + { + FontFamily fontFamily(L"Century Gothic"); + Font font(&fontFamily, 11, FontStyleRegular, UnitPixel); + PointF pointF(10.0f, 10.0f); + SolidBrush solidBrush(Color(255, 255, 230, 55)); + + LPTSTR lpStr = m_ImageName.GetBuffer( m_ImageName.GetLength() ); + int nLen = MultiByteToWideChar(CP_ACP, 0,lpStr, -1, NULL, NULL); + LPWSTR lpszW = new WCHAR[nLen]; + MultiByteToWideChar(CP_ACP, 0, lpStr, -1, lpszW, nLen); + + graphics.DrawString(lpszW, -1, &font, pointF, &solidBrush); + delete [] lpszW; + } + + + // here's our sample + //CRect rTest(2000, 2200, 3000, 2800); + //CPen penBrown(PS_SOLID, 0, RGB(192,110,0)); + //CPen penGreen(PS_SOLID, 0, RGB(0,192,0)); + //CPen* pOldPen = pDC->SelectObject(&penGreen); + //pDC->Ellipse(&rTest); + + //pDC->SelectObject(&penBrown); + //pDC->MoveTo(0, 0); + //pDC->LineTo(5000, 5000); + //pDC->MoveTo(5000, 0); + //pDC->LineTo(0, 5000); + + //pDC->SelectObject(pOldPen); +} +//--------------------------------------------------------------------- +void CZoomCtrl::OnPaint() +{ + CPaintDC dc(this); + /*if(m_bIsPicLoaded) */Draw(&dc); +} +//--------------------------------------------------------------------- +void CZoomCtrl::PrepDC(CDC *pDC, const CRect& rVirt, const CRect& rScreen) +{ + // maps virtual into client + m_rVirt = rVirt; + m_rScreen = rScreen; + + //pDC->IntersectClipRect(&rScreen); + + //pDC->SetMapMode(MM_ANISOTROPIC); + pDC->SetWindowExt(rVirt.Width(), rVirt.Height()); + + //LONG wid = (LONG)(m_zoomFactor * (double)rVirt.Width()); + //LONG hgt = (LONG)(m_zoomFactor * (double)rVirt.Height()); + LONG wid = (LONG)(/*m_zoomFactor * (double)*/rScreen.Width() ); + LONG hgt = (LONG)(/*m_zoomFactor * (double)*/rScreen.Height()); + pDC->SetViewportExt(wid, hgt); + + CSize scrollPos = m_scrollHelper.GetScrollPos(); + pDC->SetViewportOrg(-scrollPos.cx, -scrollPos.cy); +} +//--------------------------------------------------------------------- +void CZoomCtrl::AdjustScrollbars() +{ + int xMax = (int)((double)m_rScreen.Width() * m_zoomFactor); + int yMax = (int)((double)m_rScreen.Height() * m_zoomFactor); + m_scrollHelper.SetPageSize(m_rScreen.Width(), m_rScreen.Height()); + m_scrollHelper.SetDisplaySize(xMax, yMax); +} +//--------------------------------------------------------------------- +void CZoomCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) +{ + m_scrollHelper.OnHScroll(nSBCode, nPos, pScrollBar); + Invalidate(); +} +//--------------------------------------------------------------------- +void CZoomCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) +{ + m_scrollHelper.OnVScroll(nSBCode, nPos, pScrollBar); + Invalidate(); +} +//--------------------------------------------------------------------- +BOOL CZoomCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) +{ + return m_scrollHelper.OnMouseWheel(nFlags, zDelta, pt); +} +//--------------------------------------------------------------------- +LRESULT CZoomCtrl::WindowProc(UINT msg, WPARAM wParam, LPARAM lParam) +{ + // necessary for getting h/vscroll msgs + if (msg == WM_NCHITTEST || msg == WM_NCLBUTTONDOWN || msg == WM_NCLBUTTONDBLCLK) + return ::DefWindowProc(m_hWnd, msg, wParam, lParam); + return CWnd::WindowProc(msg, wParam, lParam); +} +//--------------------------------------------------------------------- +int CZoomCtrl::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message) +{ + // necessary for getting mousewheel messages + int status = CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message); + SetFocus(); + return status; +} +//--------------------------------------------------------------------- +BOOL CZoomCtrl::OnEraseBkgnd(CDC* pDC) +{ + // prevent erase to reduce flashing + // for smoothest resize, also set clipchildren style in parent dialog + return TRUE; +} +//--------------------------------------------------------------------- + +BOOL CZoomCtrl::LoadFromFile(CString &szFilePath) +{ + //Set success error state + SetLastError(ERROR_SUCCESS); + FreeData(); + + //Allocate stream + DWORD dwResult = CreateStreamOnHGlobal(NULL, TRUE, &m_pStream); + if(dwResult != S_OK) + { + SetLastError(dwResult); + return FALSE; + } + + //Open the specified file + CFile cFile; + CFileException cFileException; + if(!cFile.Open(szFilePath, CStdioFile::modeRead | CStdioFile::typeBinary, &cFileException)) + { + SetLastError(cFileException.m_lOsError); + SAFE_RELEASE(m_pStream); + m_Error = 1;//"Failed to load image file : " + szFilePath; + return FALSE; + } + + //Copy the specified file's content to the stream + BYTE pBuffer[1024] = {0}; + while(UINT dwRead = cFile.Read(pBuffer, 1024)) + { + dwResult = m_pStream->Write(pBuffer, dwRead, NULL); + if(dwResult != S_OK) + { + SetLastError(dwResult); + SAFE_RELEASE(m_pStream); + cFile.Close(); + m_Error = 3; + return FALSE; + } + } + + //Close the file + cFile.Close(); + + //Mark as Loaded + //m_bIsPicLoaded = TRUE; + + Invalidate(); + RedrawWindow(); + + return TRUE; +} + +void CZoomCtrl::FreeData() +{ + m_bIsPicLoaded = FALSE; + SAFE_RELEASE(m_pStream); +} diff --git a/zoomctrl.h b/zoomctrl.h new file mode 100644 index 0000000..25b3ae0 --- /dev/null +++ b/zoomctrl.h @@ -0,0 +1,61 @@ +// zoomctrl.h +//--------------------------------------------------------------------- +#ifndef _H_ZoomCtrl +#define _H_ZoomCtrl + +#include "scrollhelper.h" + +//--------------------------------------------------------------------- +class CZoomCtrl : public CWnd +{ +public: + CZoomCtrl(); + ~CZoomCtrl(); + + double GetZoomFactor() const { return m_zoomFactor; } + void SetZoomFactor(double d) { m_zoomFactor = d; } + void AdjustScrollbars(); + //Loads an image from a file + BOOL LoadFromFile(CString &szFilePath); + //Frees the image data + void FreeData(); + + + UINT m_Sx, m_Sy, m_Error, m_Page; + bool m_IsMultiPage, m_ResetPage, m_About; + CString m_ImageName; + + //{{AFX_MSG(CDendroCtl) + afx_msg void OnPaint(); + afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); + afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); + afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() + + LRESULT WindowProc(UINT mess, WPARAM wParam, LPARAM lParam); + afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message); + afx_msg BOOL OnEraseBkgnd(CDC* pDC); + +protected: + virtual void Draw(CDC *pDC); + void PrepDC(CDC *pDC, const CRect& rVirt, const CRect& rScreen); + + CRect m_rVirt, m_rScreen; + CScrollHelper m_scrollHelper; + double m_zoomFactor; +private: + + //Internal image stream buffer + IStream* m_pStream; + + //Control flag if a pic is loaded + BOOL m_bIsPicLoaded; + + //GDI Plus Token + ULONG_PTR m_gdiplusToken; + + +}; +//--------------------------------------------------------------------- +#endif // _H_ZoomCtrl